@dnax/ui 0.0.75 → 0.0.77
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/components/QFilePicker.vue +22 -65
- package/components/QSpreadsheet.vue +624 -73
- package/index.ts +14 -0
- package/lib/cellSize.test.ts +90 -0
- package/lib/cellSize.ts +79 -0
- package/lib/fileList.test.ts +119 -0
- package/lib/fileList.ts +159 -0
- package/lib/pagination.test.ts +77 -0
- package/lib/pagination.ts +50 -0
- package/lib/spreadsheetDisplay.test.ts +49 -0
- package/lib/spreadsheetDisplay.ts +42 -0
- package/package.json +1 -1
- package/styles/main.css +188 -10
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Texte d'une valeur de cellule pour les surfaces **textuelles** du tableur :
|
|
2
|
+
// barre de formule (`fx`) et moteur de recherche (Find).
|
|
3
|
+
//
|
|
4
|
+
// Piège visé : `String(valeur)` sur un objet/tableau produit « [object Object] ». Les types
|
|
5
|
+
// à valeur structurée (`attachment`, et tout futur type objet) doivent donc passer par ici
|
|
6
|
+
// au lieu d'un `String()` sauvage.
|
|
7
|
+
import { attachmentsOf } from "./fileList"
|
|
8
|
+
|
|
9
|
+
/** Valeur affichable en texte : `null`/objet → `""`, tableau → éléments joints. */
|
|
10
|
+
const plain = (value: unknown): string => {
|
|
11
|
+
if (value === null || value === undefined) return ""
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
return value
|
|
14
|
+
.map((entry) => (entry === null || entry === undefined || typeof entry === "object" ? "" : String(entry)))
|
|
15
|
+
.filter((text) => text !== "")
|
|
16
|
+
.join(", ")
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === "object") return ""
|
|
19
|
+
return String(value)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Contenu de la **barre de formule** pour une cellule.
|
|
24
|
+
* `attachment` → `""` (la valeur est un tableau d'objets : rien de pertinent à éditer).
|
|
25
|
+
*/
|
|
26
|
+
export const fxTextFor = (value: unknown, type?: string): string => {
|
|
27
|
+
if (type === "attachment") return ""
|
|
28
|
+
return plain(value)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Texte indexé par la **recherche** (Find & Replace).
|
|
33
|
+
* `attachment` → les **noms de fichiers**, pour pouvoir chercher par nom.
|
|
34
|
+
*/
|
|
35
|
+
export const searchTextFor = (value: unknown, type?: string): string => {
|
|
36
|
+
if (type === "attachment") {
|
|
37
|
+
return attachmentsOf(value)
|
|
38
|
+
.map((att) => att.name)
|
|
39
|
+
.join(", ")
|
|
40
|
+
}
|
|
41
|
+
return plain(value)
|
|
42
|
+
}
|
package/package.json
CHANGED
package/styles/main.css
CHANGED
|
@@ -6882,6 +6882,11 @@ a.q-breadcrumbs__el:hover {
|
|
|
6882
6882
|
background-color: rgb(0 0 0 / 0.6);
|
|
6883
6883
|
color: #fff;
|
|
6884
6884
|
}
|
|
6885
|
+
/* Thème sombre : le voile blanc codé en dur éblouit (même convention que les champs) */
|
|
6886
|
+
.dark .q-inner-loading {
|
|
6887
|
+
background-color: rgb(0 0 0 / 0.55);
|
|
6888
|
+
color: var(--foreground);
|
|
6889
|
+
}
|
|
6885
6890
|
|
|
6886
6891
|
.q-inner-loading__icon {
|
|
6887
6892
|
animation: q-btn-spin 0.7s linear infinite;
|
|
@@ -9637,6 +9642,20 @@ a.q-breadcrumbs__el:hover {
|
|
|
9637
9642
|
overflow: auto;
|
|
9638
9643
|
outline: none;
|
|
9639
9644
|
}
|
|
9645
|
+
|
|
9646
|
+
/* Chargement distant : spinner du design system, teinté par le thème */
|
|
9647
|
+
.q-spreadsheet__loader {
|
|
9648
|
+
width: 30px;
|
|
9649
|
+
height: 30px;
|
|
9650
|
+
border-width: 3px;
|
|
9651
|
+
color: var(--primary, #1976d2);
|
|
9652
|
+
}
|
|
9653
|
+
|
|
9654
|
+
/* Le voile passe au-dessus de l'éditeur (z-index 20) et de la poignée de remplissage :
|
|
9655
|
+
on ne doit pas éditer une page en cours de remplacement. */
|
|
9656
|
+
.q-spreadsheet > .q-inner-loading {
|
|
9657
|
+
z-index: 40;
|
|
9658
|
+
}
|
|
9640
9659
|
.q-spreadsheet__table {
|
|
9641
9660
|
/* PAS de `min-width: 100%` : avec `table-layout: fixed`, un tableau étiré au-delà
|
|
9642
9661
|
de la somme de ses colonnes RÉPARTIT l'espace libre sur toutes les colonnes
|
|
@@ -9648,7 +9667,8 @@ a.q-breadcrumbs__el:hover {
|
|
|
9648
9667
|
border-collapse: separate;
|
|
9649
9668
|
border-spacing: 0;
|
|
9650
9669
|
table-layout: fixed;
|
|
9651
|
-
|
|
9670
|
+
/* Suit `sizeCell` (la police grandit avec la cellule) ; 13px = taille historique */
|
|
9671
|
+
font-size: var(--q-spreadsheet-font, 13px);
|
|
9652
9672
|
}
|
|
9653
9673
|
|
|
9654
9674
|
/* Grille sans aucune colonne : un seul message → il doit occuper toute la largeur */
|
|
@@ -9670,9 +9690,9 @@ a.q-breadcrumbs__el:hover {
|
|
|
9670
9690
|
top: 0;
|
|
9671
9691
|
left: 0;
|
|
9672
9692
|
z-index: 6;
|
|
9673
|
-
width: 34px;
|
|
9674
|
-
min-width: 34px;
|
|
9675
|
-
height: 28px;
|
|
9693
|
+
width: var(--q-spreadsheet-gutter-width, 34px);
|
|
9694
|
+
min-width: var(--q-spreadsheet-gutter-width, 34px);
|
|
9695
|
+
height: var(--q-spreadsheet-head-height, 28px);
|
|
9676
9696
|
border-right: 1px solid var(--q-spreadsheet-border);
|
|
9677
9697
|
border-bottom: 1px solid var(--q-spreadsheet-border);
|
|
9678
9698
|
text-align: center;
|
|
@@ -9682,7 +9702,7 @@ a.q-breadcrumbs__el:hover {
|
|
|
9682
9702
|
.q-spreadsheet__colhead {
|
|
9683
9703
|
top: 0;
|
|
9684
9704
|
z-index: 4;
|
|
9685
|
-
height: 28px;
|
|
9705
|
+
height: var(--q-spreadsheet-head-height, 28px);
|
|
9686
9706
|
padding: 0 10px 0 6px;
|
|
9687
9707
|
border-right: 1px solid var(--q-spreadsheet-border);
|
|
9688
9708
|
border-bottom: 1px solid var(--q-spreadsheet-border);
|
|
@@ -9703,7 +9723,7 @@ a.q-breadcrumbs__el:hover {
|
|
|
9703
9723
|
padding-right: 6px;
|
|
9704
9724
|
}
|
|
9705
9725
|
.q-spreadsheet__colhead-letter {
|
|
9706
|
-
font-size: 9.5px;
|
|
9726
|
+
font-size: var(--q-spreadsheet-head-letter-font, 9.5px);
|
|
9707
9727
|
font-weight: 700;
|
|
9708
9728
|
line-height: 1.1;
|
|
9709
9729
|
letter-spacing: 0.04em;
|
|
@@ -9711,7 +9731,7 @@ a.q-breadcrumbs__el:hover {
|
|
|
9711
9731
|
color: var(--primary, #1976d2);
|
|
9712
9732
|
}
|
|
9713
9733
|
.q-spreadsheet__colhead-label {
|
|
9714
|
-
font-size: 11.5px;
|
|
9734
|
+
font-size: var(--q-spreadsheet-head-font, 11.5px);
|
|
9715
9735
|
line-height: 1.25;
|
|
9716
9736
|
overflow: hidden;
|
|
9717
9737
|
text-overflow: ellipsis;
|
|
@@ -9719,11 +9739,11 @@ a.q-breadcrumbs__el:hover {
|
|
|
9719
9739
|
.q-spreadsheet__rownum {
|
|
9720
9740
|
left: 0;
|
|
9721
9741
|
z-index: 3;
|
|
9722
|
-
width: 34px;
|
|
9723
|
-
min-width: 34px;
|
|
9742
|
+
width: var(--q-spreadsheet-gutter-width, 34px);
|
|
9743
|
+
min-width: var(--q-spreadsheet-gutter-width, 34px);
|
|
9724
9744
|
border-right: 1px solid var(--q-spreadsheet-border);
|
|
9725
9745
|
border-bottom: 1px solid var(--q-spreadsheet-border);
|
|
9726
|
-
font-size: 11px;
|
|
9746
|
+
font-size: var(--q-spreadsheet-row-font, 11px);
|
|
9727
9747
|
font-weight: 500;
|
|
9728
9748
|
text-align: center;
|
|
9729
9749
|
vertical-align: middle;
|
|
@@ -9868,6 +9888,132 @@ a.q-breadcrumbs__el:hover {
|
|
|
9868
9888
|
vertical-align: middle;
|
|
9869
9889
|
}
|
|
9870
9890
|
|
|
9891
|
+
/* ─── Fichiers joints (type `attachment`) ─── */
|
|
9892
|
+
/* Une « puce » par fichier : vignette (image) ou icône typée, nom tronqué, bouton de retrait.
|
|
9893
|
+
Les puces passent à la ligne dans une cellule étroite, comme les badges. */
|
|
9894
|
+
.q-spreadsheet__attachments {
|
|
9895
|
+
display: inline-flex;
|
|
9896
|
+
flex-wrap: wrap;
|
|
9897
|
+
align-items: center;
|
|
9898
|
+
gap: 4px;
|
|
9899
|
+
max-width: 100%;
|
|
9900
|
+
vertical-align: middle;
|
|
9901
|
+
}
|
|
9902
|
+
|
|
9903
|
+
.q-spreadsheet__attachment {
|
|
9904
|
+
display: inline-flex;
|
|
9905
|
+
align-items: center;
|
|
9906
|
+
gap: 4px;
|
|
9907
|
+
max-width: 100%;
|
|
9908
|
+
padding: 1px 4px 1px 2px;
|
|
9909
|
+
border: 1px solid rgb(0 0 0 / 0.12);
|
|
9910
|
+
border-radius: 999px;
|
|
9911
|
+
background: rgb(0 0 0 / 0.04);
|
|
9912
|
+
font-size: 11.5px;
|
|
9913
|
+
line-height: 1.6;
|
|
9914
|
+
white-space: nowrap;
|
|
9915
|
+
/* La puce est cliquable : elle émet `attachment-click` (aperçu côté app) */
|
|
9916
|
+
cursor: pointer;
|
|
9917
|
+
}
|
|
9918
|
+
.q-spreadsheet__attachment:hover {
|
|
9919
|
+
border-color: rgb(0 0 0 / 0.24);
|
|
9920
|
+
background: rgb(0 0 0 / 0.08);
|
|
9921
|
+
}
|
|
9922
|
+
|
|
9923
|
+
.q-spreadsheet__attachment-thumb {
|
|
9924
|
+
width: 18px;
|
|
9925
|
+
height: 18px;
|
|
9926
|
+
flex: 0 0 auto;
|
|
9927
|
+
border-radius: 4px;
|
|
9928
|
+
object-fit: cover;
|
|
9929
|
+
}
|
|
9930
|
+
|
|
9931
|
+
.q-spreadsheet__attachment-icon {
|
|
9932
|
+
width: 14px;
|
|
9933
|
+
height: 14px;
|
|
9934
|
+
flex: 0 0 auto;
|
|
9935
|
+
color: rgb(0 0 0 / 0.55);
|
|
9936
|
+
}
|
|
9937
|
+
|
|
9938
|
+
.q-spreadsheet__attachment-name {
|
|
9939
|
+
max-width: 140px;
|
|
9940
|
+
overflow: hidden;
|
|
9941
|
+
text-overflow: ellipsis;
|
|
9942
|
+
}
|
|
9943
|
+
|
|
9944
|
+
.q-spreadsheet__attachment-x {
|
|
9945
|
+
display: inline-flex;
|
|
9946
|
+
align-items: center;
|
|
9947
|
+
justify-content: center;
|
|
9948
|
+
width: 14px;
|
|
9949
|
+
height: 14px;
|
|
9950
|
+
padding: 0;
|
|
9951
|
+
border: none;
|
|
9952
|
+
border-radius: 50%;
|
|
9953
|
+
background: transparent;
|
|
9954
|
+
color: rgb(0 0 0 / 0.45);
|
|
9955
|
+
cursor: pointer;
|
|
9956
|
+
flex: 0 0 auto;
|
|
9957
|
+
}
|
|
9958
|
+
.q-spreadsheet__attachment-x:hover {
|
|
9959
|
+
background: rgb(0 0 0 / 0.12);
|
|
9960
|
+
color: var(--negative, #c10015);
|
|
9961
|
+
}
|
|
9962
|
+
.q-spreadsheet__attachment-x svg {
|
|
9963
|
+
width: 10px;
|
|
9964
|
+
height: 10px;
|
|
9965
|
+
}
|
|
9966
|
+
|
|
9967
|
+
/* Bouton d'ajout : discret, visible dès qu'on survole / sélectionne la cellule */
|
|
9968
|
+
.q-spreadsheet__attachment-add {
|
|
9969
|
+
display: inline-flex;
|
|
9970
|
+
align-items: center;
|
|
9971
|
+
justify-content: center;
|
|
9972
|
+
width: 18px;
|
|
9973
|
+
height: 18px;
|
|
9974
|
+
padding: 0;
|
|
9975
|
+
border: 1px dashed rgb(0 0 0 / 0.25);
|
|
9976
|
+
border-radius: 50%;
|
|
9977
|
+
background: transparent;
|
|
9978
|
+
color: rgb(0 0 0 / 0.45);
|
|
9979
|
+
cursor: pointer;
|
|
9980
|
+
flex: 0 0 auto;
|
|
9981
|
+
}
|
|
9982
|
+
.q-spreadsheet__attachment-add:hover {
|
|
9983
|
+
border-color: var(--primary, #1976d2);
|
|
9984
|
+
color: var(--primary, #1976d2);
|
|
9985
|
+
}
|
|
9986
|
+
.q-spreadsheet__attachment-add svg {
|
|
9987
|
+
width: 10px;
|
|
9988
|
+
height: 10px;
|
|
9989
|
+
}
|
|
9990
|
+
|
|
9991
|
+
/* Input `type=file` masqué (piloté par `openAttachments`) */
|
|
9992
|
+
.q-spreadsheet__attach-input {
|
|
9993
|
+
position: absolute;
|
|
9994
|
+
width: 0;
|
|
9995
|
+
height: 0;
|
|
9996
|
+
opacity: 0;
|
|
9997
|
+
pointer-events: none;
|
|
9998
|
+
}
|
|
9999
|
+
|
|
10000
|
+
.dark .q-spreadsheet__attachment {
|
|
10001
|
+
border-color: rgb(255 255 255 / 0.16);
|
|
10002
|
+
background: rgb(255 255 255 / 0.06);
|
|
10003
|
+
}
|
|
10004
|
+
.dark .q-spreadsheet__attachment:hover {
|
|
10005
|
+
border-color: rgb(255 255 255 / 0.3);
|
|
10006
|
+
background: rgb(255 255 255 / 0.11);
|
|
10007
|
+
}
|
|
10008
|
+
.dark .q-spreadsheet__attachment-icon,
|
|
10009
|
+
.dark .q-spreadsheet__attachment-x,
|
|
10010
|
+
.dark .q-spreadsheet__attachment-add {
|
|
10011
|
+
color: rgb(255 255 255 / 0.6);
|
|
10012
|
+
}
|
|
10013
|
+
.dark .q-spreadsheet__attachment-add {
|
|
10014
|
+
border-color: rgb(255 255 255 / 0.24);
|
|
10015
|
+
}
|
|
10016
|
+
|
|
9871
10017
|
/* ─── Éditeur overlay ─── */
|
|
9872
10018
|
.q-spreadsheet__editor {
|
|
9873
10019
|
position: absolute;
|
|
@@ -10758,6 +10904,38 @@ a.q-breadcrumbs__el:hover {
|
|
|
10758
10904
|
.q-spreadsheet__status-spacer {
|
|
10759
10905
|
flex: 1;
|
|
10760
10906
|
}
|
|
10907
|
+
|
|
10908
|
+
/* Pagination distante : ‹ lignes 401–800 sur 12 000 · 2 / 30 › */
|
|
10909
|
+
.q-spreadsheet__pager {
|
|
10910
|
+
display: inline-flex;
|
|
10911
|
+
align-items: center;
|
|
10912
|
+
gap: 4px;
|
|
10913
|
+
padding-right: 8px;
|
|
10914
|
+
border-right: 1px solid rgb(0 0 0 / 0.1);
|
|
10915
|
+
margin-right: 2px;
|
|
10916
|
+
}
|
|
10917
|
+
.q-spreadsheet__pager .q-spreadsheet__tool {
|
|
10918
|
+
width: 22px;
|
|
10919
|
+
height: 20px;
|
|
10920
|
+
}
|
|
10921
|
+
.q-spreadsheet__pager-range {
|
|
10922
|
+
font-variant-numeric: tabular-nums;
|
|
10923
|
+
white-space: nowrap;
|
|
10924
|
+
}
|
|
10925
|
+
.q-spreadsheet__pager-page {
|
|
10926
|
+
padding: 0 6px;
|
|
10927
|
+
border-radius: 999px;
|
|
10928
|
+
background: rgb(0 0 0 / 0.06);
|
|
10929
|
+
font-weight: 600;
|
|
10930
|
+
font-variant-numeric: tabular-nums;
|
|
10931
|
+
white-space: nowrap;
|
|
10932
|
+
}
|
|
10933
|
+
.dark .q-spreadsheet__pager {
|
|
10934
|
+
border-right-color: rgb(255 255 255 / 0.14);
|
|
10935
|
+
}
|
|
10936
|
+
.dark .q-spreadsheet__pager-page {
|
|
10937
|
+
background: rgb(255 255 255 / 0.12);
|
|
10938
|
+
}
|
|
10761
10939
|
.q-spreadsheet__status-zoom {
|
|
10762
10940
|
display: inline-flex;
|
|
10763
10941
|
align-items: center;
|