@tekkare/romulus 0.1.73 → 0.1.75

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.72",
7
+ "version": "0.1.74",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
@@ -1 +1 @@
1
- :root{--rm-shell-bg:#f9f9fa;--rm-shell-surface:#fff;--rm-shell-border:#dbdef0;--rm-shell-subtle:#f5f5f9;--rm-shell-text:#1e293b;--rm-shell-text-dark:#475569;--rm-shell-text-muted:#878ca6;--rm-shell-accent:#2017ad;--rm-shell-inset:8px;--rm-shell-radius:12px;--rm-bar-h:56px;--rm-nav-w:240px;--rm-nav-collapsed-w:64px;--rm-rail-w:56px;--rm-dots-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAcUlEQVR42u3TwQmAMAxAUdfQfUoSZ3OBTNMFHEqLVBEtCB6M8B8EevwktOsAAACAl0SkNzNXtaw6zut7SikNYeJq2Hksh4gs27rG7ZH+eWA7bttigMC78x4TIdBbceX8fJKnkSL1s5RY8zBxAAAA+LUF0ula10BxVDoAAAAASUVORK5CYII=");--rm-dots-size:12px;--rm-dots-opacity:0.1}body.night{--rm-shell-bg:var(--bg-app);--rm-shell-surface:var(--bg-surface,#1a1a24);--rm-shell-border:var(--border-default);--rm-shell-subtle:var(--bg-subtle,#22222e);--rm-shell-text:var(--text-primary);--rm-shell-text-dark:var(--text-secondary);--rm-shell-text-muted:var(--text-muted);--rm-shell-accent:var(--color-primary);--rm-dots-opacity:0.06}.rm-shell{background:var(--rm-shell-bg);color:var(--rm-shell-text);font-family:var(--font-sans,"Figtree",sans-serif);inset:0;overflow:hidden;position:fixed}.rm-shell__dots{background-image:var(--rm-dots-image);background-repeat:repeat;background-size:var(--rm-dots-size) var(--rm-dots-size);inset:0;opacity:var(--rm-dots-opacity);pointer-events:none;position:absolute}.rm-shell__frame{border:1px solid var(--rm-shell-border);border-radius:var(--rm-shell-radius);display:flex;inset:var(--rm-shell-inset);overflow:hidden;position:absolute}.rm-shell__body{display:flex;flex:1;flex-direction:column;min-width:0}.rm-shell__main{flex:1;min-width:0;overflow-y:auto}.rm-sb{background:var(--rm-shell-surface);display:flex;flex-direction:column;flex-shrink:0;height:100%}.rm-sb--left{border-right:1px solid var(--rm-shell-border);position:relative;transition:width .2s;width:var(--rm-nav-w);z-index:200}.rm-sb--left.rm-sb--collapsed{width:var(--rm-nav-collapsed-w)}.rm-sb--right{border-left:1px solid var(--rm-shell-border);width:var(--rm-rail-w)}.rm-sb__header{align-items:center;border-bottom:1px solid var(--rm-shell-border);display:flex;flex-shrink:0;gap:8px;height:var(--rm-bar-h);padding:0 16px}.rm-sb--collapsed .rm-sb__header{justify-content:center;padding:0}.rm-sb__logo{align-items:center;color:var(--rm-shell-text);display:flex;flex:1;font-size:20px;font-weight:700;gap:8px;line-height:1.4;min-width:0;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-sb__toggle{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);cursor:pointer;display:block;flex-shrink:0;height:20px;margin:0;padding:0;transition:color .15s;width:20px}.rm-sb__toggle:hover{color:var(--rm-shell-text)}.rm-sb__toggle svg{display:block;height:100%;width:100%}.rm-sb__nav{display:flex;flex:1;flex-direction:column;gap:16px;overflow-y:auto;padding:16px}.rm-sb--collapsed .rm-sb__nav{padding-left:8px;padding-right:8px}.rm-sb__group{display:flex;flex-direction:column;gap:4px}.rm-sb__label{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);display:flex;font-family:inherit;font-size:10px;font-weight:500;gap:4px;letter-spacing:.025em;line-height:1.6;margin:0;padding:0 2px;text-align:left;text-transform:uppercase;width:100%}button.rm-sb__label{cursor:pointer}button.rm-sb__label:hover{color:var(--rm-shell-text)}.rm-sb__label-text{flex:1;min-width:0}.rm-sb__chev{display:block;flex-shrink:0;height:12px;transition:transform .2s;width:12px}.rm-sb__label[aria-expanded=true] .rm-sb__chev{transform:rotate(90deg)}.rm-sb__rule{background:var(--rm-shell-border);height:1px;margin:4px}.rm-mi{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:4px;box-shadow:none;color:var(--rm-shell-text);cursor:pointer;display:flex;font-family:inherit;gap:8px;height:26px;margin:0;padding:2px;text-align:left;text-decoration:none;transition:background-color .15s;width:100%}.rm-mi:hover{background:color-mix(in srgb,var(--rm-shell-subtle) 50%,transparent)}.rm-mi.rm-mi--active{background:var(--rm-shell-subtle)}.rm-mi.rm-mi--current{background:color-mix(in srgb,var(--rm-shell-accent) 5%,transparent)}.rm-mi.rm-mi--current .rm-mi__icon{background:var(--rm-shell-accent);color:#fff}.rm-mi.rm-mi--current .rm-mi__icon svg{stroke:#fff}.rm-mi__icon{align-items:center;background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-dark);display:flex;flex-shrink:0;height:22px;justify-content:center;line-height:1;width:22px}.rm-mi__icon svg{display:block;height:14px;width:14px}.rm-mi__icon i{font-size:14px;line-height:1}.rm-mi__label{color:var(--rm-shell-text);flex:1;font-size:14px;line-height:1.625;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-mi__badge{background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-muted);flex-shrink:0;font-size:9px;font-weight:700;letter-spacing:.025em;padding:2px 4px;text-transform:uppercase}.rm-sb--collapsed .rm-mi{justify-content:center}.rm-sb--collapsed .rm-mi>:not(.rm-mi__icon),.rm-sb--collapsed .rm-sb__sub{display:none}.rm-sb__tip{background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:6px;box-shadow:0 4px 12px rgba(30,41,59,.1);color:var(--rm-shell-text);font-size:12px;line-height:1.3;padding:5px 9px;pointer-events:none;position:fixed;transform:translateY(-50%);white-space:nowrap;z-index:60}.rm-sb__sub{display:flex;flex-direction:column;gap:2px;padding:2px 0 2px 28px}.rm-sb__sub-item{border-radius:4px;color:var(--rm-shell-text);display:block;font-size:14px;line-height:1.625;overflow:hidden;padding:2px 4px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-sb__sub-item:hover{background:color-mix(in srgb,var(--rm-shell-subtle) 50%,transparent)}.rm-rail__item{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;cursor:pointer;display:flex;flex-direction:column;font-family:inherit;gap:4px;margin:0;padding:12px 0 8px;text-decoration:none;width:100%}.rm-rail__avatar{align-items:center;border:2px solid var(--rm-shell-surface);border-radius:9999px;color:#fff;display:flex;font-size:14px;height:32px;justify-content:center;transition:opacity .15s;width:32px}.rm-rail__item:hover .rm-rail__avatar{opacity:.8}.rm-rail__tile{align-items:center;background:var(--rm-shell-subtle);border-radius:8px;color:var(--rm-shell-text-dark);display:flex;font-size:16px;height:32px;justify-content:center;transition:background-color .15s,color .15s;width:32px}.rm-rail__item:hover .rm-rail__tile{background:var(--rm-shell-border)}.rm-rail__item.rm-rail__item--active .rm-rail__tile{background:var(--rm-shell-accent);color:#fff}.rm-rail__tile{position:relative}.rm-rail__badge{background:var(--rm-shell-accent);border-radius:9999px;color:#fff;font-size:10px;font-weight:700;height:16px;line-height:16px;min-width:16px;padding:0 4px;position:absolute;right:-4px;text-align:center;top:-4px}.rm-rail__item--active .rm-rail__badge{background:#fff;color:var(--rm-shell-accent)}.rm-rail__caption{color:var(--rm-shell-text-muted);font-size:10px;line-height:1;max-width:100%;overflow:hidden;padding:0 2px;text-overflow:ellipsis;transition:color .15s;white-space:nowrap}.rm-rail__item--active .rm-rail__caption,.rm-rail__item:hover .rm-rail__caption{color:var(--rm-shell-text)}.rm-rail__bottom{display:flex;justify-content:center;margin-top:auto;padding-bottom:16px}.rm-lang{background:var(--rm-shell-subtle);border:1px solid var(--rm-shell-accent);border-radius:9999px;display:grid;gap:2px;grid-template-rows:1fr 1fr;padding:3px;position:relative}.rm-lang__thumb{background:var(--rm-shell-surface);border-radius:9999px;box-shadow:0 1px 4px rgba(30,41,59,.16);height:32px;left:3px;position:absolute;top:3px;transition:transform .26s cubic-bezier(.34,1.56,.64,1);width:32px}.rm-lang--second .rm-lang__thumb{transform:translateY(34px)}.rm-lang__option{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:9999px;box-shadow:none;cursor:pointer;display:flex;filter:grayscale(1);font-size:17px;height:32px;justify-content:center;line-height:1;margin:0;opacity:.5;padding:0;position:relative;transition:filter .18s ease,opacity .18s ease,transform .18s ease;width:32px}.rm-lang__option:hover{filter:grayscale(0);opacity:.85}.rm-lang__option.rm-lang__option--active{filter:grayscale(0);opacity:1}.rm-lang__option:focus-visible{outline:2px solid var(--rm-shell-accent);outline-offset:2px}@media (prefers-reduced-motion:reduce){.rm-lang__option,.rm-lang__thumb{transition:none}}.rm-hd{background:var(--rm-shell-surface);border-bottom:1px solid var(--rm-shell-border);display:flex;flex-direction:column;flex-shrink:0}.rm-hd__row{gap:16px;height:var(--rm-bar-h);padding:0 16px}.rm-hd__crumbs,.rm-hd__row{align-items:center;display:flex}.rm-hd__crumbs{flex:1;font-size:14px;gap:4px;min-width:0}.rm-hd__crumb{align-items:center;color:var(--rm-shell-text-muted);display:inline-flex;gap:6px;text-decoration:none;transition:color .15s;white-space:nowrap}a.rm-hd__crumb:hover{color:var(--rm-shell-text)}.rm-hd__sep{color:var(--rm-shell-text-muted)}.rm-hd__picker{display:inline-flex;min-width:0;position:relative}.rm-hd__crumb--picker{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:4px;box-shadow:none;cursor:pointer;font:inherit;font-size:14px;margin:0;padding:2px 4px;transition:background-color .15s,color .15s}.rm-hd__crumb--picker:hover{background:var(--rm-shell-subtle)}.rm-hd__caret{display:block;flex-shrink:0;height:12px;opacity:.7;transition:transform .15s;width:12px}.rm-hd__caret--open{transform:rotate(180deg)}.rm-hd__menu{background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:8px;box-shadow:0 8px 24px rgba(30,41,59,.12);left:0;max-height:60vh;max-width:320px;min-width:200px;overflow-y:auto;padding:4px;position:absolute;top:calc(100% + 4px);z-index:300}.rm-hd__menu-item{align-items:center;border-radius:4px;color:var(--rm-shell-text);display:flex;font-size:14px;gap:8px;line-height:1.5;overflow:hidden;padding:4px 6px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-hd__menu-item:hover{background:var(--rm-shell-subtle)}.rm-hd__menu-group{color:var(--rm-shell-text-muted);display:block;font-size:10px;font-weight:500;letter-spacing:.025em;line-height:1.6;padding:8px 6px 2px;text-transform:uppercase}.rm-hd__menu-group:first-child{padding-top:2px}.rm-hd__menu-item--active{background:color-mix(in srgb,var(--rm-shell-accent) 5%,transparent);font-weight:600}.rm-hd__menu-icon{align-items:center;background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-dark);display:flex;flex-shrink:0;height:22px;justify-content:center;line-height:1;width:22px}.rm-hd__menu-icon i{font-size:14px;line-height:1}.rm-hd__menu-item--active .rm-hd__menu-icon{background:var(--rm-shell-accent);color:#fff}.rm-hd__crumb--last{color:var(--rm-shell-text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-hd__search{align-items:center;background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:9999px;display:flex;flex-shrink:0;gap:4px;padding:4px 12px;width:300px}.rm-hd__search input{background:transparent;border:none;color:var(--rm-shell-text);flex:1;font-family:inherit;font-size:14px;line-height:20px;min-width:0;outline:none;padding:0}.rm-hd__search input::-moz-placeholder{color:var(--rm-shell-text-muted)}.rm-hd__search input::placeholder{color:var(--rm-shell-text-muted)}.rm-hd__search i,.rm-hd__search svg{color:var(--rm-shell-text-muted);display:block;flex-shrink:0;font-size:14px;height:14px;line-height:20px;width:14px}.rm-hd__tabs{display:flex;gap:16px;padding:0 16px}.rm-hd__tab{align-items:flex-start;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-bottom:2px solid transparent;border-radius:0;box-shadow:none;color:var(--rm-shell-text-dark);cursor:pointer;display:flex;flex-direction:column;font-family:inherit;font-size:14px;font-weight:700;line-height:1.6;margin:0;padding:4px 4px 8px;white-space:nowrap}.rm-hd__tab--active{border-bottom-color:var(--rm-shell-accent);color:var(--rm-shell-text)}@media (max-width:767px){.rm-sb--left{inset:0 auto 0 0;position:absolute;transform:translateX(-100%);transition:transform .2s;z-index:40}.rm-sb--left.rm-sb--open{transform:translateX(0)}.rm-sb--right{display:none}.rm-hd__search{flex:1;width:auto}}.rm-panel{background:var(--rm-shell-surface);border-left:1px solid var(--rm-shell-border);bottom:0;box-shadow:-8px 0 24px rgba(30,41,59,.08);display:flex;flex-direction:column;position:absolute;right:0;top:0;width:var(--rm-panel-w,360px);z-index:401}.rm-panel__veil{backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);background:var(--rm-panel-veil,rgba(100,116,139,.12));cursor:default;inset:0;position:absolute;z-index:400}.rm-panel-veil-enter-active,.rm-panel-veil-leave-active{transition:opacity .22s ease}.rm-panel-veil-enter-from,.rm-panel-veil-leave-to{opacity:0}@media (prefers-reduced-motion:reduce){.rm-panel-veil-enter-active,.rm-panel-veil-leave-active{transition:none}}.rm-sb--right{position:relative;z-index:402}.rm-panel-enter-active,.rm-panel-leave-active,.rm-sb--right{transition:transform .22s cubic-bezier(.4,0,.2,1)}.rm-panel-enter-from,.rm-panel-leave-to{transform:translateX(100%)}@media (prefers-reduced-motion:reduce){.rm-panel-enter-active,.rm-panel-leave-active,.rm-sb--right{transition:none}}.rm-panel__header{align-items:center;border-bottom:1px solid var(--rm-shell-border);display:flex;flex-shrink:0;gap:8px;height:var(--rm-bar-h);padding:0 16px}.rm-panel__title{color:var(--rm-shell-text);flex:1;font-size:14px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-panel__close{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);cursor:pointer;display:block;flex-shrink:0;height:20px;margin:0;padding:0;transition:color .15s;width:20px}.rm-panel__close:hover{color:var(--rm-shell-text)}.rm-panel__close svg{display:block;height:100%;width:100%}.rm-panel__body{flex:1;min-height:0;overflow-y:auto;padding:16px}@media (max-width:767px){.rm-panel{border-left:none;left:0;width:auto}}
1
+ :root{--rm-shell-bg:#f9f9fa;--rm-shell-surface:#fff;--rm-shell-border:#dbdef0;--rm-shell-subtle:#f5f5f9;--rm-shell-text:#1e293b;--rm-shell-text-dark:#475569;--rm-shell-text-muted:#878ca6;--rm-shell-accent:#2017ad;--rm-shell-inset:8px;--rm-shell-radius:12px;--rm-bar-h:56px;--rm-nav-w:240px;--rm-nav-collapsed-w:64px;--rm-rail-w:56px;--rm-dots-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAcUlEQVR42u3TwQmAMAxAUdfQfUoSZ3OBTNMFHEqLVBEtCB6M8B8EevwktOsAAACAl0SkNzNXtaw6zut7SikNYeJq2Hksh4gs27rG7ZH+eWA7bttigMC78x4TIdBbceX8fJKnkSL1s5RY8zBxAAAA+LUF0ula10BxVDoAAAAASUVORK5CYII=");--rm-dots-size:12px;--rm-dots-opacity:0.1}body.night{--rm-shell-bg:var(--bg-app);--rm-shell-surface:var(--bg-surface,#1a1a24);--rm-shell-border:var(--border-default);--rm-shell-subtle:var(--bg-subtle,#22222e);--rm-shell-text:var(--text-primary);--rm-shell-text-dark:var(--text-secondary);--rm-shell-text-muted:var(--text-muted);--rm-shell-accent:var(--color-primary);--rm-dots-opacity:0.06}.rm-shell{background:var(--rm-shell-bg);color:var(--rm-shell-text);font-family:var(--font-sans,"Figtree",sans-serif);inset:0;overflow:hidden;position:fixed}.rm-shell__dots{background-image:var(--rm-dots-image);background-repeat:repeat;background-size:var(--rm-dots-size) var(--rm-dots-size);inset:0;opacity:var(--rm-dots-opacity);pointer-events:none;position:absolute}.rm-shell__frame{border:1px solid var(--rm-shell-border);border-radius:var(--rm-shell-radius);display:flex;inset:var(--rm-shell-inset);overflow:hidden;position:absolute}.rm-shell__body{display:flex;flex:1;flex-direction:column;min-width:0}.rm-shell__main{flex:1;min-width:0;overflow-y:auto}.rm-sb{background:var(--rm-shell-surface);display:flex;flex-direction:column;flex-shrink:0;height:100%}.rm-sb--left{border-right:1px solid var(--rm-shell-border);position:relative;transition:width .2s;width:var(--rm-nav-w);z-index:200}.rm-sb--left.rm-sb--collapsed{width:var(--rm-nav-collapsed-w)}.rm-sb--right{border-left:1px solid var(--rm-shell-border);width:var(--rm-rail-w)}.rm-sb__header{align-items:center;border-bottom:1px solid var(--rm-shell-border);display:flex;flex-shrink:0;gap:8px;height:var(--rm-bar-h);padding:0 16px}.rm-sb--collapsed .rm-sb__header{justify-content:center;padding:0}.rm-sb__logo{align-items:center;color:var(--rm-shell-text);display:flex;flex:1;font-size:20px;font-weight:700;gap:8px;line-height:1.4;min-width:0;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-sb__toggle{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);cursor:pointer;display:block;flex-shrink:0;height:20px;margin:0;padding:0;transition:color .15s;width:20px}.rm-sb__toggle:hover{color:var(--rm-shell-text)}.rm-sb__toggle svg{display:block;height:100%;width:100%}.rm-sb__nav{display:flex;flex:1;flex-direction:column;gap:16px;overflow-y:auto;padding:16px}.rm-sb--collapsed .rm-sb__nav{padding-left:8px;padding-right:8px}.rm-sb__group{display:flex;flex-direction:column;gap:4px}.rm-sb__label{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);display:flex;font-family:inherit;font-size:10px;font-weight:500;gap:4px;letter-spacing:.025em;line-height:1.6;margin:0;padding:0 2px;text-align:left;text-transform:uppercase;width:100%}button.rm-sb__label{cursor:pointer}button.rm-sb__label:hover{color:var(--rm-shell-text)}.rm-sb__label-text{flex:1;min-width:0}.rm-sb__chev{display:block;flex-shrink:0;height:12px;transition:transform .2s;width:12px}.rm-sb__label[aria-expanded=true] .rm-sb__chev{transform:rotate(90deg)}.rm-sb__rule{background:var(--rm-shell-border);height:1px;margin:4px}.rm-mi{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:4px;box-shadow:none;color:var(--rm-shell-text);cursor:pointer;display:flex;font-family:inherit;gap:8px;height:26px;margin:0;padding:2px;text-align:left;text-decoration:none;transition:background-color .15s;width:100%}.rm-mi:hover{background:color-mix(in srgb,var(--rm-shell-subtle) 50%,transparent)}.rm-mi.rm-mi--active{background:var(--rm-shell-subtle)}.rm-mi.rm-mi--current{background:color-mix(in srgb,var(--rm-shell-accent) 5%,transparent)}.rm-mi.rm-mi--current .rm-mi__icon{background:var(--rm-shell-accent);color:#fff}.rm-mi.rm-mi--current .rm-mi__icon svg{stroke:#fff}.rm-mi__icon{align-items:center;background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-dark);display:flex;flex-shrink:0;height:22px;justify-content:center;line-height:1;width:22px}.rm-mi__icon svg{display:block;height:14px;width:14px}.rm-mi__icon i{font-size:14px;line-height:1}.rm-mi__label{color:var(--rm-shell-text);flex:1;font-size:14px;line-height:1.625;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-mi__badge{background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-muted);flex-shrink:0;font-size:9px;font-weight:700;letter-spacing:.025em;padding:2px 4px;text-transform:uppercase}.rm-sb--collapsed .rm-mi{justify-content:center}.rm-sb--collapsed .rm-mi>:not(.rm-mi__icon),.rm-sb--collapsed .rm-sb__sub{display:none}.rm-sb__tip{background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:6px;box-shadow:0 4px 12px rgba(30,41,59,.1);color:var(--rm-shell-text);font-size:12px;line-height:1.3;padding:5px 9px;pointer-events:none;position:fixed;transform:translateY(-50%);white-space:nowrap;z-index:60}.rm-sb__sub{display:flex;flex-direction:column;gap:2px;padding:2px 0 2px 28px}.rm-sb__sub-item{border-radius:4px;color:var(--rm-shell-text);display:block;font-size:14px;line-height:1.625;overflow:hidden;padding:2px 4px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-sb__sub-item:hover{background:color-mix(in srgb,var(--rm-shell-subtle) 50%,transparent)}.rm-rail__item{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;cursor:pointer;display:flex;flex-direction:column;font-family:inherit;gap:4px;margin:0;padding:12px 0 8px;text-decoration:none;width:100%}.rm-rail__avatar{align-items:center;border:2px solid var(--rm-shell-surface);border-radius:9999px;color:#fff;display:flex;font-size:14px;height:32px;justify-content:center;transition:opacity .15s;width:32px}.rm-rail__item:hover .rm-rail__avatar{opacity:.8}.rm-rail__tile{align-items:center;background:var(--rm-shell-subtle);border-radius:8px;color:var(--rm-shell-text-dark);display:flex;font-size:16px;height:32px;justify-content:center;transition:background-color .15s,color .15s;width:32px}.rm-rail__item:hover .rm-rail__tile{background:var(--rm-shell-border)}.rm-rail__item.rm-rail__item--active .rm-rail__tile{background:var(--rm-shell-accent);color:#fff}.rm-rail__tile{position:relative}.rm-rail__badge{background:var(--rm-shell-accent);border-radius:9999px;color:#fff;font-size:10px;font-weight:700;height:16px;line-height:16px;min-width:16px;padding:0 4px;position:absolute;right:-4px;text-align:center;top:-4px}.rm-rail__item--active .rm-rail__badge{background:#fff;color:var(--rm-shell-accent)}.rm-rail__dot{animation:rm-rail-dot-pulse 2s ease-out infinite;background:var(--color-success,#16a34a);border:2px solid var(--rm-shell-surface);border-radius:9999px;height:10px;position:absolute;right:-2px;top:-2px;width:10px}@keyframes rm-rail-dot-pulse{0%{box-shadow:0 0 0 0 rgba(22,163,74,.55)}70%{box-shadow:0 0 0 6px rgba(22,163,74,0)}to{box-shadow:0 0 0 0 rgba(22,163,74,0)}}@media (prefers-reduced-motion:reduce){.rm-rail__dot{animation:none}}.rm-rail__item--active .rm-rail__dot{border-color:var(--rm-shell-accent)}.rm-rail__caption{color:var(--rm-shell-text-muted);font-size:10px;line-height:1;max-width:100%;overflow:hidden;padding:0 2px;text-overflow:ellipsis;transition:color .15s;white-space:nowrap}.rm-rail__item--active .rm-rail__caption,.rm-rail__item:hover .rm-rail__caption{color:var(--rm-shell-text)}.rm-rail__bottom{display:flex;justify-content:center;margin-top:auto;padding-bottom:16px}.rm-lang{background:var(--rm-shell-subtle);border:1px solid var(--rm-shell-accent);border-radius:9999px;display:grid;gap:2px;grid-template-rows:1fr 1fr;padding:3px;position:relative}.rm-lang__thumb{background:var(--rm-shell-surface);border-radius:9999px;box-shadow:0 1px 4px rgba(30,41,59,.16);height:32px;left:3px;position:absolute;top:3px;transition:transform .26s cubic-bezier(.34,1.56,.64,1);width:32px}.rm-lang--second .rm-lang__thumb{transform:translateY(34px)}.rm-lang__option{align-items:center;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:9999px;box-shadow:none;cursor:pointer;display:flex;filter:grayscale(1);font-size:17px;height:32px;justify-content:center;line-height:1;margin:0;opacity:.5;padding:0;position:relative;transition:filter .18s ease,opacity .18s ease,transform .18s ease;width:32px}.rm-lang__option:hover{filter:grayscale(0);opacity:.85}.rm-lang__option.rm-lang__option--active{filter:grayscale(0);opacity:1}.rm-lang__option:focus-visible{outline:2px solid var(--rm-shell-accent);outline-offset:2px}@media (prefers-reduced-motion:reduce){.rm-lang__option,.rm-lang__thumb{transition:none}}.rm-hd{background:var(--rm-shell-surface);border-bottom:1px solid var(--rm-shell-border);display:flex;flex-direction:column;flex-shrink:0}.rm-hd__row{gap:16px;height:var(--rm-bar-h);padding:0 16px}.rm-hd__crumbs,.rm-hd__row{align-items:center;display:flex}.rm-hd__crumbs{flex:1;font-size:14px;gap:4px;min-width:0}.rm-hd__crumb{align-items:center;color:var(--rm-shell-text-muted);display:inline-flex;gap:6px;text-decoration:none;transition:color .15s;white-space:nowrap}a.rm-hd__crumb:hover{color:var(--rm-shell-text)}.rm-hd__sep{color:var(--rm-shell-text-muted)}.rm-hd__picker{display:inline-flex;min-width:0;position:relative}.rm-hd__crumb--picker{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:4px;box-shadow:none;cursor:pointer;font:inherit;font-size:14px;margin:0;padding:2px 4px;transition:background-color .15s,color .15s}.rm-hd__crumb--picker:hover{background:var(--rm-shell-subtle)}.rm-hd__caret{display:block;flex-shrink:0;height:12px;opacity:.7;transition:transform .15s;width:12px}.rm-hd__caret--open{transform:rotate(180deg)}.rm-hd__menu{background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:8px;box-shadow:0 8px 24px rgba(30,41,59,.12);left:0;max-height:60vh;max-width:320px;min-width:200px;overflow-y:auto;padding:4px;position:absolute;top:calc(100% + 4px);z-index:300}.rm-hd__menu-item{align-items:center;border-radius:4px;color:var(--rm-shell-text);display:flex;font-size:14px;gap:8px;line-height:1.5;overflow:hidden;padding:4px 6px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.rm-hd__menu-item:hover{background:var(--rm-shell-subtle)}.rm-hd__menu-group{color:var(--rm-shell-text-muted);display:block;font-size:10px;font-weight:500;letter-spacing:.025em;line-height:1.6;padding:8px 6px 2px;text-transform:uppercase}.rm-hd__menu-group:first-child{padding-top:2px}.rm-hd__menu-item--active{background:color-mix(in srgb,var(--rm-shell-accent) 5%,transparent);font-weight:600}.rm-hd__menu-icon{align-items:center;background:var(--rm-shell-subtle);border-radius:4px;color:var(--rm-shell-text-dark);display:flex;flex-shrink:0;height:22px;justify-content:center;line-height:1;width:22px}.rm-hd__menu-icon i{font-size:14px;line-height:1}.rm-hd__menu-item--active .rm-hd__menu-icon{background:var(--rm-shell-accent);color:#fff}.rm-hd__crumb--last{color:var(--rm-shell-text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-hd__search{align-items:center;background:var(--rm-shell-surface);border:1px solid var(--rm-shell-border);border-radius:9999px;display:flex;flex-shrink:0;gap:4px;padding:4px 12px;width:300px}.rm-hd__search input{background:transparent;border:none;color:var(--rm-shell-text);flex:1;font-family:inherit;font-size:14px;line-height:20px;min-width:0;outline:none;padding:0}.rm-hd__search input::-moz-placeholder{color:var(--rm-shell-text-muted)}.rm-hd__search input::placeholder{color:var(--rm-shell-text-muted)}.rm-hd__search i,.rm-hd__search svg{color:var(--rm-shell-text-muted);display:block;flex-shrink:0;font-size:14px;height:14px;line-height:20px;width:14px}.rm-hd__tabs{display:flex;gap:16px;padding:0 16px}.rm-hd__tab{align-items:flex-start;-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-bottom:2px solid transparent;border-radius:0;box-shadow:none;color:var(--rm-shell-text-dark);cursor:pointer;display:flex;flex-direction:column;font-family:inherit;font-size:14px;font-weight:700;line-height:1.6;margin:0;padding:4px 4px 8px;white-space:nowrap}.rm-hd__tab--active{border-bottom-color:var(--rm-shell-accent);color:var(--rm-shell-text)}@media (max-width:767px){.rm-sb--left{inset:0 auto 0 0;position:absolute;transform:translateX(-100%);transition:transform .2s;z-index:40}.rm-sb--left.rm-sb--open{transform:translateX(0)}.rm-sb--right{display:none}.rm-hd__search{flex:1;width:auto}}.rm-panel{background:var(--rm-shell-surface);border-left:1px solid var(--rm-shell-border);bottom:0;box-shadow:-8px 0 24px rgba(30,41,59,.08);display:flex;flex-direction:column;position:absolute;right:0;top:0;width:var(--rm-panel-w,360px);z-index:401}.rm-panel__veil{backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);background:var(--rm-panel-veil,rgba(100,116,139,.12));cursor:default;inset:0;position:absolute;z-index:400}.rm-panel-veil-enter-active,.rm-panel-veil-leave-active{transition:opacity .22s ease}.rm-panel-veil-enter-from,.rm-panel-veil-leave-to{opacity:0}@media (prefers-reduced-motion:reduce){.rm-panel-veil-enter-active,.rm-panel-veil-leave-active{transition:none}}.rm-sb--right{position:relative;z-index:402}.rm-panel-enter-active,.rm-panel-leave-active,.rm-sb--right{transition:transform .22s cubic-bezier(.4,0,.2,1)}.rm-panel-enter-from,.rm-panel-leave-to{transform:translateX(100%)}@media (prefers-reduced-motion:reduce){.rm-panel-enter-active,.rm-panel-leave-active,.rm-sb--right{transition:none}}.rm-panel__header{align-items:center;border-bottom:1px solid var(--rm-shell-border);display:flex;flex-shrink:0;gap:8px;height:var(--rm-bar-h);padding:0 16px}.rm-panel__title{color:var(--rm-shell-text);flex:1;font-size:14px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-panel__close{-moz-appearance:none;appearance:none;-webkit-appearance:none;background:none;border:none;border-radius:0;box-shadow:none;color:var(--rm-shell-text-muted);cursor:pointer;display:block;flex-shrink:0;height:20px;margin:0;padding:0;transition:color .15s;width:20px}.rm-panel__close:hover{color:var(--rm-shell-text)}.rm-panel__close svg{display:block;height:100%;width:100%}.rm-panel__body{flex:1;min-height:0;overflow-y:auto;padding:16px}@media (max-width:767px){.rm-panel{border-left:none;left:0;width:auto}}
@@ -0,0 +1,374 @@
1
+ <!--
2
+ RmComplexSelect - champ de filtre a deux colonnes : ajouter d'un cote,
3
+ retirer de l'autre.
4
+
5
+ Reprend `arg-complex-select` d'Auriga : un intitule, un champ qui enumere la
6
+ selection, et un panneau large ou la colonne de gauche propose les valeurs
7
+ disponibles (avec selections rapides et recherche) pendant que celle de
8
+ droite tient la selection en cours.
9
+
10
+ Laquelle prendre : celle-ci quand le referentiel est trop long pour se
11
+ cocher d'un bloc (des milliers de marques, de molecules, de pays) ;
12
+ `RmMultipleSelect` pour une liste courte a cocher ; `RmFilterComplex` pour
13
+ la pastille equivalente dans une barre de filtres.
14
+
15
+ Trois choses changent par rapport a Auriga.
16
+
17
+ La selection est un `v-model`, plus le couple `already_selected` en entree
18
+ et `update:Selection` en sortie : les deux se repondaient en boucle des que
19
+ la page reposait la selection elle-meme.
20
+
21
+ Les lignes sont des boutons : la colonne se parcourt au clavier, alors
22
+ qu'Auriga posait des `div` avec un `@click` et un `@mouseover` pour changer
23
+ l'icone, invisible pour qui n'a pas de souris.
24
+
25
+ Le mode « appliquer / annuler » a ete laisse de cote : il etait deja mis en
26
+ commentaire dans Auriga, et aucune page ne l'appelait.
27
+ -->
28
+ <script setup lang="ts">
29
+ import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
30
+ import { rmPanelOpened, rmPanelRegister } from '../utils/panels'
31
+
32
+ export interface RmComplexSelectPreset {
33
+ label: string
34
+ values: string[]
35
+ }
36
+
37
+ const props = withDefaults(defineProps<{
38
+ /** Intitule pose au-dessus du champ. */
39
+ label: string
40
+ options: string[]
41
+ loading?: boolean
42
+ disabled?: boolean
43
+ /** Selections rapides. Vides, la section ne sort pas. */
44
+ presets?: RmComplexSelectPreset[] | null
45
+ /** Action « Tout » en tete de la colonne de gauche. */
46
+ showSelectAll?: boolean
47
+ /** L'action « Tout » annonce combien de valeurs elle ajouterait. */
48
+ selectAllCount?: boolean
49
+ /**
50
+ * La liste est tronquee par le serveur : le compte de l'action « Tout »
51
+ * s'annonce comme un maximum, sinon il se lit comme le total du
52
+ * referentiel.
53
+ */
54
+ hasMore?: boolean
55
+ addPlaceholder?: string
56
+ removePlaceholder?: string
57
+ emptyLabel?: string
58
+ emptyContent?: string
59
+ /**
60
+ * Filtrage local de la colonne de gauche. A passer a `false` quand les
61
+ * options arrivent deja filtrees du serveur (cf. `RmDropdownSelect`).
62
+ */
63
+ filterSearch?: boolean
64
+ /** Pastille du nombre de valeurs retenues, posee sur le champ. */
65
+ showAmount?: boolean
66
+ /** Pastille d'aide a cote de l'intitule, qui emet `openInfo`. */
67
+ labelInfo?: boolean
68
+ /** Nombre de lignes posees d'un coup dans la colonne de gauche. */
69
+ maxOptions?: number
70
+ lang?: 'fr' | 'en'
71
+ }>(), {
72
+ loading: false,
73
+ disabled: false,
74
+ presets: null,
75
+ showSelectAll: false,
76
+ selectAllCount: false,
77
+ hasMore: false,
78
+ addPlaceholder: undefined,
79
+ removePlaceholder: undefined,
80
+ emptyLabel: undefined,
81
+ emptyContent: undefined,
82
+ filterSearch: true,
83
+ showAmount: true,
84
+ labelInfo: false,
85
+ maxOptions: 500,
86
+ lang: 'fr',
87
+ })
88
+
89
+ const emit = defineEmits<{
90
+ /** Selection complete apres le changement. Double le `v-model`. */
91
+ change: [values: string[]]
92
+ /** Saisie de la colonne « ajouter », amortie a 500 ms. */
93
+ search: [value: string]
94
+ openInfo: []
95
+ }>()
96
+
97
+ const selected = defineModel<string[]>({ default: () => [] })
98
+
99
+ const WORDS = {
100
+ fr: {
101
+ empty: 'Aucune sélection',
102
+ quick: 'Sélection rapide',
103
+ add: 'Ajouter',
104
+ custom: 'Sélection personnalisée',
105
+ all: 'Tout',
106
+ current: 'Sélection en cours',
107
+ clear: 'Tout effacer',
108
+ searchAdd: 'Rechercher une valeur',
109
+ searchDel: 'Rechercher dans la sélection',
110
+ notFound: 'Aucun résultat',
111
+ loading: 'Chargement',
112
+ noSelection: 'Rien de retenu pour le moment',
113
+ },
114
+ en: {
115
+ empty: 'No selection',
116
+ quick: 'Quick selection',
117
+ add: 'Add',
118
+ custom: 'Custom selection',
119
+ all: 'All',
120
+ current: 'Current selection',
121
+ clear: 'Clear all',
122
+ searchAdd: 'Search a value',
123
+ searchDel: 'Search in the selection',
124
+ notFound: 'No result',
125
+ loading: 'Loading',
126
+ noSelection: 'Nothing selected yet',
127
+ },
128
+ } as const
129
+
130
+ const t = computed(() => WORDS[props.lang])
131
+
132
+ const isOpen = ref(false)
133
+ const addSearch = ref('')
134
+ const removeSearch = ref('')
135
+ const activePreset = ref<string>()
136
+ const rootRef = ref<HTMLElement>()
137
+ const addRef = ref<HTMLInputElement>()
138
+
139
+ /** La colonne de gauche ne propose que ce qui n'est pas deja retenu. */
140
+ const addOptions = computed(() => {
141
+ const needle = addSearch.value.trim().toLowerCase()
142
+ const parts = needle && props.filterSearch ? needle.split(' ').filter(Boolean) : []
143
+ return props.options
144
+ .filter(option => !selected.value.includes(option))
145
+ .filter(option => parts.every(part => option.toLowerCase().includes(part)))
146
+ .slice(0, props.maxOptions)
147
+ })
148
+
149
+ const removeOptions = computed(() => {
150
+ const needle = removeSearch.value.trim().toLowerCase()
151
+ if (!needle) return selected.value
152
+ return selected.value.filter(option => option.toLowerCase().includes(needle))
153
+ })
154
+
155
+ const summary = computed(() => selected.value.join(', '))
156
+
157
+ const selectAllLabel = computed(() => {
158
+ if (!props.selectAllCount) return t.value.all
159
+ const count = props.hasMore ? `Max: ${addOptions.value.length}` : addOptions.value.length
160
+ return `${t.value.all} (${count})`
161
+ })
162
+
163
+ let debounceId: ReturnType<typeof setTimeout> | undefined
164
+ watch(addSearch, (value) => {
165
+ clearTimeout(debounceId)
166
+ debounceId = setTimeout(() => emit('search', value), 500)
167
+ })
168
+
169
+ function close() {
170
+ isOpen.value = false
171
+ document.removeEventListener('click', onDocumentClick)
172
+ }
173
+
174
+ function onDocumentClick(event: MouseEvent) {
175
+ if (!rootRef.value?.contains(event.target as Node)) close()
176
+ }
177
+
178
+ async function toggle() {
179
+ if (props.disabled) return
180
+ if (isOpen.value) return close()
181
+
182
+ isOpen.value = true
183
+ rmPanelOpened(close)
184
+ document.addEventListener('click', onDocumentClick)
185
+ await nextTick()
186
+ addRef.value?.focus()
187
+ }
188
+
189
+ function commit(values: string[]) {
190
+ selected.value = values
191
+ emit('change', values)
192
+ }
193
+
194
+ function add(option: string) {
195
+ activePreset.value = undefined
196
+ commit([...selected.value, option])
197
+ }
198
+
199
+ function remove(option: string) {
200
+ activePreset.value = undefined
201
+ commit(selected.value.filter(value => value !== option))
202
+ }
203
+
204
+ function addAll() {
205
+ activePreset.value = undefined
206
+ commit([...selected.value, ...addOptions.value])
207
+ }
208
+
209
+ function clearAll() {
210
+ activePreset.value = undefined
211
+ commit([])
212
+ }
213
+
214
+ /** Une selection rapide remplace la selection : elle ne s'y ajoute pas. */
215
+ function applyPreset(preset: RmComplexSelectPreset) {
216
+ if (activePreset.value === preset.label) {
217
+ clearAll()
218
+ return
219
+ }
220
+ commit([...new Set(preset.values)])
221
+ activePreset.value = preset.label
222
+ }
223
+
224
+ let unregister: (() => void) | undefined
225
+ onMounted(() => {
226
+ unregister = rmPanelRegister(close)
227
+ })
228
+
229
+ onUnmounted(() => {
230
+ unregister?.()
231
+ clearTimeout(debounceId)
232
+ document.removeEventListener('click', onDocumentClick)
233
+ })
234
+ </script>
235
+
236
+ <template>
237
+ <div ref="rootRef" class="rm-csel" @keydown.escape="close">
238
+ <p class="rm-csel__label">
239
+ {{ label }}
240
+ <button v-if="labelInfo" type="button" class="rm-csel__info" @click="emit('openInfo')">
241
+ <RmIcon name="Info" :size="14" />
242
+ </button>
243
+ </p>
244
+
245
+ <button
246
+ type="button"
247
+ class="rm-csel__field"
248
+ :class="{ 'is-open': isOpen, 'is-disabled': disabled }"
249
+ :disabled="disabled"
250
+ :aria-expanded="isOpen"
251
+ aria-haspopup="true"
252
+ @click="toggle"
253
+ >
254
+ <RmTooltip :text="summary" :disabled="selected.length === 0" class="rm-csel__value-slot">
255
+ <span class="rm-csel__value" :class="{ 'is-empty': selected.length === 0 }">
256
+ {{ selected.length > 0 ? summary : emptyLabel || t.empty }}
257
+ </span>
258
+ </RmTooltip>
259
+ <span v-if="showAmount && selected.length > 0" class="rm-csel__count">
260
+ {{ selected.length > 99 ? '99+' : selected.length }}
261
+ </span>
262
+ <RmIcon name="CaretDown" :size="16" />
263
+ </button>
264
+
265
+ <div v-show="isOpen" class="rm-csel__panel" @click.stop>
266
+ <div class="rm-csel__column">
267
+ <div v-if="presets && presets.length > 0" class="rm-csel__presets">
268
+ <h2 class="rm-csel__section">{{ t.quick }}</h2>
269
+ <div class="rm-csel__pills">
270
+ <button
271
+ v-for="preset in presets"
272
+ :key="preset.label"
273
+ type="button"
274
+ class="rm-csel__pill"
275
+ :class="{ 'is-active': activePreset === preset.label }"
276
+ :aria-pressed="activePreset === preset.label"
277
+ @click="applyPreset(preset)"
278
+ >
279
+ {{ preset.label }}
280
+ </button>
281
+ </div>
282
+ </div>
283
+
284
+ <div class="rm-csel__head">
285
+ <h2 class="rm-csel__section">{{ presets && presets.length > 0 ? t.custom : t.add }}</h2>
286
+ <button
287
+ v-if="showSelectAll || selectAllCount"
288
+ type="button"
289
+ class="rm-csel__action"
290
+ :disabled="addOptions.length === 0"
291
+ @click="addAll"
292
+ >
293
+ {{ selectAllLabel }}
294
+ </button>
295
+ </div>
296
+
297
+ <div class="rm-csel__search">
298
+ <RmIcon name="MagnifyingGlass" :size="14" />
299
+ <input
300
+ ref="addRef"
301
+ v-model="addSearch"
302
+ type="search"
303
+ class="rm-csel__search-input"
304
+ :placeholder="addPlaceholder || t.searchAdd"
305
+ :aria-label="addPlaceholder || t.searchAdd"
306
+ >
307
+ </div>
308
+
309
+ <p v-if="loading" class="rm-csel__state" aria-busy="true">{{ t.loading }}</p>
310
+ <p v-else-if="addOptions.length === 0" class="rm-csel__state">
311
+ {{ emptyContent || t.notFound }}
312
+ </p>
313
+ <div v-else class="rm-csel__list">
314
+ <button
315
+ v-for="option in addOptions"
316
+ :key="option"
317
+ type="button"
318
+ class="rm-csel__option rm-csel__option--add"
319
+ @click="add(option)"
320
+ >
321
+ <RmIcon name="PlusCircle" :size="14" />
322
+ <span>{{ option }}</span>
323
+ </button>
324
+ </div>
325
+ </div>
326
+
327
+ <div class="rm-csel__column rm-csel__column--right">
328
+ <div class="rm-csel__head">
329
+ <h2 class="rm-csel__section">{{ t.current }}</h2>
330
+ <button
331
+ type="button"
332
+ class="rm-csel__action rm-csel__action--clear"
333
+ :disabled="selected.length === 0"
334
+ @click="clearAll"
335
+ >
336
+ {{ t.clear }}
337
+ </button>
338
+ </div>
339
+
340
+ <div class="rm-csel__search">
341
+ <RmIcon name="MagnifyingGlass" :size="14" />
342
+ <input
343
+ v-model="removeSearch"
344
+ type="search"
345
+ class="rm-csel__search-input"
346
+ :placeholder="removePlaceholder || t.searchDel"
347
+ :aria-label="removePlaceholder || t.searchDel"
348
+ >
349
+ </div>
350
+
351
+ <p v-if="selected.length === 0" class="rm-csel__state">{{ t.noSelection }}</p>
352
+ <p v-else-if="removeOptions.length === 0" class="rm-csel__state">
353
+ {{ emptyContent || t.notFound }}
354
+ </p>
355
+ <div v-else class="rm-csel__list">
356
+ <button
357
+ v-for="option in removeOptions"
358
+ :key="option"
359
+ type="button"
360
+ class="rm-csel__option rm-csel__option--remove"
361
+ @click="remove(option)"
362
+ >
363
+ <RmIcon name="MinusCircle" :size="16" />
364
+ <span>{{ option }}</span>
365
+ </button>
366
+ </div>
367
+ </div>
368
+ </div>
369
+ </div>
370
+ </template>
371
+
372
+ <style scoped>
373
+ .rm-csel{align-items:flex-start;display:flex;flex-direction:column;gap:4px;position:relative}.rm-csel__label{align-items:center;color:var(--text-secondary);display:flex;font-size:var(--font-12,12px);gap:4px;line-height:14px}.rm-csel__info{background:none;border:none;color:var(--text-muted);cursor:pointer;display:flex;padding:0}.rm-csel__field{align-items:center;background:var(--bg-surface);border:1.5px solid var(--border-default);border-radius:var(--radius-md,8px);color:var(--text-primary);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-14,14px);font-weight:700;gap:4px;line-height:16px;padding:12px;text-align:left;width:196px}.rm-csel__field:hover:not(.is-disabled){border-color:rgba(var(--brand-rgb),.3)}.rm-csel__field.is-open{border-color:var(--color-primary)}.rm-csel__field.is-disabled{background:var(--bg-surface-2);color:var(--text-muted);cursor:not-allowed}.rm-csel__field:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.rm-csel__value-slot{display:block;flex:1;min-width:0}.rm-csel__value{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-csel__value.is-empty{color:var(--text-muted);font-style:italic;font-weight:400}.rm-csel__field :deep(svg){color:var(--text-secondary);flex-shrink:0}.rm-csel__count{align-items:center;background:rgba(var(--brand-rgb),.1);border-radius:50%;color:var(--color-primary);display:flex;flex-shrink:0;font-size:var(--font-12,12px);font-weight:600;height:20px;justify-content:center;width:20px}.rm-csel__panel{background:var(--bg-surface);border:1.5px solid var(--border-default);border-radius:var(--radius-lg,12px);box-shadow:var(--r-shadow-lg,0 8px 24px rgba(0,0,0,.12));box-sizing:border-box;display:flex;left:0;margin-top:8px;max-width:calc(100vw - 32px);position:absolute;top:100%;width:620px;z-index:12}.rm-csel__column{display:flex;flex:1;flex-direction:column;gap:8px;min-width:0;padding:16px}.rm-csel__column--right{background:var(--bg-surface-2);border-left:1px solid var(--border-soft);border-radius:0 var(--radius-lg,12px) var(--radius-lg,12px) 0}.rm-csel__presets{border-bottom:1px solid var(--border-soft);display:flex;flex-direction:column;gap:8px;padding-bottom:8px}.rm-csel__pills{display:flex;flex-wrap:wrap;gap:4px}.rm-csel__pill{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:9999px;color:var(--text-secondary);cursor:pointer;font-family:inherit;font-size:var(--font-12,12px);padding:4px 10px}.rm-csel__pill.is-active,.rm-csel__pill:hover{border-color:var(--color-primary);color:var(--color-primary)}.rm-csel__pill.is-active{background:rgba(var(--brand-rgb),.1);font-weight:700}.rm-csel__head{align-items:center;display:flex;gap:8px;justify-content:space-between}.rm-csel__section{color:var(--text-secondary);font-size:var(--font-12,12px);font-weight:700;margin:0}.rm-csel__action{background:none;border:none;color:var(--color-primary);cursor:pointer;font-family:inherit;font-size:var(--font-12,12px);font-weight:600;padding:0}.rm-csel__action:disabled{color:var(--text-muted);cursor:not-allowed}.rm-csel__action:hover:not(:disabled){text-decoration:underline}.rm-csel__action--clear:not(:disabled){color:var(--color-danger)}.rm-csel__search{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:var(--radius-md,8px);display:flex;gap:8px;padding:6px 10px}.rm-csel__search :deep(svg){color:var(--text-muted);flex-shrink:0}.rm-csel__search-input{background:none;border:none;color:var(--text-primary);font-family:inherit;font-size:var(--font-14,14px);width:100%}.rm-csel__search-input::-moz-placeholder{color:var(--text-muted);font-size:var(--font-12,12px)}.rm-csel__search-input::placeholder{color:var(--text-muted);font-size:var(--font-12,12px)}.rm-csel__search-input:focus-visible{outline:none}.rm-csel__state{color:var(--text-secondary);font-size:var(--font-14,14px);font-style:italic;padding-top:8px}.rm-csel__list{display:flex;flex-direction:column;gap:4px;height:260px;overflow-y:auto;scrollbar-width:thin}.rm-csel__option{align-items:flex-start;background:none;border:none;border-radius:var(--radius-sm,4px);color:var(--text-primary);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-14,14px);gap:8px;line-height:160%;padding:2px 4px;text-align:left}.rm-csel__option :deep(svg){flex-shrink:0;margin-top:4px}.rm-csel__option:hover{background:rgba(var(--brand-rgb),.05)}.rm-csel__option:focus-visible{outline:2px solid var(--color-primary);outline-offset:-2px}.rm-csel__option--add :deep(svg){color:var(--color-primary)}.rm-csel__option--remove :deep(svg){color:var(--color-danger)}@media (max-width:767px){.rm-csel__panel{flex-direction:column;width:calc(100vw - 32px)}.rm-csel__column--right{border-left:none;border-top:1px solid var(--border-soft)}.rm-csel__list{height:180px}}
374
+ </style>
@@ -26,7 +26,8 @@
26
26
  JSON de locale au montage.
27
27
  -->
28
28
  <script setup lang="ts">
29
- import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
29
+ import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
30
+ import { rmPanelOpened, rmPanelRegister } from '../utils/panels'
30
31
 
31
32
  const props = withDefaults(defineProps<{
32
33
  /** Intitule pose au-dessus du champ. */
@@ -120,6 +121,7 @@ async function toggle() {
120
121
  if (isOpen.value) return close()
121
122
 
122
123
  isOpen.value = true
124
+ rmPanelOpened(close)
123
125
  searchTerm.value = ''
124
126
  activeIndex.value = props.options.indexOf(selected.value ?? '')
125
127
  document.addEventListener('click', onDocumentClick)
@@ -155,7 +157,13 @@ function onKeydown(event: KeyboardEvent) {
155
157
  }
156
158
  }
157
159
 
160
+ let unregister: (() => void) | undefined
161
+ onMounted(() => {
162
+ unregister = rmPanelRegister(close)
163
+ })
164
+
158
165
  onUnmounted(() => {
166
+ unregister?.()
159
167
  clearTimeout(debounceId)
160
168
  document.removeEventListener('click', onDocumentClick)
161
169
  })
@@ -172,7 +180,7 @@ onUnmounted(() => {
172
180
  :disabled="disabled"
173
181
  :aria-expanded="isOpen"
174
182
  aria-haspopup="listbox"
175
- @click.stop="toggle"
183
+ @click="toggle"
176
184
  >
177
185
  <RmTooltip :text="selected ?? ''" :disabled="!selected" class="rm-dsel__value-slot">
178
186
  <span class="rm-dsel__value" :class="{ 'is-empty': !selected }">
@@ -275,5 +275,5 @@ onBeforeUnmount(() => {
275
275
  </template>
276
276
 
277
277
  <style scoped>
278
- .rm-fbar{margin-inline:calc((min(var(--oip-content-max, 100%), 100%) - var(--oip-main-w, 100%))/2);position:sticky;width:var(--oip-main-w,100%);z-index:91;--rm-fbar-field-h:32px;backdrop-filter:blur(12px);background:rgba(245,245,249,.8);border-bottom:1px solid var(--border-default);display:flex;flex-direction:column;font-family:var(--font-sans)}.rm-fbar__views{align-items:center;display:flex;flex:0 0 auto}.rm-fbar__views:empty{display:none}.rm-fbar__row{align-items:flex-start;display:flex;gap:12px;padding-block:8px;padding-inline:max(32px,(100% - var(--oip-content-max,100%))/2 + 32px)}.rm-fbar--open .rm-fbar__row:not(:has(~.rm-fbar__rail-row)){border-bottom:1px solid var(--border-default)}.rm-fbar__toggle :deep(p),.rm-fbar__toggle :deep(span){font-size:inherit;font-weight:inherit;line-height:inherit;margin:0}.rm-fbar__toggle{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:var(--radius-pill);color:var(--text-primary);cursor:pointer;display:flex;flex:0 0 auto;font-family:inherit;font-size:var(--font-14);font-weight:var(--weight-medium);gap:6px;height:var(--rm-fbar-field-h);justify-content:center;padding:0 14px}.rm-fbar__toggle:hover{background:var(--bg-surface-3)}.rm-fbar__toggle.is-active,.rm-fbar__toggle.is-active:hover{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-text-inverse)}.rm-fbar__toggle.is-active .rm-fbar__badge{background:var(--color-text-inverse);color:var(--color-primary)}.rm-fbar__badge{align-items:center;background:var(--color-primary);border-radius:16px;color:var(--color-text-inverse);display:inline-flex;font-size:var(--font-11);font-weight:var(--weight-bold);justify-content:center;min-width:18px;padding:0 5px}.rm-fbar__view{align-items:center;display:flex;flex:0 0 auto}.rm-fbar__advanced{align-items:center;background:none;border:none;border-left:1px solid var(--border-default);color:var(--color-primary);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--font-13);font-weight:var(--weight-medium);height:var(--rm-fbar-field-h);padding:0 0 0 12px;position:absolute;right:14px;text-decoration-line:underline;top:0;white-space:nowrap;z-index:2}.rm-fbar__advanced.is-active,.rm-fbar__advanced:hover{color:var(--color-primary-hover,var(--color-primary));text-decoration-thickness:2px}.rm-fbar__rail-row{display:flex;padding-bottom:8px;padding-inline:max(32px,(100% - var(--oip-content-max,100%))/2 + 32px)}.rm-fbar--open .rm-fbar__rail-row{border-bottom:1px solid var(--border-default)}.rm-fbar__rail{align-items:center;display:flex;flex:0 1 auto;min-width:0;overflow-x:auto;scrollbar-width:thin}.rm-fbar__rail:empty{display:none}.rm-fbar__search{align-items:center;display:flex;flex:1 1 auto;gap:8px;min-width:0;position:relative}.rm-fbar__search:empty{display:none}.rm-fbar__search :deep(.search-bar-wrapper){flex:1 1 auto;min-width:0}.rm-fbar__search :deep(.search-bar){background:var(--bg-surface);box-sizing:border-box;display:flex;height:var(--rm-fbar-field-h);width:100%}.rm-fbar__search :deep(.filters_input_search){border-radius:var(--radius-pill);box-sizing:border-box;height:auto;min-height:var(--rm-fbar-field-h);padding-right:calc(var(--rm-fbar-advanced-w, 0px) + 12px);width:100%}.rm-fbar__search :deep(.research_tags:not(:has(*))){display:none}.rm-fbar__search :deep(.select_shortcut){box-sizing:border-box;font-size:var(--font-11);height:24px;padding-block:0}.rm-fbar__search :deep(.select_shortcut:hover){background:var(--bg-surface-3)!important;border-color:var(--border-default)!important;color:inherit!important}.rm-fbar__search :deep(.select_shortcut:hover svg){color:inherit!important}.rm-fbar__search :deep(.remove_search_section){border-left:none;border-radius:0 var(--radius-pill) var(--radius-pill) 0}.rm-fbar__search :deep(.remove_search_section:hover){background:transparent!important}.rm-fbar__search :deep(.remove_search_section:hover svg){color:var(--text-primary)!important}.rm-fbar__search :deep(.filters_input_search.no_bottom){border-bottom:1.5px solid var(--color-primary)!important;border-radius:var(--radius-pill)}.rm-fbar__search :deep(.search_suggestions){border:1px solid var(--border-default);border-radius:var(--radius-2xl);box-shadow:var(--shadow-lg);left:0;padding:6px;right:0;top:calc(100% + 6px);width:auto}.rm-fbar__search :deep(.sugg_container>*){border-radius:var(--radius-lg)}.rm-fbar__search :deep(.sugg_container>.selected){background:color-mix(in srgb,var(--color-primary) 6%,transparent)!important}.rm-fbar__panel{--rm-filter-col:224px;--rm-fbar-panel-field-h:40px;align-items:end;display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(0,var(--rm-filter-col)));justify-content:center;padding-block:16px 20px;padding-inline:56px}.rm-fbar__panel--wide{align-items:stretch;display:flex;flex-direction:column;gap:12px}.rm-fbar__filters{display:contents}.rm-fbar__filters :deep(.filter-chip),.rm-fbar__filters :deep(.filter-complex__trigger),.rm-fbar__filters :deep(.rm-number__box){border-radius:var(--radius-lg);height:var(--rm-fbar-panel-field-h);width:100%}.rm-fbar__panel-head{align-items:baseline;display:flex;gap:16px;grid-column:1/-1;width:100%}.rm-fbar__customize{grid-column:1/-1}.rm-fbar__panel :deep(.filters_row_break){grid-column:1/-1}.rm-fbar__panel-title{font-size:var(--font-18);font-weight:800;margin:0}.rm-fbar__action{background:none;border:none;cursor:pointer;font-family:inherit;font-size:var(--font-14);font-weight:var(--weight-medium);padding:0;text-decoration-line:underline}.rm-fbar__action--save{color:var(--color-primary)}.rm-fbar__action--clear{color:var(--color-danger)}.rm-fbar__action--clear:hover{opacity:.8;text-decoration-thickness:2px}
278
+ .rm-fbar{margin-inline:calc((min(var(--oip-content-max, 100%), 100%) - var(--oip-main-w, 100%))/2);position:sticky;width:var(--oip-main-w,100%);z-index:91;--rm-fbar-field-h:32px;backdrop-filter:blur(12px);background:rgba(245,245,249,.8);border-bottom:1px solid var(--border-default);display:flex;flex-direction:column;font-family:var(--font-sans)}.rm-fbar__views{align-items:center;display:flex;flex:0 0 auto}.rm-fbar__views:empty{display:none}.rm-fbar__row{align-items:flex-start;display:flex;gap:12px;padding-block:8px;padding-inline:max(32px,(100% - var(--oip-content-max,100%))/2 + 32px)}.rm-fbar--open .rm-fbar__row:not(:has(~.rm-fbar__rail-row)){border-bottom:1px solid var(--border-default)}.rm-fbar__toggle :deep(p),.rm-fbar__toggle :deep(span){font-size:inherit;font-weight:inherit;line-height:inherit;margin:0}.rm-fbar__toggle{align-items:center;background:var(--bg-surface);border:1px solid var(--border-default);border-radius:var(--radius-pill);color:var(--text-primary);cursor:pointer;display:flex;flex:0 0 auto;font-family:inherit;font-size:var(--font-14);font-weight:var(--weight-medium);gap:6px;height:var(--rm-fbar-field-h);justify-content:center;padding:0 14px}.rm-fbar__toggle:hover{background:var(--bg-surface-3)}.rm-fbar__toggle.is-active,.rm-fbar__toggle.is-active:hover{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-text-inverse)}.rm-fbar__toggle.is-active .rm-fbar__badge{background:var(--color-text-inverse);color:var(--color-primary)}.rm-fbar__badge{align-items:center;background:var(--color-primary);border-radius:16px;color:var(--color-text-inverse);display:inline-flex;font-size:var(--font-11);font-weight:var(--weight-bold);justify-content:center;min-width:18px;padding:0 5px}.rm-fbar__view{align-items:center;display:flex;flex:0 0 auto}.rm-fbar__advanced{align-items:center;background:none;border:none;border-left:1px solid var(--border-default);color:var(--color-primary);cursor:pointer;display:inline-flex;font-family:inherit;font-size:var(--font-13);font-weight:var(--weight-medium);height:var(--rm-fbar-field-h);padding:0 0 0 12px;position:absolute;right:14px;text-decoration-line:underline;top:0;white-space:nowrap;z-index:2}.rm-fbar__advanced.is-active,.rm-fbar__advanced:hover{color:var(--color-primary-hover,var(--color-primary));text-decoration-thickness:2px}.rm-fbar__rail-row{display:flex;padding-bottom:8px;padding-inline:max(32px,(100% - var(--oip-content-max,100%))/2 + 32px)}.rm-fbar--open .rm-fbar__rail-row{border-bottom:1px solid var(--border-default)}.rm-fbar__rail{align-items:center;display:flex;flex:0 1 auto;min-width:0;overflow-x:auto;scrollbar-width:thin}.rm-fbar__rail:empty{display:none}.rm-fbar__search{align-items:center;display:flex;flex:1 1 auto;gap:8px;min-width:0;position:relative}.rm-fbar__search:empty{display:none}.rm-fbar__search :deep(.search-bar-wrapper){flex:1 1 auto;min-width:0}.rm-fbar__search :deep(.search-bar){background:var(--bg-surface);box-sizing:border-box;display:flex;height:var(--rm-fbar-field-h);width:100%}.rm-fbar__search :deep(.filters_input_search){border-radius:var(--radius-pill);box-sizing:border-box;height:auto;min-height:var(--rm-fbar-field-h);padding-right:calc(var(--rm-fbar-advanced-w, 0px) + 12px);width:100%}.rm-fbar__search :deep(.research_tags:not(:has(*))){display:none}.rm-fbar__search :deep(.select_shortcut){box-sizing:border-box;font-size:var(--font-11);height:24px;padding-block:0}.rm-fbar__search :deep(.select_shortcut:hover){background:var(--bg-surface-3)!important;border-color:var(--border-default)!important;color:inherit!important}.rm-fbar__search :deep(.select_shortcut:hover svg){color:inherit!important}.rm-fbar__search :deep(.remove_search_section){border-left:none;border-radius:0 var(--radius-pill) var(--radius-pill) 0}.rm-fbar__search :deep(.remove_search_section:hover){background:transparent!important}.rm-fbar__search :deep(.remove_search_section:hover svg){color:var(--text-primary)!important}.rm-fbar__search :deep(.filters_input_search.no_bottom){border-bottom:1.5px solid var(--color-primary)!important;border-radius:var(--radius-pill)}.rm-fbar__search :deep(.search_suggestions){border:1px solid var(--border-default);border-radius:var(--radius-2xl);box-shadow:var(--shadow-lg);left:0;padding:6px;right:0;top:calc(100% + 6px);width:auto}.rm-fbar__search :deep(.sugg_container>*){border-radius:var(--radius-lg)}.rm-fbar__search :deep(.sugg_container>.selected){background:color-mix(in srgb,var(--color-primary) 6%,transparent)!important}.rm-fbar__panel{--rm-filter-col:224px;--rm-fbar-panel-field-h:40px;align-items:end;display:grid;gap:8px;grid-template-columns:repeat(auto-fit,minmax(0,var(--rm-filter-col)));justify-content:center;padding-block:16px 20px;padding-inline:56px}.rm-fbar__panel--wide{align-items:stretch;display:flex;flex-direction:column;gap:12px}.rm-fbar__filters{display:contents}.rm-fbar__filters :deep(.filter-chip),.rm-fbar__filters :deep(.filter-complex__trigger),.rm-fbar__filters :deep(.rm-number__box){border-radius:var(--radius-lg);height:var(--rm-fbar-panel-field-h);width:100%}.rm-fbar__panel-head{align-items:baseline;display:flex;gap:16px;grid-column:1/-1;width:100%}.rm-fbar__customize{grid-column:1/-1}.rm-fbar__panel :deep(.filters_row_break){grid-column:1/-1}.rm-fbar__panel-title{font-size:var(--font-18);font-weight:800;margin:0}.rm-fbar__action{background:none;border:none;cursor:pointer;font-family:inherit;font-size:var(--font-14);font-weight:var(--weight-medium);padding:0;text-decoration-line:underline}.rm-fbar__action--save{color:var(--color-primary)}.rm-fbar__action--clear{color:var(--color-danger)}.rm-fbar__action--clear:hover{opacity:.8;text-decoration-thickness:2px}
279
279
  </style>
@@ -24,7 +24,8 @@
24
24
  identifiant cassait des que la liste etait filtree.
25
25
  -->
26
26
  <script setup lang="ts">
27
- import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
27
+ import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
28
+ import { rmPanelOpened, rmPanelRegister } from '../utils/panels'
28
29
 
29
30
  const props = withDefaults(defineProps<{
30
31
  /** Intitule pose au-dessus du champ. */
@@ -134,6 +135,7 @@ async function toggle() {
134
135
  if (isOpen.value) return close()
135
136
 
136
137
  isOpen.value = true
138
+ rmPanelOpened(close)
137
139
  searchTerm.value = ''
138
140
  document.addEventListener('click', onDocumentClick)
139
141
  if (!props.search) return
@@ -156,7 +158,13 @@ function toggleAll() {
156
158
  commit(allSelected.value ? [] : [...props.options])
157
159
  }
158
160
 
161
+ let unregister: (() => void) | undefined
162
+ onMounted(() => {
163
+ unregister = rmPanelRegister(close)
164
+ })
165
+
159
166
  onUnmounted(() => {
167
+ unregister?.()
160
168
  clearTimeout(debounceId)
161
169
  document.removeEventListener('click', onDocumentClick)
162
170
  })
@@ -178,7 +186,7 @@ onUnmounted(() => {
178
186
  :disabled="disabled"
179
187
  :aria-expanded="isOpen"
180
188
  aria-haspopup="true"
181
- @click.stop="toggle"
189
+ @click="toggle"
182
190
  >
183
191
  <RmTooltip :text="summary" :disabled="selected.length === 0" class="rm-msel__value-slot">
184
192
  <span class="rm-msel__value" :class="{ 'is-empty': selected.length === 0 }">
@@ -7,9 +7,11 @@
7
7
  enregistrees, basculer sur une vue favorite, ouvrir le reste (toutes les
8
8
  vues, enregistrer, et ce que la page ajoute).
9
9
 
10
- Un point orange parait des que l'ecran ne correspond plus a la vue active :
11
- c'est le seul etat que la pastille porte elle-meme, parce que c'est le seul
12
- qui se perd si on ne le voit pas.
10
+ Un point pulse a droite du nom des qu'il y a un etat a dire : vert quand une
11
+ vue est posee, orange quand l'ecran ne correspond plus a cette vue. Le second
12
+ couvre le premier, parce qu'une modification non enregistree est ce qui se
13
+ perd si on ne le voit pas. Meme forme que le point du rail : un seul signe a
14
+ apprendre pour les deux endroits ou l'etat d'une vue se lit.
13
15
 
14
16
  La pastille ne connait ni l'API ni le magasin de vues : elle recoit une
15
17
  liste et emet ce que l'utilisateur demande.
@@ -74,6 +76,7 @@ const WORDS = {
74
76
  favorites: 'Favoris',
75
77
  actions: 'Actions',
76
78
  unsaved: 'Modifications non enregistrées',
79
+ applied: 'Vue appliquée',
77
80
  save: 'Sauvegarder',
78
81
  aria: 'Vue affichée',
79
82
  },
@@ -83,6 +86,7 @@ const WORDS = {
83
86
  favorites: 'Favorites',
84
87
  actions: 'Actions',
85
88
  unsaved: 'Unsaved changes',
89
+ applied: 'View applied',
86
90
  save: 'Save',
87
91
  aria: 'Current view',
88
92
  },
@@ -142,7 +146,18 @@ onBeforeUnmount(() => {
142
146
  <RmIcon name="BookmarkSimple" :size="16" class="rm-vpill__icon" />
143
147
  <span class="rm-vpill__key">{{ t.key }}</span>
144
148
  <span class="rm-vpill__value">{{ label }}</span>
145
- <span v-if="dirty" class="rm-vpill__dot" :title="t.unsaved" aria-hidden="true" />
149
+ <span
150
+ v-if="dirty"
151
+ class="rm-vpill__dot rm-vpill__dot--unsaved"
152
+ :title="t.unsaved"
153
+ aria-hidden="true"
154
+ />
155
+ <span
156
+ v-else-if="viewName"
157
+ class="rm-vpill__dot rm-vpill__dot--applied"
158
+ :title="t.applied"
159
+ aria-hidden="true"
160
+ />
146
161
  <RmIcon class="rm-vpill__caret" name="CaretDown" :size="14" />
147
162
  </button>
148
163
 
@@ -194,5 +209,5 @@ onBeforeUnmount(() => {
194
209
  </template>
195
210
 
196
211
  <style scoped>
197
- .rm-vpill{position:relative}.rm-vpill,.rm-vpill__pill{align-items:center;display:flex}.rm-vpill__pill{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:var(--radius-pill);color:var(--text-primary);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-14);font-weight:var(--weight-medium);gap:6px;height:var(--rm-fbar-field-h,32px);padding:0 14px;white-space:nowrap}.rm-vpill__pill:hover{background:var(--bg-surface-3)}.rm-vpill__pill.is-open{border-color:var(--color-primary);color:var(--color-primary)}.rm-vpill__icon{color:currentColor;flex-shrink:0}.rm-vpill__key{color:var(--text-muted);font-weight:var(--weight-normal)}.rm-vpill__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-vpill__pill.has-unsaved{border-color:var(--color-warning)}.rm-vpill__dot{animation:rm-vpill-pulse 2s ease-out infinite;background:var(--color-warning);border-radius:50%;flex-shrink:0;height:8px;width:8px}@keyframes rm-vpill-pulse{0%{box-shadow:0 0 0 0 rgba(217,119,6,.6)}70%{box-shadow:0 0 0 6px rgba(217,119,6,0)}to{box-shadow:0 0 0 0 rgba(217,119,6,0)}}@media (prefers-reduced-motion:reduce){.rm-vpill__dot,.rm-vpill__unsaved-dot:before{animation:none}}.rm-vpill__caret{color:var(--text-muted);flex-shrink:0}.rm-vpill__menu{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:8px;box-shadow:var(--shadow-lg);box-sizing:border-box;font-family:var(--font-sans);left:0;max-width:460px;min-width:320px;padding:6px;position:absolute;top:calc(100% + 6px);z-index:60}.rm-vpill__unsaved{align-items:center;background:var(--color-warning-bg);border-radius:var(--radius-md);color:var(--color-warning);display:flex;font-size:var(--font-12);gap:8px;padding:8px 12px}.rm-vpill__unsaved-dot{align-items:center;display:inline-flex;flex-shrink:0;height:14px;justify-content:center;width:14px}.rm-vpill__unsaved-dot:before{animation:rm-vpill-pulse 2s ease-out infinite;background:var(--color-warning);border-radius:50%;content:"";height:7px;width:7px}.rm-vpill__unsaved-label{flex:1;font-weight:var(--weight-semibold)}.rm-vpill__unsaved-cta{background:transparent;border:none;color:var(--color-warning);cursor:pointer;font-family:inherit;font-size:inherit;font-weight:var(--weight-bold);padding:0;text-decoration:underline;text-underline-offset:2px}.rm-vpill__unsaved-cta:hover{color:var(--text-primary)}.rm-vpill__divider{background:var(--border-soft);height:1px;margin:6px -6px}.rm-vpill__section{color:var(--text-muted);font-size:var(--font-10);font-weight:var(--weight-bold);letter-spacing:.08em;margin:0;padding:8px 12px 4px 34px;text-align:left;text-transform:uppercase}.rm-vpill__item{align-items:center;background:none;border:none;border-radius:var(--radius-md);color:var(--text-secondary);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-13);gap:8px;padding:8px 12px;text-align:left;transition:background .1s,color .1s;width:100%}.rm-vpill__item:hover{background:var(--bg-hover);color:var(--text-primary)}.rm-vpill__item.is-active{background:var(--bg-hover);color:var(--color-secondary);font-weight:var(--weight-semibold)}.rm-vpill__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-vpill__item--view .rm-vpill__check{color:var(--color-secondary);flex-shrink:0;opacity:0;transition:opacity .1s}.rm-vpill__item--view.is-active .rm-vpill__check{opacity:1}
212
+ .rm-vpill{position:relative}.rm-vpill,.rm-vpill__pill{align-items:center;display:flex}.rm-vpill__pill{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:var(--radius-pill);color:var(--text-primary);cursor:pointer;font-family:var(--font-sans);font-size:var(--font-14);font-weight:var(--weight-medium);gap:6px;height:var(--rm-fbar-field-h,32px);padding:0 14px;white-space:nowrap}.rm-vpill__pill:hover{background:var(--bg-surface-3)}.rm-vpill__pill.is-open{border-color:var(--color-primary);color:var(--color-primary)}.rm-vpill__icon{color:currentColor;flex-shrink:0}.rm-vpill__key{color:var(--text-muted);font-weight:var(--weight-normal)}.rm-vpill__value{max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-vpill__pill.has-unsaved{border-color:var(--color-warning)}.rm-vpill__dot{border-radius:50%;flex-shrink:0;height:8px;width:8px}.rm-vpill__dot--applied{animation:rm-vpill-pulse-applied 2s ease-out infinite;background:var(--color-success)}.rm-vpill__dot--unsaved{animation:rm-vpill-pulse 2s ease-out infinite;background:var(--color-warning)}@keyframes rm-vpill-pulse{0%{box-shadow:0 0 0 0 rgba(217,119,6,.6)}70%{box-shadow:0 0 0 6px rgba(217,119,6,0)}to{box-shadow:0 0 0 0 rgba(217,119,6,0)}}@keyframes rm-vpill-pulse-applied{0%{box-shadow:0 0 0 0 rgba(22,163,74,.55)}70%{box-shadow:0 0 0 6px rgba(22,163,74,0)}to{box-shadow:0 0 0 0 rgba(22,163,74,0)}}@media (prefers-reduced-motion:reduce){.rm-vpill__dot,.rm-vpill__unsaved-dot:before{animation:none}}.rm-vpill__caret{color:var(--text-muted);flex-shrink:0}.rm-vpill__menu{background:var(--bg-surface);border:1px solid var(--border-default);border-radius:8px;box-shadow:var(--shadow-lg);box-sizing:border-box;font-family:var(--font-sans);left:0;max-width:460px;min-width:320px;padding:6px;position:absolute;top:calc(100% + 6px);z-index:60}.rm-vpill__unsaved{align-items:center;background:var(--color-warning-bg);border-radius:var(--radius-md);color:var(--color-warning);display:flex;font-size:var(--font-12);gap:8px;padding:8px 12px}.rm-vpill__unsaved-dot{align-items:center;display:inline-flex;flex-shrink:0;height:14px;justify-content:center;width:14px}.rm-vpill__unsaved-dot:before{animation:rm-vpill-pulse 2s ease-out infinite;background:var(--color-warning);border-radius:50%;content:"";height:7px;width:7px}.rm-vpill__unsaved-label{flex:1;font-weight:var(--weight-semibold)}.rm-vpill__unsaved-cta{background:transparent;border:none;color:var(--color-warning);cursor:pointer;font-family:inherit;font-size:inherit;font-weight:var(--weight-bold);padding:0;text-decoration:underline;text-underline-offset:2px}.rm-vpill__unsaved-cta:hover{color:var(--text-primary)}.rm-vpill__divider{background:var(--border-soft);height:1px;margin:6px -6px}.rm-vpill__section{color:var(--text-muted);font-size:var(--font-10);font-weight:var(--weight-bold);letter-spacing:.08em;margin:0;padding:8px 12px 4px 34px;text-align:left;text-transform:uppercase}.rm-vpill__item{align-items:center;background:none;border:none;border-radius:var(--radius-md);color:var(--text-secondary);cursor:pointer;display:flex;font-family:inherit;font-size:var(--font-13);gap:8px;padding:8px 12px;text-align:left;transition:background .1s,color .1s;width:100%}.rm-vpill__item:hover{background:var(--bg-hover);color:var(--text-primary)}.rm-vpill__item.is-active{background:var(--bg-hover);color:var(--color-secondary);font-weight:var(--weight-semibold)}.rm-vpill__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rm-vpill__item--view .rm-vpill__check{color:var(--color-secondary);flex-shrink:0;opacity:0;transition:opacity .1s}.rm-vpill__item--view.is-active .rm-vpill__check{opacity:1}
198
213
  </style>
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Inscrit un panneau. A appeler au montage, cote client seulement : sur le
3
+ * serveur le registre est partage par toutes les requetes et personne ne le
4
+ * vide.
5
+ */
6
+ export declare function rmPanelRegister(close: () => void): () => boolean;
7
+ /** Ferme tous les panneaux sauf celui qui vient de s'ouvrir. */
8
+ export declare function rmPanelOpened(self: () => void): void;
@@ -0,0 +1,10 @@
1
+ const closers = /* @__PURE__ */ new Set();
2
+ export function rmPanelRegister(close) {
3
+ closers.add(close);
4
+ return () => closers.delete(close);
5
+ }
6
+ export function rmPanelOpened(self) {
7
+ closers.forEach((close) => {
8
+ if (close !== self) close();
9
+ });
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekkare/romulus",
3
- "version": "0.1.73",
3
+ "version": "0.1.75",
4
4
  "description": "Romulus Design System - Nuxt module by Tekkare",
5
5
  "license": "MIT",
6
6
  "type": "module",