@tekkare/romulus 0.1.182 → 0.1.184

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/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.16.0"
6
6
  },
7
- "version": "0.1.181",
7
+ "version": "0.1.183",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
@@ -15,6 +15,12 @@
15
15
  * composant recursif : la recherche et le pliage se calculent sur une seule
16
16
  * liste, et une taxonomie de plusieurs milliers de codes ne monte pas autant
17
17
  * d'instances de composant qu'elle a de noeuds.
18
+ *
19
+ * Trois gestes sur une ligne, et un seul coche : le caret ouvre, le LIBELLE
20
+ * ouvre aussi quand le noeud a des enfants (il coche quand c'est une feuille),
21
+ * la CASE coche. Lire une branche et la retenir sont deux intentions
22
+ * differentes : les confondre faisait partir des milliers de codes dans
23
+ * l'analyse au premier clic sur un nom.
18
24
  */
19
25
  import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
20
26
  import { PhCaretDown, PhCaretRight, PhCheck, PhMagnifyingGlass, PhMinus } from '@phosphor-icons/vue'
@@ -183,9 +189,21 @@ watch(selected, resetDraft, { immediate: true, deep: true })
183
189
  * parent coche pouvait survivre au decochage d'un de ses enfants et la
184
190
  * selection affirmait couvrir une branche entiere qu'elle ne couvrait plus.
185
191
  */
192
+ /**
193
+ * Les noeuds a enfants, du plus profond au moins profond.
194
+ *
195
+ * Calcule une fois par arbre : `settle` repartait sinon d'un tri de tout
196
+ * l'index a CHAQUE clic, soit seize mille entrees triees pour cocher une case
197
+ * sur les nomenclatures de la LPP ou de la CIM.
198
+ */
199
+ const settleOrder = computed(() =>
200
+ [...index.value.values()]
201
+ .filter(entry => entry.node.children?.length)
202
+ .sort((a, b) => b.depth - a.depth),
203
+ )
204
+
186
205
  function settle() {
187
- const entries = [...index.value.values()].sort((a, b) => b.depth - a.depth)
188
- entries.forEach(({ node }) => {
206
+ settleOrder.value.forEach(({ node }) => {
189
207
  if (!node.children?.length) return
190
208
  const all = node.children.every(child => draft.value.has(child.value))
191
209
  if (all) draft.value.add(node.value)
@@ -445,7 +463,17 @@ function onClickOutside(event: Event) {
445
463
  </button>
446
464
  <span v-else class="rm-ftree-caret rm-ftree-caret--none" />
447
465
 
448
- <button type="button" class="rm-ftree-label" @click="toggle(row.node.value)">
466
+ <!-- La case coche, et elle seule. Elle est sortie du libelle : cocher
467
+ une categorie emporte toute sa branche, et ce geste ne peut pas
468
+ etre celui qu'on fait pour lire ce qu'elle contient. -->
469
+ <button
470
+ type="button"
471
+ class="rm-ftree-check"
472
+ role="checkbox"
473
+ :aria-checked="row.state === 'on' ? 'true' : row.state === 'partial' ? 'mixed' : 'false'"
474
+ :aria-label="row.node.label"
475
+ @click.stop="toggle(row.node.value)"
476
+ >
449
477
  <span
450
478
  class="rm-ftree-box"
451
479
  :class="{
@@ -456,6 +484,19 @@ function onClickOutside(event: Event) {
456
484
  <PhCheck v-if="row.state === 'on'" :size="10" weight="bold" />
457
485
  <PhMinus v-else-if="row.state === 'partial'" :size="10" weight="bold" />
458
486
  </span>
487
+ </button>
488
+
489
+ <!-- Le libelle d'un noeud a enfants ouvre sa branche, comme le
490
+ caret : c'est le geste qu'on fait pour descendre dans une
491
+ taxonomie, et il selectionnait jusqu'ici des milliers de codes
492
+ au passage. Sur une feuille, il n'y a rien a ouvrir : il coche,
493
+ comme le libelle d'une case a cocher. -->
494
+ <button
495
+ type="button"
496
+ class="rm-ftree-label"
497
+ :aria-expanded="row.leaf ? undefined : row.open"
498
+ @click="row.leaf ? toggle(row.node.value) : toggleExpand(row.node.value)"
499
+ >
459
500
  <span v-if="row.node.code" class="rm-ftree-code">{{ row.node.code }}</span>
460
501
  <span class="rm-ftree-text">{{ row.node.label }}</span>
461
502
  <span v-if="row.node.count !== undefined" class="rm-ftree-count">{{ row.node.count }}</span>
@@ -478,5 +519,5 @@ function onClickOutside(event: Event) {
478
519
  </template>
479
520
 
480
521
  <style scoped>
481
- .rm-ftree-wrap{position:relative}.rm-ftree-wrap--inline{display:flex;flex-direction:column;height:100%;min-height:0}.rm-ftree-pill{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:6px;color:var(--text-secondary);cursor:pointer;display:inline-flex;font-family:var(--font-sans);font-size:var(--font-14);font-weight:var(--weight-medium);gap:var(--space-8);height:32px;max-width:320px;padding:0 var(--space-8);transition:border-color var(--duration-fast) var(--ease-in-out);white-space:nowrap}.rm-ftree-pill--active{border-color:var(--color-primary);box-shadow:0 0 8px 0 rgba(var(--brand-rgb),.1)}.rm-ftree-pill__icon{color:var(--color-secondary);flex-shrink:0}.rm-ftree-pill__label{overflow:hidden;text-overflow:ellipsis}.rm-ftree-pill__label b{color:var(--text-primary);font-weight:var(--weight-semibold)}.rm-ftree-pill__more{align-items:center;background:var(--bg-surface-2);border-radius:100px;color:var(--text-secondary);display:inline-flex;flex-shrink:0;font-size:var(--font-11);font-weight:var(--weight-semibold);height:18px;padding:0 6px}.rm-ftree-pill__caret{color:var(--text-muted);flex-shrink:0;transition:transform var(--duration-fast) var(--ease-in-out)}.rm-ftree-pill__caret--open{transform:rotate(180deg)}.rm-ftree-panel{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:8px;display:flex;flex-direction:column;min-height:0}.rm-ftree-wrap:not(.rm-ftree-wrap--inline) .rm-ftree-panel{box-shadow:0 4px 12px rgba(var(--shadow-rgb),.08),0 2px 4px rgba(var(--shadow-rgb),.04);left:0;max-width:460px;min-width:380px;position:absolute;top:calc(100% + 4px);z-index:50}.rm-ftree-wrap--inline .rm-ftree-panel{flex:1}.rm-ftree-search{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:6px;color:var(--text-muted);display:flex;flex-shrink:0;gap:var(--space-6);margin:var(--space-8);padding:var(--space-8)}.rm-ftree-search input{background:none;border:none;color:var(--text-primary);flex:1;font-family:var(--font-sans);font-size:var(--font-14);min-width:0;outline:none}.rm-ftree-list{flex:1;max-height:340px;min-height:0;overflow-y:auto;padding:0 var(--space-4) var(--space-4)}.rm-ftree-wrap--inline .rm-ftree-list{max-height:none}.rm-ftree-empty{color:var(--text-muted);font-family:var(--font-sans);font-size:var(--font-14);margin:0;padding:var(--space-10) var(--space-8)}.rm-ftree-row{align-items:center;border-radius:4px;display:flex}.rm-ftree-row--on{background:rgba(var(--brand-rgb),.06)}.rm-ftree-caret{align-items:center;background:none;border:none;color:var(--text-muted);cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;width:22px}.rm-ftree-caret:hover{color:var(--text-primary)}.rm-ftree-caret--none{cursor:default}.rm-ftree-label{align-items:center;background:none;border:none;border-radius:4px;color:var(--text-secondary);cursor:pointer;display:flex;flex:1;font-family:var(--font-sans);font-size:var(--font-14);gap:var(--space-8);min-width:0;padding:var(--space-6) var(--space-8);text-align:left}.rm-ftree-label:hover{background:var(--bg-surface-2)}.rm-ftree-box{align-items:center;border:1.5px solid var(--border-default);border-radius:3px;display:flex;flex-shrink:0;height:16px;justify-content:center;transition:all var(--duration-fast) var(--ease-in-out);width:16px}.rm-ftree-box--on,.rm-ftree-box--partial{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-text-inverse)}.rm-ftree-box--partial{background:var(--bg-surface);color:var(--color-primary)}.rm-ftree-code{color:var(--color-secondary);flex-shrink:0;font-family:var(--font-mono);font-size:var(--font-12);font-weight:var(--weight-semibold)}.rm-ftree-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-ftree-count{color:var(--text-muted);flex-shrink:0;font-size:var(--font-12);font-variant-numeric:tabular-nums}.rm-ftree-foot{align-items:center;border-top:1px solid var(--border-soft);display:flex;flex-shrink:0;gap:var(--space-8);justify-content:space-between;padding:var(--space-8) var(--space-12)}.rm-ftree-clear{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-13);padding:0;text-decoration:underline}.rm-ftree-clear:hover{color:var(--text-primary)}.rm-ftree-apply{background:var(--color-primary);border:none;border-radius:6px;color:var(--color-text-inverse);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-13);font-weight:var(--weight-semibold);height:30px;padding:0 var(--space-16)}.rm-ftree-apply:hover{filter:brightness(1.05)}
522
+ .rm-ftree-wrap{position:relative}.rm-ftree-wrap--inline{display:flex;flex-direction:column;height:100%;min-height:0}.rm-ftree-pill{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:6px;color:var(--text-secondary);cursor:pointer;display:inline-flex;font-family:var(--font-sans);font-size:var(--font-14);font-weight:var(--weight-medium);gap:var(--space-8);height:32px;max-width:320px;padding:0 var(--space-8);transition:border-color var(--duration-fast) var(--ease-in-out);white-space:nowrap}.rm-ftree-pill--active{border-color:var(--color-primary);box-shadow:0 0 8px 0 rgba(var(--brand-rgb),.1)}.rm-ftree-pill__icon{color:var(--color-secondary);flex-shrink:0}.rm-ftree-pill__label{overflow:hidden;text-overflow:ellipsis}.rm-ftree-pill__label b{color:var(--text-primary);font-weight:var(--weight-semibold)}.rm-ftree-pill__more{align-items:center;background:var(--bg-surface-2);border-radius:100px;color:var(--text-secondary);display:inline-flex;flex-shrink:0;font-size:var(--font-11);font-weight:var(--weight-semibold);height:18px;padding:0 6px}.rm-ftree-pill__caret{color:var(--text-muted);flex-shrink:0;transition:transform var(--duration-fast) var(--ease-in-out)}.rm-ftree-pill__caret--open{transform:rotate(180deg)}.rm-ftree-panel{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:8px;display:flex;flex-direction:column;min-height:0}.rm-ftree-wrap:not(.rm-ftree-wrap--inline) .rm-ftree-panel{box-shadow:0 4px 12px rgba(var(--shadow-rgb),.08),0 2px 4px rgba(var(--shadow-rgb),.04);left:0;max-width:460px;min-width:380px;position:absolute;top:calc(100% + 4px);z-index:50}.rm-ftree-wrap--inline .rm-ftree-panel{flex:1}.rm-ftree-search{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:6px;color:var(--text-muted);display:flex;flex-shrink:0;gap:var(--space-6);margin:var(--space-8);padding:var(--space-8)}.rm-ftree-search input{background:none;border:none;color:var(--text-primary);flex:1;font-family:var(--font-sans);font-size:var(--font-14);min-width:0;outline:none}.rm-ftree-list{flex:1;max-height:340px;min-height:0;overflow-y:auto;padding:0 var(--space-4) var(--space-4)}.rm-ftree-wrap--inline .rm-ftree-list{max-height:none}.rm-ftree-empty{color:var(--text-muted);font-family:var(--font-sans);font-size:var(--font-14);margin:0;padding:var(--space-10) var(--space-8)}.rm-ftree-row{align-items:center;border-radius:4px;display:flex}.rm-ftree-row--on{background:rgba(var(--brand-rgb),.06)}.rm-ftree-caret{align-items:center;background:none;border:none;color:var(--text-muted);cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;width:22px}.rm-ftree-caret:hover{color:var(--text-primary)}.rm-ftree-caret--none{cursor:default}.rm-ftree-check{align-items:center;background:none;border:none;border-radius:4px;cursor:pointer;display:flex;flex-shrink:0;height:28px;justify-content:center;width:28px}.rm-ftree-check:hover .rm-ftree-box{border-color:var(--color-primary)}.rm-ftree-label{align-items:center;background:none;border:none;border-radius:4px;color:var(--text-secondary);cursor:pointer;display:flex;flex:1;font-family:var(--font-sans);font-size:var(--font-14);gap:var(--space-8);min-width:0;padding:var(--space-6) var(--space-8);text-align:left}.rm-ftree-label:hover{background:var(--bg-surface-2)}.rm-ftree-box{align-items:center;border:1.5px solid var(--border-default);border-radius:3px;display:flex;flex-shrink:0;height:16px;justify-content:center;transition:all var(--duration-fast) var(--ease-in-out);width:16px}.rm-ftree-box--on,.rm-ftree-box--partial{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-text-inverse)}.rm-ftree-box--partial{background:var(--bg-surface);color:var(--color-primary)}.rm-ftree-code{color:var(--color-secondary);flex-shrink:0;font-family:var(--font-mono);font-size:var(--font-12);font-weight:var(--weight-semibold)}.rm-ftree-text{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-ftree-count{color:var(--text-muted);flex-shrink:0;font-size:var(--font-12);font-variant-numeric:tabular-nums}.rm-ftree-foot{align-items:center;border-top:1px solid var(--border-soft);display:flex;flex-shrink:0;gap:var(--space-8);justify-content:space-between;padding:var(--space-8) var(--space-12)}.rm-ftree-clear{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-13);padding:0;text-decoration:underline}.rm-ftree-clear:hover{color:var(--text-primary)}.rm-ftree-apply{background:var(--color-primary);border:none;border-radius:6px;color:var(--color-text-inverse);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-13);font-weight:var(--weight-semibold);height:30px;padding:0 var(--space-16)}.rm-ftree-apply:hover{filter:brightness(1.05)}
482
523
  </style>
@@ -163,9 +163,9 @@ export declare function rmLegend(theme: RmChartTheme, count: number, position?:
163
163
  * echelle de comparaison entre deux courbes.
164
164
  */
165
165
  /**
166
- * `formatter` s'applique AUSSI a la graduation, pas seulement a l'infobulle :
167
- * un axe qui affiche 400 000 000 la ou l'infobulle dit 400 M donne deux
168
- * lectures du meme nombre sur le meme graphe.
166
+ * `formatter` s'applique a la graduation. L'infobulle, elle, garde toujours
167
+ * le nombre entier (`rmNumber`) meme quand l'axe est abrege : au survol, le
168
+ * lecteur veut la valeur exacte, la ou l'axe n'a que la place pour "18,8 M".
169
169
  */
170
170
  /**
171
171
  * Couleur d'une serie a l'indice `index`.
@@ -1,3 +1,4 @@
1
+ import { rmNumber } from "./format.js";
1
2
  export const RM_PALETTES = {
2
3
  default: {
3
4
  cat: ["#2100AD", "#00D4A8", "#F59E0B", "#4164EE", "#EC4899", "#6B3FFF"],
@@ -227,6 +228,7 @@ export function rmLineOption(categories, series, theme, palette, options = {}) {
227
228
  const dual = series.some((s) => s.axis === 1);
228
229
  const bottomLegend = legendPosition === "bottom";
229
230
  const format = (value) => valueFormatter ? valueFormatter(value) : String(value);
231
+ const tooltipFormat = (value) => valueFormatter ? rmNumber(value) : String(value);
230
232
  const values = series.flatMap((s) => s.data).filter((v) => typeof v === "number");
231
233
  const floorAtZero = startAtZero && values.length > 0 && Math.min(...values) >= 0;
232
234
  const base = rmBaseOption(theme, decal);
@@ -239,7 +241,7 @@ export function rmLineOption(categories, series, theme, palette, options = {}) {
239
241
  tooltip: {
240
242
  ...base.tooltip,
241
243
  trigger: rmTooltipTrigger(series.length),
242
- ...valueFormatter ? { valueFormatter: (value) => typeof value === "number" ? format(value) : "" } : {}
244
+ ...valueFormatter ? { valueFormatter: (value) => typeof value === "number" ? tooltipFormat(value) : "" } : {}
243
245
  },
244
246
  // Legende obligatoire en double axe : sans elle, rien ne dit quelle courbe
245
247
  // se lit sur quel axe.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekkare/romulus",
3
- "version": "0.1.182",
3
+ "version": "0.1.184",
4
4
  "description": "Romulus Design System - Nuxt module by Tekkare",
5
5
  "license": "MIT",
6
6
  "type": "module",