shirkasoft-ui-components 1.0.23 → 1.0.26
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.
- package/README.md +439 -268
- package/fesm2022/shirkasoft-ui-components.mjs +411 -30
- package/fesm2022/shirkasoft-ui-components.mjs.map +1 -1
- package/package.json +3 -2
- package/src/theme.css +32 -5
- package/types/shirkasoft-ui-components.d.ts +137 -5
package/README.md
CHANGED
|
@@ -1,40 +1,48 @@
|
|
|
1
1
|
# Shirkasoft UI Components
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
|
|
4
|
+
<a href="https://github.com/Ansem13/shirkasoft-ui-components/releases"><img src="https://img.shields.io/npm/v/shirkasoft-ui-components?style=flat&logo=npm&label=version" alt="npm version" /></a>
|
|
5
|
+
<a href="https://github.com/Ansem13/shirkasoft-ui-components/issues"><img src="https://img.shields.io/github/issues/Ansem13/shirkasoft-ui-components?style=flat&logo=github" alt="GitHub issues" /></a>
|
|
6
|
+
<a href="https://github.com/Ansem13/shirkasoft-ui-components"><img src="https://img.shields.io/badge/source-github-181717?style=flat&logo=github" alt="GitHub source" /></a>
|
|
7
|
+
<a href="https://ansem13.github.io/shirkasoft-ui-components/"><img src="https://img.shields.io/badge/showcase-online-10b981?style=flat&logo=githubpages" alt="Showcase" /></a>
|
|
5
8
|
</p>
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
<p align="center">
|
|
11
|
+
Created by <a href="https://shirkasoft.com" target="_blank"><strong>Shirkasoft</strong></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
Angular 21+ UI components library built with **Tailwind CSS**, **standalone components**, **Angular signals**, and **light/dark theme** support via CSS custom properties.
|
|
8
15
|
|
|
9
|
-
##
|
|
16
|
+
## Installation
|
|
10
17
|
|
|
11
18
|
```bash
|
|
12
19
|
pnpm add shirkasoft-ui-components
|
|
13
|
-
#
|
|
20
|
+
# or
|
|
14
21
|
npm install shirkasoft-ui-components
|
|
15
22
|
```
|
|
16
23
|
|
|
17
|
-
###
|
|
24
|
+
### Peer Dependencies
|
|
18
25
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
| @angular/common
|
|
22
|
-
| @angular/core
|
|
23
|
-
| @angular/forms
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
| @
|
|
27
|
-
|
|
|
26
|
+
| Package | Minimum version |
|
|
27
|
+
| ------------------ | --------------- |
|
|
28
|
+
| @angular/common | ^21.2.0 |
|
|
29
|
+
| @angular/core | ^21.2.0 |
|
|
30
|
+
| @angular/forms | ^21.2.0 |
|
|
31
|
+
| @angular/router | ^21.2.0 |
|
|
32
|
+
| rxjs | ^7.8.0 |
|
|
33
|
+
| @jsverse/transloco | >= 8.0.0 |
|
|
34
|
+
| @lucide/angular | ^1.17.0 |
|
|
35
|
+
| chart.js | ^4.4.0 |
|
|
28
36
|
|
|
29
|
-
##
|
|
37
|
+
## Theme Setup
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
Import the theme in your global `styles.css`:
|
|
32
40
|
|
|
33
41
|
```css
|
|
34
42
|
@import '@shirkasoft/ui-components/theme.css';
|
|
35
43
|
```
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
The theme is based on `--shk-*` CSS variables. To customize colors, override the variables in `:root` (light mode) and `.dark` (dark mode):
|
|
38
46
|
|
|
39
47
|
```css
|
|
40
48
|
:root {
|
|
@@ -46,7 +54,7 @@ El tema se basa en variables CSS `--shk-*`. Para personalizar colores, sobrescri
|
|
|
46
54
|
|
|
47
55
|
### Dark mode
|
|
48
56
|
|
|
49
|
-
|
|
57
|
+
Add the `dark` class to the `<html>` element to enable dark mode.
|
|
50
58
|
|
|
51
59
|
```typescript
|
|
52
60
|
document.documentElement.classList.toggle('dark');
|
|
@@ -54,110 +62,112 @@ document.documentElement.classList.toggle('dark');
|
|
|
54
62
|
|
|
55
63
|
---
|
|
56
64
|
|
|
57
|
-
##
|
|
58
|
-
|
|
59
|
-
| #
|
|
60
|
-
|
|
61
|
-
| 1
|
|
62
|
-
| 2
|
|
63
|
-
| 3
|
|
64
|
-
| 4
|
|
65
|
-
| 5
|
|
66
|
-
| 6
|
|
67
|
-
| 7
|
|
68
|
-
| 8
|
|
69
|
-
| 9
|
|
70
|
-
| 10
|
|
71
|
-
| 11
|
|
72
|
-
| 12
|
|
65
|
+
## Components
|
|
66
|
+
|
|
67
|
+
| # | Component | Selector | ControlValueAccessor | Associated service |
|
|
68
|
+
| --- | ------------- | -------------------- | -------------------- | ---------------------- |
|
|
69
|
+
| 1 | TextField | `shk-text-field` | ✅ | — |
|
|
70
|
+
| 2 | Toggle | `shk-toggle` | ✅ | — |
|
|
71
|
+
| 3 | Select | `shk-select` | ✅ | — |
|
|
72
|
+
| 4 | DatePicker | `shk-date-picker` | ✅ | — |
|
|
73
|
+
| 5 | PriceInput | `shk-price-input` | — | — |
|
|
74
|
+
| 6 | FileUpload | `shk-file-upload` | — | — |
|
|
75
|
+
| 7 | Table | `shk-table` | — | — |
|
|
76
|
+
| 8 | Modal | `shk-modal` | — | `ModalService` |
|
|
77
|
+
| 9 | Notification | `shk-notification` | — | `NotificationService` |
|
|
78
|
+
| 10 | ConfirmDialog | `shk-confirm-dialog` | — | `ConfirmDialogService` |
|
|
79
|
+
| 11 | Chart | `shk-chart` | — | — |
|
|
80
|
+
| 12 | Tooltip | `shk-tooltip` | — | — |
|
|
81
|
+
| 13 | Sidebar | `shk-sidebar` | — | — |
|
|
82
|
+
| 14 | Rail Sidebar | `shk-rail-sidebar` | — | — |
|
|
73
83
|
|
|
74
84
|
---
|
|
75
85
|
|
|
76
86
|
### TextField (`shk-text-field`)
|
|
77
87
|
|
|
78
|
-
|
|
88
|
+
Text input with support for input, textarea, password, search, credit card formatting, and error validation. Implements `ControlValueAccessor`.
|
|
79
89
|
|
|
80
90
|
```html
|
|
81
91
|
<shk-text-field
|
|
82
|
-
[label]="'
|
|
92
|
+
[label]="'Name'"
|
|
83
93
|
[control]="myControl"
|
|
84
94
|
[type]="'text'"
|
|
85
|
-
[placeholder]="'
|
|
95
|
+
[placeholder]="'Enter your name'"
|
|
86
96
|
[disabled]="false"
|
|
87
|
-
[errorMessages]="{ required: '
|
|
97
|
+
[errorMessages]="{ required: 'This field is required' }"
|
|
88
98
|
[isTextArea]="false"
|
|
89
99
|
[searchMode]="false"
|
|
90
100
|
(searchButtonClick)="onSearch()"
|
|
91
101
|
/>
|
|
92
102
|
```
|
|
93
103
|
|
|
94
|
-
| Input
|
|
95
|
-
|
|
96
|
-
| `id`
|
|
97
|
-
| `label`
|
|
98
|
-
| `type`
|
|
99
|
-
| `placeholder`
|
|
100
|
-
| `disabled`
|
|
101
|
-
| `control`
|
|
102
|
-
| `formGroup`
|
|
103
|
-
| `errorMessage`
|
|
104
|
-
| `errorMessages`
|
|
105
|
-
| `isTextArea`
|
|
106
|
-
| `textAreaHeight`
|
|
107
|
-
| `searchMode`
|
|
108
|
-
| `searchButtonClick` | `output<void>`
|
|
109
|
-
| `numbersOnly`
|
|
110
|
-
| `allowDecimals`
|
|
111
|
-
| `maxLength`
|
|
112
|
-
| `formatCard`
|
|
113
|
-
| `preventNegative`
|
|
114
|
-
| `displayValue`
|
|
115
|
-
| `autocomplete`
|
|
116
|
-
|
|
117
|
-
>
|
|
104
|
+
| Input | Type | Default |
|
|
105
|
+
| ------------------- | --------------------------- | ---------------- |
|
|
106
|
+
| `id` | `string` | `''` |
|
|
107
|
+
| `label` | `string` | `''` |
|
|
108
|
+
| `type` | `string` | `'text'` |
|
|
109
|
+
| `placeholder` | `string` | `''` |
|
|
110
|
+
| `disabled` | `boolean` | `false` |
|
|
111
|
+
| `control` | `FormControl` | `undefined` |
|
|
112
|
+
| `formGroup` | `FormGroup` | `undefined` |
|
|
113
|
+
| `errorMessage` | `string` | `''` |
|
|
114
|
+
| `errorMessages` | `{ [key: string]: string }` | `{}` |
|
|
115
|
+
| `isTextArea` | `boolean` | `false` |
|
|
116
|
+
| `textAreaHeight` | `string` | `'h-28'` |
|
|
117
|
+
| `searchMode` | `boolean` | `false` |
|
|
118
|
+
| `searchButtonClick` | `output<void>` | — |
|
|
119
|
+
| `numbersOnly` | `boolean` | `false` |
|
|
120
|
+
| `allowDecimals` | `boolean` | `false` |
|
|
121
|
+
| `maxLength` | `number` | `undefined` |
|
|
122
|
+
| `formatCard` | `boolean` | `false` |
|
|
123
|
+
| `preventNegative` | `boolean` | `false` |
|
|
124
|
+
| `displayValue` | `string` | `''` |
|
|
125
|
+
| `autocomplete` | `string` | `'new-password'` |
|
|
126
|
+
|
|
127
|
+
> Also exposes `inputElement` and `textareaElement` as `viewChild`.
|
|
118
128
|
|
|
119
129
|
---
|
|
120
130
|
|
|
121
131
|
### Toggle (`shk-toggle`)
|
|
122
132
|
|
|
123
|
-
Switch
|
|
133
|
+
Switch or checkbox. Implements `ControlValueAccessor`.
|
|
124
134
|
|
|
125
135
|
```html
|
|
126
136
|
<shk-toggle
|
|
127
|
-
[label]="'
|
|
137
|
+
[label]="'Enable notifications'"
|
|
128
138
|
[mode]="'toggle'"
|
|
129
139
|
[(checked)]="isChecked"
|
|
130
140
|
(checkedChange)="onChange($event)"
|
|
131
141
|
/>
|
|
132
142
|
```
|
|
133
143
|
|
|
134
|
-
| Input
|
|
135
|
-
|
|
136
|
-
| `label`
|
|
137
|
-
| `mode`
|
|
138
|
-
| `checked` | `boolean`
|
|
144
|
+
| Input | Type | Default |
|
|
145
|
+
| --------- | ------------------------ | ----------- |
|
|
146
|
+
| `label` | `string` | `''` |
|
|
147
|
+
| `mode` | `'toggle' \| 'checkbox'` | `'toggle'` |
|
|
148
|
+
| `checked` | `boolean` | `undefined` |
|
|
139
149
|
|
|
140
|
-
| Output
|
|
141
|
-
|
|
150
|
+
| Output | Type |
|
|
151
|
+
| --------------- | --------- |
|
|
142
152
|
| `checkedChange` | `boolean` |
|
|
143
153
|
|
|
144
154
|
---
|
|
145
155
|
|
|
146
156
|
### Select (`shk-select`)
|
|
147
157
|
|
|
148
|
-
|
|
158
|
+
Searchable dropdown with pagination, multiple selection, custom options, and validation. Implements `ControlValueAccessor`.
|
|
149
159
|
|
|
150
160
|
```html
|
|
151
161
|
<shk-select
|
|
152
162
|
[options]="options"
|
|
153
|
-
[label]="'
|
|
163
|
+
[label]="'Country'"
|
|
154
164
|
[control]="countryControl"
|
|
155
165
|
[multiple]="false"
|
|
156
166
|
[isSearchable]="true"
|
|
157
167
|
[usePagination]="true"
|
|
158
168
|
[itemsPerPage]="10"
|
|
159
169
|
[allowCustomEntries]="false"
|
|
160
|
-
[placeholder]="'
|
|
170
|
+
[placeholder]="'Select...'"
|
|
161
171
|
[isLoading]="false"
|
|
162
172
|
(selectionChange)="onSelect($event)"
|
|
163
173
|
(search)="onSearch($event)"
|
|
@@ -172,42 +182,42 @@ interface SelectOption {
|
|
|
172
182
|
}
|
|
173
183
|
```
|
|
174
184
|
|
|
175
|
-
| Input
|
|
176
|
-
|
|
177
|
-
| `options`
|
|
178
|
-
| `label`
|
|
179
|
-
| `placeholder`
|
|
180
|
-
| `disabled`
|
|
181
|
-
| `control`
|
|
182
|
-
| `formGroup`
|
|
183
|
-
| `multiple`
|
|
184
|
-
| `isSearchable`
|
|
185
|
-
| `usePagination`
|
|
186
|
-
| `itemsPerPage`
|
|
187
|
-
| `allowCustomEntries`
|
|
188
|
-
| `isLoading`
|
|
189
|
-
| `isAllDataLoaded`
|
|
190
|
-
| `preserveSearchOnLoad` | `boolean`
|
|
191
|
-
| `dropdownUpward`
|
|
192
|
-
| `showEmptyOption`
|
|
193
|
-
| `emptyMessageKey`
|
|
194
|
-
| `validCombinations`
|
|
195
|
-
| `errorMessages`
|
|
196
|
-
|
|
197
|
-
| Output
|
|
198
|
-
|
|
199
|
-
| `selectionChange` | `any`
|
|
200
|
-
| `search`
|
|
185
|
+
| Input | Type | Default |
|
|
186
|
+
| ---------------------- | --------------------------- | ---------------------------------------- |
|
|
187
|
+
| `options` | `SelectOption[]` | `[]` |
|
|
188
|
+
| `label` | `string` | `undefined` |
|
|
189
|
+
| `placeholder` | `string` | `'Select...'` |
|
|
190
|
+
| `disabled` | `boolean` | `false` |
|
|
191
|
+
| `control` | `FormControl` | `undefined` |
|
|
192
|
+
| `formGroup` | `FormGroup` | `undefined` |
|
|
193
|
+
| `multiple` | `boolean` | `false` |
|
|
194
|
+
| `isSearchable` | `boolean` | `false` |
|
|
195
|
+
| `usePagination` | `boolean` | `false` |
|
|
196
|
+
| `itemsPerPage` | `number` | `10` |
|
|
197
|
+
| `allowCustomEntries` | `boolean` | `false` |
|
|
198
|
+
| `isLoading` | `boolean` | `false` |
|
|
199
|
+
| `isAllDataLoaded` | `boolean` | `false` |
|
|
200
|
+
| `preserveSearchOnLoad` | `boolean` | `false` |
|
|
201
|
+
| `dropdownUpward` | `boolean` | `false` |
|
|
202
|
+
| `showEmptyOption` | `boolean` | `true` |
|
|
203
|
+
| `emptyMessageKey` | `string` | `'common.no_records'` |
|
|
204
|
+
| `validCombinations` | `string[][]` | `undefined` |
|
|
205
|
+
| `errorMessages` | `{ [key: string]: string }` | `{ required: 'This field is required' }` |
|
|
206
|
+
|
|
207
|
+
| Output | Type |
|
|
208
|
+
| ----------------- | -------- |
|
|
209
|
+
| `selectionChange` | `any` |
|
|
210
|
+
| `search` | `string` |
|
|
201
211
|
|
|
202
212
|
---
|
|
203
213
|
|
|
204
214
|
### DatePicker (`shk-date-picker`)
|
|
205
215
|
|
|
206
|
-
|
|
216
|
+
Date, month, or year picker. Implements `ControlValueAccessor`. Supports `'date'`, `'month'`, `'year'` views.
|
|
207
217
|
|
|
208
218
|
```html
|
|
209
219
|
<shk-date-picker
|
|
210
|
-
[label]="'
|
|
220
|
+
[label]="'Start date'"
|
|
211
221
|
[control]="dateControl"
|
|
212
222
|
[view]="'date'"
|
|
213
223
|
[locale]="'es'"
|
|
@@ -216,67 +226,68 @@ Selector de fecha, mes o año. Implementa `ControlValueAccessor`. Soporta format
|
|
|
216
226
|
/>
|
|
217
227
|
```
|
|
218
228
|
|
|
219
|
-
| Input
|
|
220
|
-
|
|
221
|
-
| `id`
|
|
222
|
-
| `label`
|
|
223
|
-
| `placeholder`
|
|
224
|
-
| `view`
|
|
225
|
-
| `control`
|
|
226
|
-
| `formGroup`
|
|
227
|
-
| `disabled`
|
|
228
|
-
| `errorMessage`
|
|
229
|
-
| `errorMessages` | `{ [key: string]: string }`
|
|
230
|
-
| `minValue`
|
|
231
|
-
| `maxValue`
|
|
232
|
-
| `locale`
|
|
233
|
-
|
|
234
|
-
**
|
|
229
|
+
| Input | Type | Default |
|
|
230
|
+
| --------------- | ----------------------------- | ----------- |
|
|
231
|
+
| `id` | `string` | `''` |
|
|
232
|
+
| `label` | `string` | `''` |
|
|
233
|
+
| `placeholder` | `string` | `''` |
|
|
234
|
+
| `view` | `'date' \| 'month' \| 'year'` | `'date'` |
|
|
235
|
+
| `control` | `FormControl` | `undefined` |
|
|
236
|
+
| `formGroup` | `FormGroup` | `undefined` |
|
|
237
|
+
| `disabled` | `boolean` | `false` |
|
|
238
|
+
| `errorMessage` | `string` | `''` |
|
|
239
|
+
| `errorMessages` | `{ [key: string]: string }` | `{}` |
|
|
240
|
+
| `minValue` | `string` | `''` |
|
|
241
|
+
| `maxValue` | `string` | `''` |
|
|
242
|
+
| `locale` | `string` | `'es'` |
|
|
243
|
+
|
|
244
|
+
**Return value** depends on `view`:
|
|
245
|
+
|
|
235
246
|
- `'date'` → `'YYYY-MM-DD'`
|
|
236
247
|
- `'month'` → `'YYYY-MM'`
|
|
237
248
|
- `'year'` → `'YYYY'`
|
|
238
249
|
|
|
239
250
|
---
|
|
240
251
|
|
|
241
|
-
### PriceInput (`shk-price-input`
|
|
252
|
+
### PriceInput (`shk-price-input`)
|
|
242
253
|
|
|
243
|
-
|
|
254
|
+
Numeric input with toggle between amount (`$`) and percentage (`%`). Uses Angular `model()` for two-way binding.
|
|
244
255
|
|
|
245
256
|
```html
|
|
246
257
|
<shk-price-input
|
|
247
258
|
[(value)]="price"
|
|
248
259
|
[(isPercentage)]="isPercent"
|
|
249
|
-
[label]="'
|
|
260
|
+
[label]="'Price'"
|
|
250
261
|
[min]="0"
|
|
251
262
|
[max]="10000"
|
|
252
263
|
[required]="true"
|
|
253
264
|
[showError]="hasError"
|
|
254
|
-
[errorMessage]="'
|
|
265
|
+
[errorMessage]="'Invalid value'"
|
|
255
266
|
/>
|
|
256
267
|
```
|
|
257
268
|
|
|
258
|
-
| Input
|
|
259
|
-
|
|
260
|
-
| `value`
|
|
261
|
-
| `isPercentage` | `model<boolean>` | `false`
|
|
262
|
-
| `label`
|
|
263
|
-
| `inputId`
|
|
264
|
-
| `required`
|
|
265
|
-
| `disabled`
|
|
266
|
-
| `min`
|
|
267
|
-
| `max`
|
|
268
|
-
| `showError`
|
|
269
|
-
| `errorMessage` | `string`
|
|
269
|
+
| Input | Type | Default |
|
|
270
|
+
| -------------- | ---------------- | ------------ |
|
|
271
|
+
| `value` | `model<number>` | **required** |
|
|
272
|
+
| `isPercentage` | `model<boolean>` | `false` |
|
|
273
|
+
| `label` | `string` | `''` |
|
|
274
|
+
| `inputId` | `string` | `''` |
|
|
275
|
+
| `required` | `boolean` | `false` |
|
|
276
|
+
| `disabled` | `boolean` | `false` |
|
|
277
|
+
| `min` | `number` | `0` |
|
|
278
|
+
| `max` | `number` | `Infinity` |
|
|
279
|
+
| `showError` | `boolean` | `false` |
|
|
280
|
+
| `errorMessage` | `string` | `''` |
|
|
270
281
|
|
|
271
282
|
---
|
|
272
283
|
|
|
273
284
|
### FileUpload (`shk-file-upload`)
|
|
274
285
|
|
|
275
|
-
|
|
286
|
+
File upload with drag & drop, image preview, file type and size validation.
|
|
276
287
|
|
|
277
288
|
```html
|
|
278
289
|
<shk-file-upload
|
|
279
|
-
[label]="'
|
|
290
|
+
[label]="'Upload your photo'"
|
|
280
291
|
[accept]="'image/*'"
|
|
281
292
|
[maxFileSize]="5 * 1024 * 1024"
|
|
282
293
|
[maxFiles]="3"
|
|
@@ -295,29 +306,29 @@ interface FileUploadError {
|
|
|
295
306
|
}
|
|
296
307
|
```
|
|
297
308
|
|
|
298
|
-
| Input
|
|
299
|
-
|
|
300
|
-
| `label`
|
|
301
|
-
| `accept`
|
|
302
|
-
| `maxFileSize`
|
|
303
|
-
| `maxFiles`
|
|
304
|
-
| `multiple`
|
|
305
|
-
| `fileUploadText`
|
|
306
|
-
| `changeFilesText`
|
|
307
|
-
| `fileRecommendation` | `string`
|
|
308
|
-
|
|
309
|
-
| Output
|
|
310
|
-
|
|
311
|
-
| `fileSelected` | `File[]`
|
|
312
|
-
| `fileRemoved`
|
|
313
|
-
| `fileError`
|
|
314
|
-
| `fileWarning`
|
|
309
|
+
| Input | Type | Default |
|
|
310
|
+
| -------------------- | --------- | ----------------------- |
|
|
311
|
+
| `label` | `string` | `'Upload file'` |
|
|
312
|
+
| `accept` | `string` | `'image/*'` |
|
|
313
|
+
| `maxFileSize` | `number` | `2 * 1024 * 1024` (2MB) |
|
|
314
|
+
| `maxFiles` | `number` | `0` (unlimited) |
|
|
315
|
+
| `multiple` | `boolean` | `false` |
|
|
316
|
+
| `fileUploadText` | `string` | `'Select file'` |
|
|
317
|
+
| `changeFilesText` | `string` | `'Change files'` |
|
|
318
|
+
| `fileRecommendation` | `string` | `''` |
|
|
319
|
+
|
|
320
|
+
| Output | Type |
|
|
321
|
+
| -------------- | ----------------- |
|
|
322
|
+
| `fileSelected` | `File[]` |
|
|
323
|
+
| `fileRemoved` | `void` |
|
|
324
|
+
| `fileError` | `FileUploadError` |
|
|
325
|
+
| `fileWarning` | `FileUploadError` |
|
|
315
326
|
|
|
316
327
|
---
|
|
317
328
|
|
|
318
329
|
### Table (`shk-table`)
|
|
319
330
|
|
|
320
|
-
|
|
331
|
+
Data table with sorting, column filters, global search, pagination, row actions, and header actions. Supports client and server-side mode.
|
|
321
332
|
|
|
322
333
|
```html
|
|
323
334
|
<shk-table
|
|
@@ -384,41 +395,41 @@ interface FilterChangeEvent {
|
|
|
384
395
|
}
|
|
385
396
|
```
|
|
386
397
|
|
|
387
|
-
| Input
|
|
388
|
-
|
|
389
|
-
| `data`
|
|
390
|
-
| `columns`
|
|
391
|
-
| `rowsPerPage`
|
|
392
|
-
| `rowsPerPageOptions` | `number[]`
|
|
393
|
-
| `loading`
|
|
394
|
-
| `showActionRow`
|
|
395
|
-
| `headerActions`
|
|
396
|
-
| `rowActions`
|
|
397
|
-
| `hasShadow`
|
|
398
|
-
| `defaultSortField`
|
|
399
|
-
| `defaultSortOrder`
|
|
400
|
-
| `showSearch`
|
|
401
|
-
| `searchPlaceholder`
|
|
402
|
-
| `emptyMessage`
|
|
403
|
-
| `serverSide`
|
|
404
|
-
| `totalRecords`
|
|
405
|
-
| `filters`
|
|
406
|
-
| `activeFilter`
|
|
407
|
-
| `customTemplates`
|
|
408
|
-
|
|
409
|
-
| Output
|
|
410
|
-
|
|
411
|
-
| `pageChange`
|
|
398
|
+
| Input | Type | Default |
|
|
399
|
+
| -------------------- | ------------------------------------ | -------------- |
|
|
400
|
+
| `data` | `any[]` | `[]` |
|
|
401
|
+
| `columns` | `Column[]` | `[]` |
|
|
402
|
+
| `rowsPerPage` | `number` | `10` |
|
|
403
|
+
| `rowsPerPageOptions` | `number[]` | `[10, 25, 50]` |
|
|
404
|
+
| `loading` | `boolean` | `false` |
|
|
405
|
+
| `showActionRow` | `boolean` | `true` |
|
|
406
|
+
| `headerActions` | `TableAction[]` | `[]` |
|
|
407
|
+
| `rowActions` | `RowAction[]` | `[]` |
|
|
408
|
+
| `hasShadow` | `boolean` | `true` |
|
|
409
|
+
| `defaultSortField` | `string` | `''` |
|
|
410
|
+
| `defaultSortOrder` | `number` | `1` |
|
|
411
|
+
| `showSearch` | `boolean` | `true` |
|
|
412
|
+
| `searchPlaceholder` | `string` | `''` |
|
|
413
|
+
| `emptyMessage` | `string` | `''` |
|
|
414
|
+
| `serverSide` | `boolean` | `false` |
|
|
415
|
+
| `totalRecords` | `number` | `0` |
|
|
416
|
+
| `filters` | `{ label: string; value: string }[]` | `[]` |
|
|
417
|
+
| `activeFilter` | `string` | `''` |
|
|
418
|
+
| `customTemplates` | `{ [key: string]: any }` | `{}` |
|
|
419
|
+
|
|
420
|
+
| Output | Type |
|
|
421
|
+
| -------------- | ------------------- |
|
|
422
|
+
| `pageChange` | `PageChangeEvent` |
|
|
412
423
|
| `filterChange` | `FilterChangeEvent` |
|
|
413
|
-
| `searchChange` | `string`
|
|
414
|
-
| `filterClick`
|
|
415
|
-
| `refresh`
|
|
424
|
+
| `searchChange` | `string` |
|
|
425
|
+
| `filterClick` | `string` |
|
|
426
|
+
| `refresh` | `void` |
|
|
416
427
|
|
|
417
428
|
---
|
|
418
429
|
|
|
419
430
|
### Modal (`shk-modal`)
|
|
420
431
|
|
|
421
|
-
|
|
432
|
+
Dynamic modal that loads components via `ModalService`. Supports forms, fullscreen expansion, and accept/cancel buttons.
|
|
422
433
|
|
|
423
434
|
```html
|
|
424
435
|
<shk-modal />
|
|
@@ -438,19 +449,20 @@ interface ModalConfig {
|
|
|
438
449
|
}
|
|
439
450
|
```
|
|
440
451
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
- `
|
|
444
|
-
- `submitSuccess
|
|
445
|
-
- `
|
|
446
|
-
- `
|
|
452
|
+
The injected component **must** expose:
|
|
453
|
+
|
|
454
|
+
- `form?: FormGroup` (optional, for validation)
|
|
455
|
+
- `onSubmit()` → calls `submitSuccess` or `submitError`
|
|
456
|
+
- `submitSuccess?: EventEmitter<void>` (optional)
|
|
457
|
+
- `submitError?: EventEmitter<void>` (optional)
|
|
458
|
+
- `handleCancel?: () => void` (optional)
|
|
447
459
|
|
|
448
460
|
```typescript
|
|
449
461
|
constructor(private modalSrv: ModalService) {}
|
|
450
462
|
|
|
451
463
|
openModal() {
|
|
452
464
|
this.modalSrv.open({
|
|
453
|
-
title: '
|
|
465
|
+
title: 'Edit user',
|
|
454
466
|
component: EditUserComponent,
|
|
455
467
|
data: { userId: 123 },
|
|
456
468
|
width: '600px',
|
|
@@ -464,20 +476,20 @@ closeModal() {
|
|
|
464
476
|
}
|
|
465
477
|
```
|
|
466
478
|
|
|
467
|
-
**
|
|
479
|
+
**Service methods:**
|
|
468
480
|
|
|
469
|
-
|
|
|
470
|
-
|
|
471
|
-
| `open(config: ModalConfig)` |
|
|
472
|
-
| `close()`
|
|
473
|
-
| `accept()`
|
|
474
|
-
| `clear()`
|
|
481
|
+
| Method | Description |
|
|
482
|
+
| --------------------------- | ---------------------------------- |
|
|
483
|
+
| `open(config: ModalConfig)` | Opens a new modal |
|
|
484
|
+
| `close()` | Closes the current modal |
|
|
485
|
+
| `accept()` | Closes the modal (alias for close) |
|
|
486
|
+
| `clear()` | Closes all modals |
|
|
475
487
|
|
|
476
488
|
---
|
|
477
489
|
|
|
478
490
|
### Notification (`shk-notification`)
|
|
479
491
|
|
|
480
|
-
|
|
492
|
+
Toast notification system with configurable positions and optional progress bar.
|
|
481
493
|
|
|
482
494
|
```html
|
|
483
495
|
<shk-notification position="right-top" />
|
|
@@ -498,7 +510,7 @@ constructor(private notifSrv: NotificationService) {}
|
|
|
498
510
|
|
|
499
511
|
showNotif() {
|
|
500
512
|
const id = this.notifSrv.addNotification(
|
|
501
|
-
'
|
|
513
|
+
'Operation successful',
|
|
502
514
|
'success',
|
|
503
515
|
false, // showProgress
|
|
504
516
|
3000 // duration (ms)
|
|
@@ -510,28 +522,28 @@ updateProgress(id: string, progress: number) {
|
|
|
510
522
|
}
|
|
511
523
|
```
|
|
512
524
|
|
|
513
|
-
| Input
|
|
514
|
-
|
|
525
|
+
| Input | Type | Default |
|
|
526
|
+
| ---------- | ------------------------------------------- | -------------- |
|
|
515
527
|
| `position` | `'center-top' \| 'right-top' \| 'left-top'` | `'center-top'` |
|
|
516
528
|
|
|
517
|
-
**
|
|
529
|
+
**Service methods:**
|
|
518
530
|
|
|
519
|
-
|
|
|
520
|
-
|
|
521
|
-
| `addNotification(msg, type?, showProgress?, duration?)` |
|
|
522
|
-
| `updateProgress(id, progress)`
|
|
523
|
-
| `removeNotification(notification)`
|
|
524
|
-
| `removeNotificationById(id)`
|
|
525
|
-
| `clearAll()`
|
|
531
|
+
| Method | Description |
|
|
532
|
+
| ------------------------------------------------------- | ------------------------- |
|
|
533
|
+
| `addNotification(msg, type?, showProgress?, duration?)` | Adds a notification |
|
|
534
|
+
| `updateProgress(id, progress)` | Updates the progress bar |
|
|
535
|
+
| `removeNotification(notification)` | Removes a notification |
|
|
536
|
+
| `removeNotificationById(id)` | Removes by ID |
|
|
537
|
+
| `clearAll()` | Removes all notifications |
|
|
526
538
|
|
|
527
539
|
---
|
|
528
540
|
|
|
529
541
|
### ConfirmDialog (`shk-confirm-dialog`)
|
|
530
542
|
|
|
531
|
-
|
|
543
|
+
Programmatic confirmation dialog. Used via `ConfirmDialogService` which dynamically creates it.
|
|
532
544
|
|
|
533
545
|
```html
|
|
534
|
-
<!-- No
|
|
546
|
+
<!-- No need to add it to the template -->
|
|
535
547
|
```
|
|
536
548
|
|
|
537
549
|
```typescript
|
|
@@ -552,120 +564,279 @@ constructor(private confirmSrv: ConfirmDialogService) {}
|
|
|
552
564
|
|
|
553
565
|
async deleteItem() {
|
|
554
566
|
const confirmed = await this.confirmSrv.confirm({
|
|
555
|
-
title: '
|
|
556
|
-
message: '
|
|
557
|
-
confirmLabel: '
|
|
567
|
+
title: 'Delete user',
|
|
568
|
+
message: 'Are you sure you want to delete this user?',
|
|
569
|
+
confirmLabel: 'Delete',
|
|
558
570
|
type: 'danger',
|
|
559
571
|
});
|
|
560
572
|
|
|
561
573
|
if (confirmed) {
|
|
562
|
-
//
|
|
574
|
+
// proceed with deletion
|
|
563
575
|
}
|
|
564
576
|
}
|
|
565
577
|
```
|
|
566
578
|
|
|
567
|
-
| Input
|
|
568
|
-
|
|
569
|
-
| `title`
|
|
570
|
-
| `message`
|
|
571
|
-
| `confirmLabel` | `string`
|
|
572
|
-
| `cancelLabel`
|
|
573
|
-
| `loadingText`
|
|
574
|
-
| `type`
|
|
575
|
-
| `loading`
|
|
576
|
-
| `showCancel`
|
|
577
|
-
|
|
578
|
-
| Output
|
|
579
|
-
|
|
579
|
+
| Input | Type | Default |
|
|
580
|
+
| -------------- | --------------------------------- | ------------------------------------- |
|
|
581
|
+
| `title` | `string` | `'Confirm action'` |
|
|
582
|
+
| `message` | `string` | `'Are you sure you want to proceed?'` |
|
|
583
|
+
| `confirmLabel` | `string` | `'Confirm'` |
|
|
584
|
+
| `cancelLabel` | `string` | `'Cancel'` |
|
|
585
|
+
| `loadingText` | `string` | `'Processing…'` |
|
|
586
|
+
| `type` | `'danger' \| 'info' \| 'warning'` | `'danger'` |
|
|
587
|
+
| `loading` | `boolean` | `false` |
|
|
588
|
+
| `showCancel` | `boolean` | `true` |
|
|
589
|
+
|
|
590
|
+
| Output | Type |
|
|
591
|
+
| -------- | ------ |
|
|
580
592
|
| `closed` | `void` |
|
|
581
593
|
|
|
582
594
|
---
|
|
583
595
|
|
|
584
596
|
### Chart (`shk-chart`)
|
|
585
597
|
|
|
586
|
-
|
|
598
|
+
Chart.js wrapper supporting the main chart types.
|
|
587
599
|
|
|
588
600
|
```html
|
|
589
|
-
<shk-chart
|
|
590
|
-
[type]="'bar'"
|
|
591
|
-
[data]="chartData"
|
|
592
|
-
[options]="chartOptions"
|
|
593
|
-
/>
|
|
601
|
+
<shk-chart [type]="'bar'" [data]="chartData" [options]="chartOptions" />
|
|
594
602
|
```
|
|
595
603
|
|
|
596
604
|
```typescript
|
|
597
605
|
import { COLOR_PALETTE, readThemeColors } from 'shirkasoft-ui-components';
|
|
598
606
|
|
|
599
|
-
const colors = readThemeColors(); //
|
|
607
|
+
const colors = readThemeColors(); // current theme colors
|
|
600
608
|
```
|
|
601
609
|
|
|
602
|
-
| Input
|
|
603
|
-
|
|
604
|
-
| `type`
|
|
605
|
-
| `data`
|
|
606
|
-
| `options` | `any`
|
|
610
|
+
| Input | Type | Default |
|
|
611
|
+
| --------- | ------------------------------------------------------- | ------------------ |
|
|
612
|
+
| `type` | `'line' \| 'bar' \| 'pie' \| 'doughnut' \| 'polarArea'` | `'bar'` |
|
|
613
|
+
| `data` | `any` | `{ datasets: [] }` |
|
|
614
|
+
| `options` | `any` | `{}` |
|
|
607
615
|
|
|
608
|
-
**
|
|
616
|
+
**Exported utils:**
|
|
609
617
|
|
|
610
|
-
| Export
|
|
611
|
-
|
|
612
|
-
| `COLOR_PALETTE`
|
|
613
|
-
| `readThemeColors()` |
|
|
618
|
+
| Export | Description |
|
|
619
|
+
| ------------------- | ---------------------------------------------- |
|
|
620
|
+
| `COLOR_PALETTE` | Predefined color array (bg + border) |
|
|
621
|
+
| `readThemeColors()` | Reads current theme colors (`--shk-surface-*`) |
|
|
614
622
|
|
|
615
623
|
---
|
|
616
624
|
|
|
617
625
|
### Tooltip (`shk-tooltip`)
|
|
618
626
|
|
|
619
|
-
Tooltip
|
|
627
|
+
Tooltip with two modes: `hover` (CSS positioning) and `fixed` (JS-calculated positioning).
|
|
620
628
|
|
|
621
629
|
```html
|
|
622
|
-
<shk-tooltip [text]="'
|
|
623
|
-
<button>
|
|
630
|
+
<shk-tooltip [text]="'Additional info'" [position]="'bottom'" [mode]="'hover'">
|
|
631
|
+
<button>Hover me</button>
|
|
624
632
|
</shk-tooltip>
|
|
625
633
|
```
|
|
626
634
|
|
|
627
|
-
| Input
|
|
628
|
-
|
|
629
|
-
| `text`
|
|
635
|
+
| Input | Type | Default |
|
|
636
|
+
| ---------- | ------------------------------ | ---------- |
|
|
637
|
+
| `text` | `string` | `''` |
|
|
630
638
|
| `position` | `'top' \| 'bottom' \| 'right'` | `'bottom'` |
|
|
631
|
-
| `mode`
|
|
632
|
-
| `offset`
|
|
639
|
+
| `mode` | `'hover' \| 'fixed'` | `'hover'` |
|
|
640
|
+
| `offset` | `number` | `8` |
|
|
633
641
|
|
|
634
642
|
---
|
|
635
643
|
|
|
636
|
-
|
|
644
|
+
### Sidebar (`shk-sidebar`)
|
|
645
|
+
|
|
646
|
+
Brand/logo header, round collapse toggle with tooltip, expandable groups with nested children, standalone items, Lucide icons, badges, separators, disabled items, active-item highlighting (`primary`-600 with white text), projected `header`/`content`/`footer` slots, tooltips on collapsed items, and a responsive off-canvas mode below 1024px. Uses the same theme tokens (`--shk-*`) as the rest of the library.
|
|
647
|
+
|
|
648
|
+
```html
|
|
649
|
+
<shk-sidebar
|
|
650
|
+
[items]="items"
|
|
651
|
+
[(collapsed)]="collapsed"
|
|
652
|
+
[activeItemId]="activeId"
|
|
653
|
+
title="WS Admin"
|
|
654
|
+
subtitle="Panel de control"
|
|
655
|
+
logo="/logo.svg"
|
|
656
|
+
[defaultExpanded]="['products']"
|
|
657
|
+
(itemClick)="onItemClick($event)"
|
|
658
|
+
>
|
|
659
|
+
<div sidebarFooter>
|
|
660
|
+
<button (click)="logout()">Cerrar sesión</button>
|
|
661
|
+
</div>
|
|
662
|
+
</shk-sidebar>
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
interface SidebarItem {
|
|
667
|
+
id: string;
|
|
668
|
+
label: string;
|
|
669
|
+
icon?: string; // Lucide icon name
|
|
670
|
+
badge?: string | number;
|
|
671
|
+
disabled?: boolean;
|
|
672
|
+
separator?: boolean; // renders a divider before the item
|
|
673
|
+
route?: string; // navigation target (optional)
|
|
674
|
+
roles?: string[]; // when `userRole` is set, items are filtered
|
|
675
|
+
children?: SidebarItem[]; // renders an expandable group with nested items
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
interface SidebarGroup {
|
|
679
|
+
id?: string;
|
|
680
|
+
label?: string;
|
|
681
|
+
items: SidebarItem[];
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
| Input | Type | Default |
|
|
686
|
+
| ----------------- | --------------------------- | --------------------------------------------- |
|
|
687
|
+
| `items` | `SidebarItem[]` | `[]` |
|
|
688
|
+
| `groups` | `SidebarGroup[]` | `[]` (when set, overrides `items`) |
|
|
689
|
+
| `title` | `string` | `''` |
|
|
690
|
+
| `subtitle` | `string` | `''` |
|
|
691
|
+
| `logo` | `string` | `''` (image URL shown in the brand header) |
|
|
692
|
+
| `collapsed` | `model<boolean>` | `false` |
|
|
693
|
+
| `mobileOpen` | `model<boolean>` | `false` (off-canvas state on mobile) |
|
|
694
|
+
| `collapsible` | `boolean` | `true` |
|
|
695
|
+
| `showToggle` | `boolean` | `true` |
|
|
696
|
+
| `responsive` | `boolean` | `true` (off-canvas below 1024px) |
|
|
697
|
+
| `fixed` | `boolean` | `false` (uses `position: fixed` + `h-screen`) |
|
|
698
|
+
| `hasShadow` | `boolean` | `true` |
|
|
699
|
+
| `expandedWidth` | `string` | `'16rem'` |
|
|
700
|
+
| `collapsedWidth` | `string` | `'5rem'` |
|
|
701
|
+
| `activeItemId` | `string` | `''` |
|
|
702
|
+
| `userRole` | `string` | `''` (filters items by `roles`) |
|
|
703
|
+
| `defaultExpanded` | `string[]` | `[]` (groups expanded on init) |
|
|
704
|
+
| `labelPipe` | `(label: string) => string` | identity (e.g. pass a Transloco translate fn) |
|
|
705
|
+
| `expandTooltip` | `string` | `'Expandir'` |
|
|
706
|
+
| `collapseTooltip` | `string` | `'Colapsar'` |
|
|
707
|
+
|
|
708
|
+
| Output | Type |
|
|
709
|
+
| ----------- | ------------- |
|
|
710
|
+
| `itemClick` | `SidebarItem` |
|
|
711
|
+
| `toggle` | `boolean` |
|
|
712
|
+
|
|
713
|
+
**Projected slots:**
|
|
714
|
+
|
|
715
|
+
| Slot | Description |
|
|
716
|
+
| ---------------- | --------------------------------------------------- |
|
|
717
|
+
| `sidebarHeader` | Brand/logo area (rendered before the title) |
|
|
718
|
+
| `sidebarContent` | Custom content between the header and the nav |
|
|
719
|
+
| `sidebarFooter` | Footer area (e.g. logout button); hidden when empty |
|
|
720
|
+
|
|
721
|
+
> Icons are resolved by name via a Lucide map with a `Menu` fallback. Use `[fixed]="true"` for a full-screen sidebar (as in ws-admin) or leave it embedded in a container for previews.
|
|
722
|
+
|
|
723
|
+
### Rail Sidebar (`shk-rail-sidebar`)
|
|
724
|
+
|
|
725
|
+
Sidebar estilo rail + nav, una columna vertical de iconos (una por sección) y un panel con el menú de la sección activa, con subgrupos expandibles, toggle de idioma, botón de logout y colapso.
|
|
726
|
+
|
|
727
|
+
```html
|
|
728
|
+
<shk-rail-sidebar
|
|
729
|
+
[sections]="sections"
|
|
730
|
+
[activeUrl]="router.url"
|
|
731
|
+
[(activeSectionKey)]="activeSectionKey"
|
|
732
|
+
[(collapsed)]="collapsed"
|
|
733
|
+
[activeLang]="transloco.getActiveLang()"
|
|
734
|
+
appName="WAC Bookings"
|
|
735
|
+
logo="/logo.png"
|
|
736
|
+
(sectionSelected)="onSectionSelected($event)"
|
|
737
|
+
(itemClick)="onItemClick($event)"
|
|
738
|
+
(setLang)="onSetLanguage($event)"
|
|
739
|
+
(logoutRequested)="requestLogout()"
|
|
740
|
+
/>
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
```ts
|
|
744
|
+
interface RailSidebarSection {
|
|
745
|
+
key: string;
|
|
746
|
+
label: string;
|
|
747
|
+
icon?: string; // nombre del icono Lucide
|
|
748
|
+
routerLink?: string; // ruta de la sección (selección automática por URL)
|
|
749
|
+
matchPrefixes?: string[]; // prefijos de URL que activan la sección
|
|
750
|
+
items?: RailSidebarItem[]; // menú del panel cuando la sección está activa
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
interface RailSidebarItem {
|
|
754
|
+
id: string;
|
|
755
|
+
label: string;
|
|
756
|
+
icon?: string;
|
|
757
|
+
routerLink?: string;
|
|
758
|
+
children?: RailSidebarItem[]; // subgrupo expandible
|
|
759
|
+
roles?: string[]; // filtro por rol (userRole)
|
|
760
|
+
badge?: string | number;
|
|
761
|
+
disabled?: boolean;
|
|
762
|
+
separator?: boolean;
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
| Input | Type | Default |
|
|
767
|
+
| ------------------ | ---------------------- | --------------------------------------------------------- |
|
|
768
|
+
| `sections` | `RailSidebarSection[]` | `[]` |
|
|
769
|
+
| `activeUrl` | `string` | `''` — activa la sección por `matchPrefixes`/`routerLink` |
|
|
770
|
+
| `activeSectionKey` | `string` (model) | `''` |
|
|
771
|
+
| `collapsed` | `boolean` (model) | `false` |
|
|
772
|
+
| `activeLang` | `string` | `'es'` |
|
|
773
|
+
| `langs` | `string[]` | `['es', 'en']` — idiomas al togglear |
|
|
774
|
+
| `logo` | `string` | `''` — imagen del workspace |
|
|
775
|
+
| `appName` | `string` | `''` — título del panel |
|
|
776
|
+
| `userRole` | `string` | `''` — filtra `items.roles` |
|
|
777
|
+
| `labelPipe` | `(label) => string` | identidad (para transloco) |
|
|
778
|
+
| `railWidth` | `string` | `'4.5rem'` |
|
|
779
|
+
| `expandedWidth` | `string` | `'16.5rem'` |
|
|
780
|
+
|
|
781
|
+
| Output | Type |
|
|
782
|
+
| ----------------- | ---------------------- |
|
|
783
|
+
| `sectionSelected` | `{ key, routerLink? }` |
|
|
784
|
+
| `itemClick` | `RailSidebarItem` |
|
|
785
|
+
| `setLang` | `string` |
|
|
786
|
+
| `logoutRequested` | `void` |
|
|
787
|
+
| `toggleSidebar` | `void` |
|
|
788
|
+
| `workspaceClick` | `void` |
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## Development
|
|
637
793
|
|
|
638
794
|
```bash
|
|
639
|
-
#
|
|
795
|
+
# Build the library
|
|
640
796
|
pnpm build
|
|
641
797
|
|
|
642
|
-
#
|
|
798
|
+
# Serve the showcase (demo app)
|
|
643
799
|
pnpm serve
|
|
644
800
|
|
|
645
|
-
#
|
|
801
|
+
# Build the showcase
|
|
646
802
|
pnpm build:showcase
|
|
647
803
|
|
|
648
|
-
#
|
|
804
|
+
# Watch for library changes
|
|
649
805
|
pnpm watch
|
|
650
806
|
```
|
|
651
807
|
|
|
652
|
-
###
|
|
808
|
+
### Versioning
|
|
809
|
+
|
|
810
|
+
```bash
|
|
811
|
+
pnpm version:patch # 1.0.23 → 1.0.24 (creates commit + tag locally)
|
|
812
|
+
pnpm version:minor # 1.0.23 → 1.1.0
|
|
813
|
+
pnpm version:major # 1.0.23 → 2.0.0
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Push code (without publishing)
|
|
653
817
|
|
|
654
818
|
```bash
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
819
|
+
git push origin main
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### Push code + publish to npm
|
|
823
|
+
|
|
824
|
+
```bash
|
|
825
|
+
git push origin main --tags
|
|
658
826
|
```
|
|
659
827
|
|
|
660
828
|
---
|
|
661
829
|
|
|
662
|
-
##
|
|
830
|
+
## Publishing
|
|
831
|
+
|
|
832
|
+
### CI/CD via GitHub Actions
|
|
663
833
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
834
|
+
| Workflow | Trigger | Description |
|
|
835
|
+
| ------------------- | --------------------------------------------- | ------------------------------------------------------------------------- |
|
|
836
|
+
| **Publish to npm** | Manual (`workflow_dispatch`) or push `v*` tag | Builds library, publishes to npm, builds showcase, deploys to public repo |
|
|
837
|
+
| **Deploy Showcase** | Push to `main`/`master` or manual | Builds library + showcase, deploys to GitHub Pages public repo |
|
|
667
838
|
|
|
668
|
-
Manual
|
|
839
|
+
### Manual publish (without GitHub Actions)
|
|
669
840
|
|
|
670
841
|
```bash
|
|
671
842
|
bash scripts/publish-lib.sh
|
|
@@ -673,6 +844,6 @@ bash scripts/publish-lib.sh
|
|
|
673
844
|
|
|
674
845
|
---
|
|
675
846
|
|
|
676
|
-
##
|
|
847
|
+
## License
|
|
677
848
|
|
|
678
849
|
MIT © Shirkasoft
|