@xleddyl/443-components-vue 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export declare function stringifyCellValue(value: unknown): string;
2
+ export declare function formatTsv(rows: string[][]): string;
3
+ export declare function parseTsv(input: string): string[][];
@@ -0,0 +1,88 @@
1
+ function pad(value) {
2
+ return String(value).padStart(2, "0");
3
+ }
4
+ function formatDate(value) {
5
+ if (Number.isNaN(value.getTime())) return "";
6
+ const date = `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}`;
7
+ if (!value.getHours() && !value.getMinutes() && !value.getSeconds()) return date;
8
+ return `${date}T${pad(value.getHours())}:${pad(value.getMinutes())}:${pad(value.getSeconds())}`;
9
+ }
10
+ export function stringifyCellValue(value) {
11
+ if (value === null || value === void 0) return "";
12
+ if (value instanceof Date) return formatDate(value);
13
+ if (Array.isArray(value)) return value.map(stringifyCellValue).join(", ");
14
+ if (typeof value === "object") {
15
+ try {
16
+ return JSON.stringify(value);
17
+ } catch {
18
+ return String(value);
19
+ }
20
+ }
21
+ return String(value);
22
+ }
23
+ function quoteField(value) {
24
+ if (!/[\t\n\r]/.test(value) && !value.startsWith('"')) return value;
25
+ return `"${value.replace(/"/g, '""')}"`;
26
+ }
27
+ export function formatTsv(rows) {
28
+ return rows.map((row) => row.map(quoteField).join(" ")).join("\n");
29
+ }
30
+ function readQuoted(text, start) {
31
+ let value = "";
32
+ let index = start + 1;
33
+ while (index < text.length) {
34
+ const char = text[index];
35
+ if (char === '"') {
36
+ if (text[index + 1] === '"') {
37
+ value += '"';
38
+ index += 2;
39
+ continue;
40
+ }
41
+ return { value, end: index + 1 };
42
+ }
43
+ value += char;
44
+ index += 1;
45
+ }
46
+ return null;
47
+ }
48
+ export function parseTsv(input) {
49
+ const text = input.replace(/\r\n?/g, "\n").replace(/\n$/, "");
50
+ const rows = [];
51
+ let row = [];
52
+ let field = "";
53
+ let fieldStart = true;
54
+ let index = 0;
55
+ while (index < text.length) {
56
+ const char = text[index];
57
+ if (fieldStart && char === '"') {
58
+ const quoted = readQuoted(text, index);
59
+ if (quoted) {
60
+ field = quoted.value;
61
+ index = quoted.end;
62
+ fieldStart = false;
63
+ continue;
64
+ }
65
+ }
66
+ fieldStart = false;
67
+ if (char === " ") {
68
+ row.push(field);
69
+ field = "";
70
+ fieldStart = true;
71
+ } else if (char === "\n") {
72
+ row.push(field);
73
+ rows.push(row);
74
+ row = [];
75
+ field = "";
76
+ fieldStart = true;
77
+ } else {
78
+ field += char;
79
+ }
80
+ index += 1;
81
+ }
82
+ row.push(field);
83
+ rows.push(row);
84
+ const width = Math.max(...rows.map((cells) => cells.length));
85
+ return rows.map(
86
+ (cells) => cells.length < width ? [...cells, ...Array(width - cells.length).fill("")] : cells
87
+ );
88
+ }
@@ -65,3 +65,84 @@ export interface LinkCellParams<T = unknown> {
65
65
  export type CellProps<P> = {
66
66
  params: ICellRendererParams & P;
67
67
  };
68
+ export type GridChangeSource = 'edit' | 'paste' | 'fill' | 'clear' | 'bulk' | 'undo' | 'redo';
69
+ export interface GridCellChange {
70
+ rowId: string;
71
+ colId: string;
72
+ field: string;
73
+ oldValue: unknown;
74
+ newValue: unknown;
75
+ }
76
+ export interface GridCellsChange {
77
+ changes: GridCellChange[];
78
+ source: GridChangeSource;
79
+ }
80
+ export interface GridInvalidCell {
81
+ rowId: string;
82
+ colId: string;
83
+ field: string;
84
+ text: string;
85
+ }
86
+ export interface GridCellsInvalid {
87
+ cells: GridInvalidCell[];
88
+ source: GridChangeSource;
89
+ }
90
+ export interface GridDirtyCell {
91
+ rowId: string;
92
+ colId: string;
93
+ field: string;
94
+ originalValue: unknown;
95
+ }
96
+ export interface GridCellPosition {
97
+ rowIndex: number;
98
+ colId: string;
99
+ }
100
+ export interface GridCellRange {
101
+ startRowIndex: number;
102
+ endRowIndex: number;
103
+ columns: string[];
104
+ active: GridCellPosition;
105
+ }
106
+ export interface GridRangeInput {
107
+ startRowIndex: number;
108
+ endRowIndex?: number;
109
+ startColumn: string;
110
+ endColumn?: string;
111
+ }
112
+ export interface GridSelectedCell<T = unknown> {
113
+ rowId: string;
114
+ rowIndex: number;
115
+ colId: string;
116
+ field: string;
117
+ value: unknown;
118
+ data: T | undefined;
119
+ editable: boolean;
120
+ }
121
+ export interface GridSetRangeValueOptions {
122
+ parse?: boolean;
123
+ }
124
+ export interface GridSpreadsheetMethods<T = unknown> {
125
+ getRange: () => GridCellRange | null;
126
+ getSelectedCells: () => GridSelectedCell<T>[];
127
+ selectRange: (range: GridRangeInput) => void;
128
+ selectAll: () => void;
129
+ clearRange: () => void;
130
+ setRangeValue: (value: unknown, options?: GridSetRangeValueOptions) => number;
131
+ copyRange: () => Promise<string | null>;
132
+ paste: (text: string) => number;
133
+ fillDown: () => number;
134
+ fillRight: () => number;
135
+ clearCells: () => number;
136
+ undo: () => boolean;
137
+ redo: () => boolean;
138
+ clearHistory: () => void;
139
+ getDirtyCells: () => GridDirtyCell[];
140
+ clearDirty: (rowIds?: string[]) => void;
141
+ }
142
+ export interface GridSpreadsheetSlotProps<T = unknown> extends GridSpreadsheetMethods<T> {
143
+ range: GridCellRange | null;
144
+ selectedCellCount: number;
145
+ dirtyCount: number;
146
+ canUndo: boolean;
147
+ canRedo: boolean;
148
+ }
@@ -102,7 +102,16 @@ export const de = {
102
102
  selectAllHint: "Leertaste dr\xFCcken, um alle Zeilen aus- oder abzuw\xE4hlen",
103
103
  selectAllRows: "Alle Zeilen ausw\xE4hlen",
104
104
  sortHint: "Eingabetaste dr\xFCcken, um zu sortieren",
105
- tooltip: "Tooltip"
105
+ tooltip: "Tooltip",
106
+ cellsCopied: "{count} Zelle kopiert | {count} Zellen kopiert",
107
+ cellsPasted: "{count} Zelle eingef\xFCgt | {count} Zellen eingef\xFCgt",
108
+ cellsFilled: "{count} Zelle ausgef\xFCllt | {count} Zellen ausgef\xFCllt",
109
+ cellsCleared: "{count} Zelle geleert | {count} Zellen geleert",
110
+ cellsUpdated: "{count} Zelle aktualisiert | {count} Zellen aktualisiert",
111
+ changesUndone: "{count} \xC4nderung r\xFCckg\xE4ngig gemacht | {count} \xC4nderungen r\xFCckg\xE4ngig gemacht",
112
+ changesRedone: "{count} \xC4nderung wiederhergestellt | {count} \xC4nderungen wiederhergestellt",
113
+ invalidValues: "{count} ung\xFCltiger Wert \xFCbersprungen | {count} ung\xFCltige Werte \xFCbersprungen",
114
+ cellsSelected: "{count} Zelle ausgew\xE4hlt | {count} Zellen ausgew\xE4hlt"
106
115
  },
107
116
  account: {
108
117
  label: "Konto"
@@ -102,7 +102,16 @@ export const en = {
102
102
  selectAllHint: "Press Space to select or deselect all rows",
103
103
  selectAllRows: "Select all rows",
104
104
  sortHint: "Press Enter to sort",
105
- tooltip: "Tooltip"
105
+ tooltip: "Tooltip",
106
+ cellsCopied: "{count} cell copied | {count} cells copied",
107
+ cellsPasted: "{count} cell pasted | {count} cells pasted",
108
+ cellsFilled: "{count} cell filled | {count} cells filled",
109
+ cellsCleared: "{count} cell cleared | {count} cells cleared",
110
+ cellsUpdated: "{count} cell updated | {count} cells updated",
111
+ changesUndone: "{count} change undone | {count} changes undone",
112
+ changesRedone: "{count} change redone | {count} changes redone",
113
+ invalidValues: "{count} invalid value skipped | {count} invalid values skipped",
114
+ cellsSelected: "{count} cell selected | {count} cells selected"
106
115
  },
107
116
  account: {
108
117
  label: "Account"
@@ -102,7 +102,16 @@ export const it = {
102
102
  selectAllHint: "Premi Spazio per selezionare o deselezionare tutte le righe",
103
103
  selectAllRows: "Seleziona tutte le righe",
104
104
  sortHint: "Premi Invio per ordinare",
105
- tooltip: "Suggerimento"
105
+ tooltip: "Suggerimento",
106
+ cellsCopied: "{count} cella copiata | {count} celle copiate",
107
+ cellsPasted: "{count} cella incollata | {count} celle incollate",
108
+ cellsFilled: "{count} cella riempita | {count} celle riempite",
109
+ cellsCleared: "{count} cella svuotata | {count} celle svuotate",
110
+ cellsUpdated: "{count} cella aggiornata | {count} celle aggiornate",
111
+ changesUndone: "{count} modifica annullata | {count} modifiche annullate",
112
+ changesRedone: "{count} modifica ripristinata | {count} modifiche ripristinate",
113
+ invalidValues: "{count} valore non valido ignorato | {count} valori non validi ignorati",
114
+ cellsSelected: "{count} cella selezionata | {count} celle selezionate"
106
115
  },
107
116
  account: {
108
117
  label: "Account"
@@ -101,6 +101,15 @@ export interface KMessages {
101
101
  selectAllRows: string;
102
102
  sortHint: string;
103
103
  tooltip: string;
104
+ cellsCopied: string;
105
+ cellsPasted: string;
106
+ cellsFilled: string;
107
+ cellsCleared: string;
108
+ cellsUpdated: string;
109
+ changesUndone: string;
110
+ changesRedone: string;
111
+ invalidValues: string;
112
+ cellsSelected: string;
104
113
  };
105
114
  account: {
106
115
  label: string;
@@ -161,11 +161,6 @@
161
161
  min-width: 0;
162
162
  }
163
163
 
164
- .k-settings-modal-breadcrumbs {
165
- flex: none;
166
- padding: 0 1.5rem 0.75rem;
167
- }
168
-
169
164
  .k-settings-modal-title {
170
165
  font-size: 0.9375rem;
171
166
  font-weight: var(--k-font-weight-strong, 600);
@@ -174,6 +169,44 @@
174
169
  color: var(--k-text);
175
170
  }
176
171
 
172
+ .k-settings-modal-title:has(> .k-settings-modal-crumb) {
173
+ display: flex;
174
+ flex-wrap: wrap;
175
+ align-items: center;
176
+ gap: 0.25rem;
177
+ }
178
+
179
+ .k-settings-modal-crumb {
180
+ padding: 0;
181
+ font: inherit;
182
+ letter-spacing: inherit;
183
+ color: var(--k-text-muted);
184
+ background: none;
185
+ border: 0;
186
+ border-radius: var(--k-radius-xs);
187
+ cursor: pointer;
188
+ transition: color var(--k-duration) var(--k-ease);
189
+ }
190
+
191
+ .k-settings-modal-crumb:hover {
192
+ color: var(--k-text);
193
+ }
194
+
195
+ .k-settings-modal-crumb:focus-visible {
196
+ outline: 2px solid var(--k-ring);
197
+ outline-offset: 2px;
198
+ }
199
+
200
+ .k-settings-modal-crumb.is-current {
201
+ color: var(--k-text);
202
+ cursor: default;
203
+ }
204
+
205
+ .k-settings-modal-crumb-separator {
206
+ --k-icon-size: 0.875rem;
207
+ color: var(--k-text-dimmed);
208
+ }
209
+
177
210
  .k-settings-modal-description {
178
211
  font-size: 0.8125rem;
179
212
  line-height: 1.4;
@@ -478,10 +511,6 @@
478
511
  padding: 1rem 1rem 0.75rem;
479
512
  }
480
513
 
481
- .k-settings-modal-breadcrumbs {
482
- padding-inline: 1rem;
483
- }
484
-
485
514
  .k-settings-modal-body {
486
515
  padding: 1rem;
487
516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xleddyl/443-components-vue",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Compact, scoped dashboard components for Vue and Nuxt",
5
5
  "license": "MIT",
6
6
  "author": "Edoardo Alberti (https://github.com/xleddyl)",
@@ -47,7 +47,8 @@
47
47
  "access": "public"
48
48
  },
49
49
  "files": [
50
- "dist"
50
+ "dist",
51
+ "CATALOG.md"
51
52
  ],
52
53
  "peerDependencies": {
53
54
  "@fontsource-variable/funnel-display": "^5.0.0",