@shibui-ui/ui 1.25.0 → 1.25.1

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.
Files changed (177) hide show
  1. package/dist/index11.js +1 -1
  2. package/dist/index194.js +97 -6
  3. package/dist/index194.js.map +1 -1
  4. package/dist/index195.js +2 -2
  5. package/dist/index197.js +2 -18
  6. package/dist/index197.js.map +1 -1
  7. package/dist/index198.js +74 -2
  8. package/dist/index198.js.map +1 -1
  9. package/dist/index199.js +64 -74
  10. package/dist/index199.js.map +1 -1
  11. package/dist/index200.js +2 -2
  12. package/dist/index201.js +57 -2
  13. package/dist/index201.js.map +1 -1
  14. package/dist/index202.js +2 -39
  15. package/dist/index202.js.map +1 -1
  16. package/dist/index203.js +2 -2
  17. package/dist/index204.js +144 -219
  18. package/dist/index204.js.map +1 -1
  19. package/dist/index205.js +43 -82
  20. package/dist/index205.js.map +1 -1
  21. package/dist/index206.js +51 -2
  22. package/dist/index206.js.map +1 -1
  23. package/dist/index207.js +2 -94
  24. package/dist/index207.js.map +1 -1
  25. package/dist/index208.js +33 -2
  26. package/dist/index208.js.map +1 -1
  27. package/dist/index209.js +2 -268
  28. package/dist/index209.js.map +1 -1
  29. package/dist/index210.js +6 -2
  30. package/dist/index210.js.map +1 -1
  31. package/dist/index211.js +2 -21
  32. package/dist/index211.js.map +1 -1
  33. package/dist/index212.js +260 -2
  34. package/dist/index212.js.map +1 -1
  35. package/dist/index213.js +16 -8
  36. package/dist/index213.js.map +1 -1
  37. package/dist/index214.js +2 -2
  38. package/dist/index215.js +2 -15
  39. package/dist/index215.js.map +1 -1
  40. package/dist/index216.js +66 -2
  41. package/dist/index216.js.map +1 -1
  42. package/dist/index217.js +24 -146
  43. package/dist/index217.js.map +1 -1
  44. package/dist/index218.js +2 -2
  45. package/dist/index219.js +2 -5
  46. package/dist/index219.js.map +1 -1
  47. package/dist/index220.js +81 -2
  48. package/dist/index220.js.map +1 -1
  49. package/dist/index221.js +78 -6
  50. package/dist/index221.js.map +1 -1
  51. package/dist/index222.js +2 -2
  52. package/dist/index223.js +133 -2
  53. package/dist/index223.js.map +1 -1
  54. package/dist/index224.js +2 -92
  55. package/dist/index224.js.map +1 -1
  56. package/dist/index225.js +2 -59
  57. package/dist/index225.js.map +1 -1
  58. package/dist/index226.js +72 -2
  59. package/dist/index226.js.map +1 -1
  60. package/dist/index227.js +94 -97
  61. package/dist/index227.js.map +1 -1
  62. package/dist/index228.js +2 -2
  63. package/dist/index229.js +71 -2
  64. package/dist/index229.js.map +1 -1
  65. package/dist/index230.js +2 -74
  66. package/dist/index230.js.map +1 -1
  67. package/dist/index231.js +2 -74
  68. package/dist/index231.js.map +1 -1
  69. package/dist/index232.js +12 -2
  70. package/dist/index232.js.map +1 -1
  71. package/dist/index233.js +5 -53
  72. package/dist/index233.js.map +1 -1
  73. package/dist/index234.js +2 -2
  74. package/dist/index235.js +18 -2
  75. package/dist/index235.js.map +1 -1
  76. package/dist/index236.js +2 -162
  77. package/dist/index236.js.map +1 -1
  78. package/dist/index237.js +84 -43
  79. package/dist/index237.js.map +1 -1
  80. package/dist/index238.js +2 -51
  81. package/dist/index238.js.map +1 -1
  82. package/dist/index239.js +2 -2
  83. package/dist/index240.js +39 -33
  84. package/dist/index240.js.map +1 -1
  85. package/dist/index241.js +2 -2
  86. package/dist/index242.js +236 -5
  87. package/dist/index242.js.map +1 -1
  88. package/dist/index243.js +82 -2
  89. package/dist/index243.js.map +1 -1
  90. package/dist/index244.js +2 -260
  91. package/dist/index244.js.map +1 -1
  92. package/dist/index245.js +93 -16
  93. package/dist/index245.js.map +1 -1
  94. package/dist/index246.js +2 -2
  95. package/dist/index247.js +268 -2
  96. package/dist/index247.js.map +1 -1
  97. package/dist/index248.js +2 -66
  98. package/dist/index248.js.map +1 -1
  99. package/dist/index249.js +13 -24
  100. package/dist/index249.js.map +1 -1
  101. package/dist/index250.js +2 -2
  102. package/dist/index251.js +9 -2
  103. package/dist/index251.js.map +1 -1
  104. package/dist/index252.js +2 -81
  105. package/dist/index252.js.map +1 -1
  106. package/dist/index253.js +12 -78
  107. package/dist/index253.js.map +1 -1
  108. package/dist/index254.js +2 -2
  109. package/dist/index255.js +132 -111
  110. package/dist/index255.js.map +1 -1
  111. package/dist/index256.js +2 -2
  112. package/dist/index257.js +5 -2
  113. package/dist/index257.js.map +1 -1
  114. package/dist/index258.js +2 -72
  115. package/dist/index258.js.map +1 -1
  116. package/dist/index259.js +5 -93
  117. package/dist/index259.js.map +1 -1
  118. package/dist/index260.js +2 -2
  119. package/dist/index261.js +2 -71
  120. package/dist/index261.js.map +1 -1
  121. package/dist/index262.js +92 -2
  122. package/dist/index262.js.map +1 -1
  123. package/dist/index263.js +59 -2
  124. package/dist/index263.js.map +1 -1
  125. package/dist/index264.js +2 -12
  126. package/dist/index264.js.map +1 -1
  127. package/dist/index34.js +1 -1
  128. package/dist/index347.js +1 -1
  129. package/dist/index353.js +14 -32
  130. package/dist/index353.js.map +1 -1
  131. package/dist/index354.js +20 -6
  132. package/dist/index354.js.map +1 -1
  133. package/dist/index355.js +56 -18
  134. package/dist/index355.js.map +1 -1
  135. package/dist/index356.js +55 -57
  136. package/dist/index356.js.map +1 -1
  137. package/dist/index357.js +32 -64
  138. package/dist/index357.js.map +1 -1
  139. package/dist/index44.js +1 -1
  140. package/dist/index47.js +1 -1
  141. package/dist/index49.js +2 -2
  142. package/dist/index50.js +2 -2
  143. package/dist/index51.js +2 -2
  144. package/dist/index52.js +2 -2
  145. package/dist/index53.js +3 -3
  146. package/dist/index54.js +2 -2
  147. package/dist/index55.js +2 -2
  148. package/dist/index56.js +3 -3
  149. package/dist/index57.js +2 -2
  150. package/dist/index58.js +2 -2
  151. package/dist/index59.js +2 -2
  152. package/dist/index60.js +2 -2
  153. package/dist/index61.js +2 -2
  154. package/dist/index62.js +2 -2
  155. package/dist/index63.js +2 -2
  156. package/dist/index64.js +2 -2
  157. package/dist/index65.js +2 -2
  158. package/dist/index66.js +1 -1
  159. package/dist/index67.js +1 -1
  160. package/dist/index68.js +2 -2
  161. package/dist/index69.js +2 -2
  162. package/dist/index70.js +2 -2
  163. package/dist/index71.js +2 -2
  164. package/dist/index72.js +2 -2
  165. package/dist/index73.js +2 -2
  166. package/dist/index74.js +2 -2
  167. package/dist/index75.js +2 -2
  168. package/dist/index76.js +2 -2
  169. package/dist/index77.js +2 -2
  170. package/dist/index78.js +2 -2
  171. package/dist/index79.js +2 -2
  172. package/dist/index80.js +2 -2
  173. package/dist/index81.js +2 -2
  174. package/dist/index82.js +1 -1
  175. package/dist/index83.js +2 -2
  176. package/dist/index84.js +2 -2
  177. package/package.json +4 -4
package/dist/index251.js CHANGED
@@ -1,5 +1,12 @@
1
- const modalCss = "@layer tokens,reset,components;@layer reset{*,*:before,*:after{box-sizing:border-box}}@layer components{:host{display:contents}.mo-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-modal, 500);background:#120e0aa6;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:var(--lib-space-lg);overflow-y:auto;opacity:0;pointer-events:none;transition:opacity var(--duration-slow) var(--ease-out)}:host([open]) .mo-backdrop{opacity:1;pointer-events:auto}.mo-panel-wrap{position:relative;width:100%;max-width:560px;max-height:calc(100vh - var(--lib-space-lg) * 2);display:flex;flex-direction:column;transform:scale(.95) translateY(8px);transition:transform var(--duration-slow) var(--ease-out)}:host([open]) .mo-panel-wrap{transform:scale(1) translateY(0)}.mo-panel-wrap.mo-slide-up{transform:translateY(40px)}:host([open]) .mo-panel-wrap.mo-slide-up{transform:translateY(0)}.mo-panel-wrap.mo-slide-down{transform:translateY(-40px)}:host([open]) .mo-panel-wrap.mo-slide-down{transform:translateY(0)}.mo-panel-wrap.mo-xs{max-width:280px}.mo-panel-wrap.mo-sm{max-width:420px}.mo-panel-wrap.mo-lg{max-width:720px}.mo-panel-wrap.mo-xl{max-width:920px}.mo-panel-wrap.mo-full{max-width:100vw;max-height:100vh;height:100vh;margin:0}.mo-panel-wrap.mo-full .mo-panel{max-height:100vh;height:100vh;border:none}.mo-panel{background:var(--bg-elevated);border:1px solid var(--border-default);box-shadow:0 20px 60px #1a140e2e,0 4px 16px #1a140e1a;display:flex;flex-direction:column;max-height:calc(100vh - var(--lib-space-lg) * 2);overflow:hidden}.mo-panel.is-editorial .mo-header{border-bottom:none;padding-bottom:0}.mo-panel.is-editorial .mo-title{font-size:2.5rem;letter-spacing:var(--tracking-tight)}.mo-panel.is-editorial .mo-body{padding-top:var(--lib-space-sm)}.mo-panel.is-danger .mo-header{border-bottom-color:#f5ddd9;background:#f5ddd9}.mo-panel.is-danger .mo-title{color:var(--color-error)}.mo-panel.is-danger .mo-footer{border-top-color:#f5ddd9;background:#fef5f3}.mo-header{display:flex;align-items:flex-start;gap:var(--lib-space-md);padding:var(--lib-space-lg) var(--lib-space-lg) var(--lib-space-md);border-bottom:1px solid var(--border-subtle);flex-shrink:0;background:var(--bg-elevated)}.mo-header-icon{width:40px;height:40px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:20px;background:var(--bg-surface);border:1px solid var(--border-subtle);color:var(--text-muted)}.mo-header-icon.is-kaki{background:var(--color-kaki-50);border-color:var(--color-kaki-100);color:var(--color-kaki-500)}.mo-header-icon.is-celadon{background:var(--color-celadon-50);border-color:var(--color-celadon-100);color:var(--color-celadon-500)}.mo-header-icon.is-error{background:#f5ddd9;border-color:#f5ddd9;color:var(--color-error)}.mo-header-icon.is-info{background:#d6e8f5;border-color:#d6e8f5;color:#1a4a6e}.mo-header-text{flex:1;min-width:0}.mo-title{font-family:var(--lib-font-display);font-size:var(--text-2xl);font-weight:var(--weight-light);letter-spacing:var(--tracking-tight);line-height:var(--leading-tight);color:var(--text-primary)}.mo-subtitle{font-family:var(--lib-font-mono);font-size:var(--text-xs);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--text-muted);margin-top:var(--lib-space-xs)}.mo-close{width:32px;height:32px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:18px;color:var(--text-muted);background:transparent;border:none;cursor:pointer;line-height:1;transition:background var(--duration-fast) var(--ease-default),color var(--duration-fast) var(--ease-default);margin-top:-2px;margin-right:-4px}.mo-close:hover{background:var(--bg-surface);color:var(--text-primary)}.mo-body{flex:1;overflow-y:auto;padding:var(--lib-space-lg);scrollbar-width:thin;scrollbar-color:var(--color-washi-300) transparent}.mo-body::-webkit-scrollbar{width:4px}.mo-body::-webkit-scrollbar-track{background:transparent}.mo-body::-webkit-scrollbar-thumb{background:var(--color-washi-300)}.mo-footer{display:flex;align-items:center;gap:var(--lib-space-md);padding:var(--lib-space-md) var(--lib-space-lg);border-top:1px solid var(--border-subtle);flex-shrink:0;background:var(--bg-surface)}.mo-footer-info{font-family:var(--lib-font-mono);font-size:10px;letter-spacing:var(--tracking-wide);color:var(--text-muted);margin-right:auto}.mo-panel-wrap.mo-dark .mo-panel{background:#0c0604;border-color:#1e130e;box-shadow:0 20px 60px #0000008c,0 4px 16px #0000004d}.mo-panel-wrap.mo-dark .mo-header{background:#0c0604;border-color:#190f0a}.mo-panel-wrap.mo-dark .mo-title{color:#c8bbb2}.mo-panel-wrap.mo-dark .mo-subtitle{color:#312620}.mo-panel-wrap.mo-dark .mo-close{color:#362b25}.mo-panel-wrap.mo-dark .mo-close:hover{background:#190f0a;color:#998c84}.mo-panel-wrap.mo-dark .mo-footer{background:#060201;border-color:#190f0a}.mo-panel-wrap.mo-dark .mo-footer-info{color:#312620}.mo-panel-wrap.mo-dark .mo-header-icon{background:#190f0a;border-color:#231813;color:#433831}@media(max-width:768px){.mo-backdrop{padding:var(--lib-space-md)}.mo-panel-wrap{max-height:calc(100vh - var(--lib-space-md) * 2)}}}";
1
+ import { html } from "lit";
2
+ function parallaxTemplate(_ctx) {
3
+ return html`
4
+ <div class="parallax-wrapper" part="wrapper">
5
+ <slot></slot>
6
+ </div>
7
+ `;
8
+ }
2
9
  export {
3
- modalCss as default
10
+ parallaxTemplate
4
11
  };
5
12
  //# sourceMappingURL=index251.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index251.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index251.js","sources":["../src/components/organisms/parallax-container/lib-parallax.html.ts"],"sourcesContent":["import { html, TemplateResult } from 'lit';\nimport type { LibParallaxContainer } from './lib-parallax.component';\n\n// _ctx disponible para futuras extensiones del template (slot named, etc.)\nexport function parallaxTemplate(_ctx: LibParallaxContainer): TemplateResult {\n return html`\n <div class=\"parallax-wrapper\" part=\"wrapper\">\n <slot></slot>\n </div>\n `;\n}"],"names":[],"mappings":";AAIO,SAAS,iBAAiB,MAA4C;AAC3E,SAAO;AAAA;AAAA;AAAA;AAAA;AAKT;"}
package/dist/index252.js CHANGED
@@ -1,84 +1,5 @@
1
- import { nothing, html } from "lit";
2
- function panelWrapClass(p) {
3
- const classes = ["mo-panel-wrap"];
4
- if (p.size !== "md") classes.push(`mo-${p.size}`);
5
- if (p._animate === "slide-up") classes.push("mo-slide-up");
6
- if (p._animate === "slide-down") classes.push("mo-slide-down");
7
- if (p.dark) classes.push("mo-dark");
8
- return classes.join(" ");
9
- }
10
- function panelClass(variant) {
11
- const classes = ["mo-panel"];
12
- if (variant === "editorial") classes.push("is-editorial");
13
- if (variant === "danger") classes.push("is-danger");
14
- return classes.join(" ");
15
- }
16
- function iconClass(tone) {
17
- const classes = ["mo-header-icon"];
18
- if (tone !== "default") classes.push(`is-${tone}`);
19
- return classes.join(" ");
20
- }
21
- function modalTemplate(p) {
22
- return html`
23
- <div
24
- class="mo-backdrop"
25
- part="backdrop"
26
- @click="${p.onBackdropClick}"
27
- >
28
- <div
29
- class="${panelWrapClass(p)}"
30
- part="panel-wrap"
31
- role="dialog"
32
- aria-modal="true"
33
- aria-labelledby="mo-title"
34
- @click="${(e) => e.stopPropagation()}"
35
- >
36
- <div class="${panelClass(p.variant)}" part="panel">
37
-
38
- <!-- ── HEADER ── -->
39
- <div class="mo-header" part="header">
40
-
41
- <!-- Ícono opcional — tone prop activa el wrapper -->
42
- ${p.iconTone !== null ? html`
43
- <div class="${iconClass(p.iconTone)}" part="icon">
44
- <slot name="icon"></slot>
45
- </div>
46
- ` : nothing}
47
-
48
- <!-- Título y subtítulo -->
49
- <div class="mo-header-text">
50
- <h2 id="mo-title" class="mo-title">${p.heading}</h2>
51
- ${p.subtitle ? html`<p class="mo-subtitle">${p.subtitle}</p>` : nothing}
52
- </div>
53
-
54
- <!-- Botón de cierre -->
55
- <button
56
- class="mo-close"
57
- part="close-btn"
58
- aria-label="Cerrar"
59
- @click="${p.onClose}"
60
- >×</button>
61
- </div>
62
-
63
- <!-- ── BODY — slot default ── -->
64
- <div class="mo-body" part="body">
65
- <slot></slot>
66
- </div>
67
-
68
- <!-- ── FOOTER ── -->
69
- <div class="mo-footer" part="footer">
70
- ${p.footerInfo ? html`
71
- <span class="mo-footer-info">${p.footerInfo}</span>
72
- ` : nothing}
73
- <slot name="footer"></slot>
74
- </div>
75
-
76
- </div>
77
- </div>
78
- </div>
79
- `;
80
- }
1
+ const parallaxCss = "@layer tokens,reset,components;@layer reset{:host{display:block;position:relative;overflow:hidden;width:100%}*,*:before,*:after{box-sizing:border-box}}@layer components{.parallax-wrapper{position:relative;width:100%;height:100%}:host([visible]) ::slotted(*){will-change:transform}@media(prefers-reduced-motion:reduce){::slotted(*){will-change:auto!important;transform:none!important}}}";
81
2
  export {
82
- modalTemplate
3
+ parallaxCss as default
83
4
  };
84
5
  //# sourceMappingURL=index252.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index252.js","sources":["../src/components/molecules/modal/lib-modal.html.ts"],"sourcesContent":["import { html, nothing, TemplateResult } from 'lit';\nimport { ModalAnimate, ModalIconTone, ModalSize, ModalVariant } from './lib-modal.types';\n\nexport interface ModalTemplateProps {\n /* Estado */\n open: boolean;\n /* Panel */\n size: ModalSize;\n variant: ModalVariant;\n _animate: ModalAnimate;\n dark: boolean;\n /* Header */\n heading: string;\n subtitle: string;\n iconTone: ModalIconTone | null;\n /* Footer */\n footerInfo: string;\n /* Handlers */\n onClose: () => void;\n onBackdropClick: (e: MouseEvent) => void;\n}\n\n/** Clases del contenedor del panel (.mo-panel-wrap). */\nfunction panelWrapClass(p: ModalTemplateProps): string {\n const classes = ['mo-panel-wrap'];\n if (p.size !== 'md') classes.push(`mo-${p.size}`);\n if (p._animate === 'slide-up') classes.push('mo-slide-up');\n if (p._animate === 'slide-down') classes.push('mo-slide-down');\n if (p.dark) classes.push('mo-dark');\n return classes.join(' ');\n}\n\n/** Clases del panel (.mo-panel). */\nfunction panelClass(variant: ModalVariant): string {\n const classes = ['mo-panel'];\n if (variant === 'editorial') classes.push('is-editorial');\n if (variant === 'danger') classes.push('is-danger');\n return classes.join(' ');\n}\n\n/** Clases del ícono de header. */\nfunction iconClass(tone: ModalIconTone): string {\n const classes = ['mo-header-icon'];\n if (tone !== 'default') classes.push(`is-${tone}`);\n return classes.join(' ');\n}\n\nexport function modalTemplate(p: ModalTemplateProps): TemplateResult {\n return html`\n <div\n class=\"mo-backdrop\"\n part=\"backdrop\"\n @click=\"${p.onBackdropClick}\"\n >\n <div\n class=\"${panelWrapClass(p)}\"\n part=\"panel-wrap\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"mo-title\"\n @click=\"${(e: MouseEvent):void => e.stopPropagation()}\"\n >\n <div class=\"${panelClass(p.variant)}\" part=\"panel\">\n\n <!-- ── HEADER ── -->\n <div class=\"mo-header\" part=\"header\">\n\n <!-- Ícono opcional — tone prop activa el wrapper -->\n ${p.iconTone !== null ? html`\n <div class=\"${iconClass(p.iconTone)}\" part=\"icon\">\n <slot name=\"icon\"></slot>\n </div>\n ` : nothing}\n\n <!-- Título y subtítulo -->\n <div class=\"mo-header-text\">\n <h2 id=\"mo-title\" class=\"mo-title\">${p.heading}</h2>\n ${p.subtitle ? html`<p class=\"mo-subtitle\">${p.subtitle}</p>` : nothing}\n </div>\n\n <!-- Botón de cierre -->\n <button\n class=\"mo-close\"\n part=\"close-btn\"\n aria-label=\"Cerrar\"\n @click=\"${p.onClose}\"\n >×</button>\n </div>\n\n <!-- ── BODY — slot default ── -->\n <div class=\"mo-body\" part=\"body\">\n <slot></slot>\n </div>\n\n <!-- ── FOOTER ── -->\n <div class=\"mo-footer\" part=\"footer\">\n ${p.footerInfo ? html`\n <span class=\"mo-footer-info\">${p.footerInfo}</span>\n ` : nothing}\n <slot name=\"footer\"></slot>\n </div>\n\n </div>\n </div>\n </div>\n `;\n}"],"names":[],"mappings":";AAuBA,SAAS,eAAe,GAA+B;AACrD,QAAM,UAAU,CAAC,eAAe;AAChC,MAAI,EAAE,SAAS,KAAc,SAAQ,KAAK,MAAM,EAAE,IAAI,EAAE;AACxD,MAAI,EAAE,aAAa,WAAc,SAAQ,KAAK,aAAa;AAC3D,MAAI,EAAE,aAAa,aAAc,SAAQ,KAAK,eAAe;AAC7D,MAAI,EAAE,KAAuB,SAAQ,KAAK,SAAS;AACnD,SAAO,QAAQ,KAAK,GAAG;AACzB;AAGA,SAAS,WAAW,SAA+B;AACjD,QAAM,UAAU,CAAC,UAAU;AAC3B,MAAI,YAAY,YAAa,SAAQ,KAAK,cAAc;AACxD,MAAI,YAAY,SAAa,SAAQ,KAAK,WAAW;AACrD,SAAO,QAAQ,KAAK,GAAG;AACzB;AAGA,SAAS,UAAU,MAA6B;AAC9C,QAAM,UAAU,CAAC,gBAAgB;AACjC,MAAI,SAAS,UAAW,SAAQ,KAAK,MAAM,IAAI,EAAE;AACjD,SAAO,QAAQ,KAAK,GAAG;AACzB;AAEO,SAAS,cAAc,GAAuC;AACnE,SAAO;AAAA;AAAA;AAAA;AAAA,gBAIO,EAAE,eAAe;AAAA;AAAA;AAAA,iBAGhB,eAAe,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKhB,CAAC,MAAuB,EAAE,iBAAiB;AAAA;AAAA,sBAEvC,WAAW,EAAE,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAM7B,EAAE,aAAa,OAAO;AAAA,4BACR,UAAU,EAAE,QAAQ,CAAC;AAAA;AAAA;AAAA,gBAGjC,OAAO;AAAA;AAAA;AAAA;AAAA,mDAI4B,EAAE,OAAO;AAAA,gBAC5C,EAAE,WAAW,8BAA8B,EAAE,QAAQ,SAAS,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAQ7D,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAWnB,EAAE,aAAa;AAAA,6CACgB,EAAE,UAAU;AAAA,gBACzC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQvB;"}
1
+ {"version":3,"file":"index252.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
package/dist/index253.js CHANGED
@@ -1,84 +1,18 @@
1
- import { html, nothing } from "lit";
2
- const chevronLeft = html`
3
- <svg viewBox="0 0 256 256" fill="currentColor" aria-hidden="true">
4
- <path d="M165.66,202.34a8,8,0,0,1-11.32,11.32l-80-80a8,8,0,0,1,0-11.32l80-80a8,8,0,0,1,11.32,11.32L91.31,128Z"/>
5
- </svg>`;
6
- const chevronRight = html`
7
- <svg viewBox="0 0 256 256" fill="currentColor" aria-hidden="true">
8
- <path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"/>
9
- </svg>`;
10
- function buildPageSequence(current, total, siblings) {
11
- if (total <= 1) return [1];
12
- const left = Math.max(2, current - siblings);
13
- const right = Math.min(total - 1, current + siblings);
14
- const pages = [1];
15
- if (left > 2) pages.push(null);
16
- for (let i = left; i <= right; i++) pages.push(i);
17
- if (right < total - 1) pages.push(null);
18
- if (total > 1) pages.push(total);
19
- return pages;
20
- }
21
- function paginationTemplate(ctx) {
22
- const total = ctx.totalPages;
23
- const current = ctx.currentPage;
24
- const sequence = buildPageSequence(current, total, ctx.siblings);
25
- const infoText = ctx.showInfo ? (() => {
26
- const from = (current - 1) * ctx.itemsPerPage + 1;
27
- const to = Math.min(current * ctx.itemsPerPage, ctx.totalItems);
28
- return html`
29
- <span class="pg-info" part="info">
30
- ${from}–${to} de ${ctx.totalItems}
31
- </span>`;
32
- })() : nothing;
1
+ import { html } from "lit";
2
+ function parallaxTextStackTemplate(ctx) {
33
3
  return html`
34
- <nav class="pg" part="root" aria-label="${ctx.ariaLabel}">
35
-
36
- ${ctx.showInfo ? infoText : nothing}
37
-
38
- <!-- Anterior -->
39
- <button
40
- class="pg-btn pg-btn--nav"
41
- part="btn-prev"
42
- ?disabled="${current === 1}"
43
- aria-label="Página anterior"
44
- @click="${() => ctx._changePage(current - 1)}"
45
- >
46
- ${chevronLeft}
47
- ${ctx.size !== "sm" ? html`<span>Ant</span>` : nothing}
48
- </button>
49
-
50
- <!-- Números -->
51
- <div class="pg-numbers" part="numbers" role="list">
52
- ${sequence.map(
53
- (page) => page === null ? html`<span class="pg-ellipsis" role="listitem" aria-hidden="true">…</span>` : html`
54
- <button
55
- class="pg-btn ${page === current ? "pg-btn--active" : ""}"
56
- part="btn-page${page === current ? " btn-page-active" : ""}"
57
- role="listitem"
58
- aria-label="Página ${page}"
59
- aria-current="${page === current ? "page" : nothing}"
60
- ?disabled="${page === current}"
61
- @click="${() => ctx._changePage(page)}"
62
- >${page}</button>`
63
- )}
64
- </div>
65
-
66
- <!-- → Siguiente -->
67
- <button
68
- class="pg-btn pg-btn--nav"
69
- part="btn-next"
70
- ?disabled="${current === total}"
71
- aria-label="Página siguiente"
72
- @click="${() => ctx._changePage(current + 1)}"
73
- >
74
- ${ctx.size !== "sm" ? html`<span>Sig</span>` : nothing}
75
- ${chevronRight}
76
- </button>
77
-
78
- </nav>
4
+ <div class="pts-container" part="container">
5
+ ${ctx.lines.map((line, i) => html`
6
+ <span
7
+ class="pts-layer ${i % 2 === 0 ? "pts-layer--outline" : "pts-layer--italic"}"
8
+ part="layer layer-${i % 2 === 0 ? "outline" : "italic"}"
9
+ aria-hidden="${i > 0}"
10
+ >${line}</span>
11
+ `)}
12
+ </div>
79
13
  `;
80
14
  }
81
15
  export {
82
- paginationTemplate
16
+ parallaxTextStackTemplate
83
17
  };
84
18
  //# sourceMappingURL=index253.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index253.js","sources":["../src/components/molecules/pagination/lib-pagination.html.ts"],"sourcesContent":["import { html, nothing, TemplateResult } from 'lit';\nimport type { LibPagination } from './lib-pagination.component';\n\n/* ── Chevrons inline — sin dependencia de lib-icon ── */\nconst chevronLeft: TemplateResult = html`\n <svg viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M165.66,202.34a8,8,0,0,1-11.32,11.32l-80-80a8,8,0,0,1,0-11.32l80-80a8,8,0,0,1,11.32,11.32L91.31,128Z\"/>\n </svg>`;\n\nconst chevronRight: TemplateResult = html`\n <svg viewBox=\"0 0 256 256\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z\"/>\n </svg>`;\n\n/**\n * Genera la secuencia de páginas con ellipsis.\n *\n * Ejemplo (current=5, total=10, siblings=1):\n * [1] … [4][5][6] … [10]\n *\n * Retorna un array de números o null (null = ellipsis).\n */\nfunction buildPageSequence(current: number, total: number, siblings: number): (number | null)[] {\n if (total <= 1) return [1];\n\n const left = Math.max(2, current - siblings);\n const right = Math.min(total - 1, current + siblings);\n\n const pages: (number | null)[] = [1];\n\n if (left > 2) pages.push(null); // ellipsis izquierdo\n for (let i = left; i <= right; i++) pages.push(i);\n if (right < total - 1) pages.push(null); // ellipsis derecho\n if (total > 1) pages.push(total);\n\n return pages;\n}\n\nexport function paginationTemplate(ctx: LibPagination): TemplateResult {\n const total = ctx.totalPages;\n const current = ctx.currentPage;\n const sequence = buildPageSequence(current, total, ctx.siblings);\n\n /* Info de resultados */\n const infoText = ctx.showInfo\n ? (():TemplateResult => {\n const from = (current - 1) * ctx.itemsPerPage + 1;\n const to = Math.min(current * ctx.itemsPerPage, ctx.totalItems);\n return html`\n <span class=\"pg-info\" part=\"info\">\n ${from}–${to} de ${ctx.totalItems}\n </span>`;\n })()\n : nothing;\n\n return html`\n <nav class=\"pg\" part=\"root\" aria-label=\"${ctx.ariaLabel}\">\n\n ${ctx.showInfo ? infoText : nothing}\n\n <!-- ← Anterior -->\n <button\n class=\"pg-btn pg-btn--nav\"\n part=\"btn-prev\"\n ?disabled=\"${current === 1}\"\n aria-label=\"Página anterior\"\n @click=\"${(): void => ctx._changePage(current - 1)}\"\n >\n ${chevronLeft}\n ${ctx.size !== 'sm' ? html`<span>Ant</span>` : nothing}\n </button>\n\n <!-- Números -->\n <div class=\"pg-numbers\" part=\"numbers\" role=\"list\">\n ${sequence.map((page, /*idx*/) =>\n page === null\n ? html`<span class=\"pg-ellipsis\" role=\"listitem\" aria-hidden=\"true\">…</span>`\n : html`\n <button\n class=\"pg-btn ${page === current ? 'pg-btn--active' : ''}\"\n part=\"btn-page${page === current ? ' btn-page-active' : ''}\"\n role=\"listitem\"\n aria-label=\"Página ${page}\"\n aria-current=\"${page === current ? 'page' : nothing}\"\n ?disabled=\"${page === current}\"\n @click=\"${(): void => ctx._changePage(page as number)}\"\n >${page}</button>`\n )}\n </div>\n\n <!-- → Siguiente -->\n <button\n class=\"pg-btn pg-btn--nav\"\n part=\"btn-next\"\n ?disabled=\"${current === total}\"\n aria-label=\"Página siguiente\"\n @click=\"${(): void => ctx._changePage(current + 1)}\"\n >\n ${ctx.size !== 'sm' ? html`<span>Sig</span>` : nothing}\n ${chevronRight}\n </button>\n\n </nav>\n `;\n}"],"names":[],"mappings":";AAIA,MAAM,cAA8B;AAAA;AAAA;AAAA;AAKpC,MAAM,eAA+B;AAAA;AAAA;AAAA;AAarC,SAAS,kBAAkB,SAAiB,OAAe,UAAqC;AAC9F,MAAI,SAAS,EAAG,QAAO,CAAC,CAAC;AAEzB,QAAM,OAAQ,KAAK,IAAI,GAAG,UAAU,QAAQ;AAC5C,QAAM,QAAQ,KAAK,IAAI,QAAQ,GAAG,UAAU,QAAQ;AAEpD,QAAM,QAA2B,CAAC,CAAC;AAEnC,MAAI,OAAO,EAAU,OAAM,KAAK,IAAI;AACpC,WAAS,IAAI,MAAM,KAAK,OAAO,IAAK,OAAM,KAAK,CAAC;AAChD,MAAI,QAAQ,QAAQ,EAAG,OAAM,KAAK,IAAI;AACtC,MAAI,QAAQ,EAAG,OAAM,KAAK,KAAK;AAE/B,SAAO;AACT;AAEO,SAAS,mBAAmB,KAAoC;AACrE,QAAM,QAAU,IAAI;AACpB,QAAM,UAAU,IAAI;AACpB,QAAM,WAAW,kBAAkB,SAAS,OAAO,IAAI,QAAQ;AAG/D,QAAM,WAAW,IAAI,YAChB,MAAqB;AACpB,UAAM,QAAQ,UAAU,KAAK,IAAI,eAAe;AAChD,UAAM,KAAO,KAAK,IAAI,UAAU,IAAI,cAAc,IAAI,UAAU;AAChE,WAAO;AAAA;AAAA,cAED,IAAI,IAAI,EAAE,OAAO,IAAI,UAAU;AAAA;AAAA,EAEvC,OACA;AAEJ,SAAO;AAAA,8CACqC,IAAI,SAAS;AAAA;AAAA,QAEnD,IAAI,WAAW,WAAW,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAMpB,YAAY,CAAC;AAAA;AAAA,kBAEhB,MAAY,IAAI,YAAY,UAAU,CAAC,CAAC;AAAA;AAAA,UAEhD,WAAW;AAAA,UACX,IAAI,SAAS,OAAO,yBAAyB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,UAKpD,SAAS;AAAA,IAAI,CAAC,SACd,SAAS,OACL,8EACA;AAAA;AAAA,gCAEkB,SAAS,UAAU,mBAAmB,EAAE;AAAA,gCACxC,SAAS,UAAU,qBAAqB,EAAE;AAAA;AAAA,qCAErC,IAAI;AAAA,gCACT,SAAS,UAAU,SAAS,OAAO;AAAA,6BACtC,SAAS,OAAO;AAAA,0BACnB,MAAY,IAAI,YAAY,IAAc,CAAC;AAAA,iBACpD,IAAI;AAAA,EAAA,CACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAOY,YAAY,KAAK;AAAA;AAAA,kBAEpB,MAAY,IAAI,YAAY,UAAU,CAAC,CAAC;AAAA;AAAA,UAEhD,IAAI,SAAS,OAAO,yBAAyB,OAAO;AAAA,UACpD,YAAY;AAAA;AAAA;AAAA;AAAA;AAKtB;"}
1
+ {"version":3,"file":"index253.js","sources":["../src/components/organisms/parallax-text/lib-parallax-text-stack.html.ts"],"sourcesContent":["import { html, TemplateResult } from 'lit';\nimport type { LibParallaxTextStack } from './lib-parallax-text-stack.component';\n\nexport function parallaxTextStackTemplate(ctx: LibParallaxTextStack): TemplateResult {\n return html`\n <div class=\"pts-container\" part=\"container\">\n ${ctx.lines.map((line, i) => html`\n <span\n class=\"pts-layer ${i % 2 === 0 ? 'pts-layer--outline' : 'pts-layer--italic'}\"\n part=\"layer layer-${i % 2 === 0 ? 'outline' : 'italic'}\"\n aria-hidden=\"${i > 0}\"\n >${line}</span>\n `)}\n </div>\n `;\n}"],"names":[],"mappings":";AAGO,SAAS,0BAA0B,KAA2C;AACnF,SAAO;AAAA;AAAA,QAED,IAAI,MAAM,IAAI,CAAC,MAAM,MAAM;AAAA;AAAA,6BAEN,IAAI,MAAM,IAAI,uBAAuB,mBAAmB;AAAA,8BACvD,IAAI,MAAM,IAAI,YAAY,QAAQ;AAAA,yBACvC,IAAI,CAAC;AAAA,WACnB,IAAI;AAAA,OACR,CAAC;AAAA;AAAA;AAGR;"}
package/dist/index254.js CHANGED
@@ -1,5 +1,5 @@
1
- const paginationCss = '@layer tokens,reset,components;@layer reset{:host{display:block}*,*:before,*:after{box-sizing:border-box}button{font:inherit;background:none;border:none;padding:0;margin:0;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}}@layer components{.pg{display:flex;align-items:center;justify-content:center;gap:var(--lib-space-sm);flex-wrap:wrap}.pg-numbers{display:flex;align-items:center;gap:var(--lib-space-xs)}.pg-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--lib-space-xs);font-family:var(--lib-font-mono);font-size:var(--text-xs);letter-spacing:var(--tracking-wide);color:var(--text-secondary);background:var(--bg-elevated);border:1px solid var(--border-default);min-width:var(--_pg-size, 32px);height:var(--_pg-size, 32px);padding:0 var(--lib-space-sm);white-space:nowrap;-webkit-user-select:none;user-select:none;transition:background var(--duration-base) var(--ease-out),border-color var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.pg-btn:hover:not(:disabled,.pg-btn--active){background:var(--bg-surface);border-color:var(--border-strong);color:var(--text-primary)}.pg-btn:focus-visible{outline:2px solid var(--color-kaki-400);outline-offset:2px}.pg-btn:active:not(:disabled){transform:scale(.96)}.pg-btn--active{background:var(--color-washi-900);border-color:var(--color-washi-900);color:var(--color-washi-50);cursor:default}.pg-btn:disabled{opacity:.35;cursor:not-allowed}.pg-btn--nav{padding:0 var(--lib-space-md)}.pg-btn--nav svg{width:10px;height:10px;flex-shrink:0}.pg-ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:var(--_pg-size, 32px);height:var(--_pg-size, 32px);font-family:var(--lib-font-mono);font-size:var(--text-xs);letter-spacing:var(--tracking-wide);color:var(--text-muted);-webkit-user-select:none;user-select:none}:host([size="sm"]){--_pg-size: 26px}:host([size="sm"]) .pg-btn{font-size:10px;padding:0 var(--lib-space-xs)}:host([size="sm"]) .pg-btn--nav{padding:0 var(--lib-space-sm)}:host([size="sm"]) .pg-ellipsis{font-size:10px}:host([size="md"]){--_pg-size: 32px}:host([size="lg"]){--_pg-size: 40px}:host([size="lg"]) .pg-btn{font-size:var(--text-sm);letter-spacing:var(--tracking-wider);padding:0 var(--lib-space-md)}:host([size="lg"]) .pg-btn--nav{padding:0 calc(var(--lib-space-md) + var(--lib-space-xs))}:host([variant="outline"]) .pg-btn{background:transparent}:host([variant="outline"]) .pg-btn:hover:not(:disabled,.pg-btn--active){background:var(--bg-surface)}:host([variant="outline"]) .pg-btn--active{background:transparent;border-color:var(--color-washi-900);color:var(--color-washi-900)}:host([variant="ghost"]) .pg-btn{background:transparent;border-color:transparent}:host([variant="ghost"]) .pg-btn:hover:not(:disabled,.pg-btn--active){background:var(--bg-surface);border-color:transparent}:host([variant="ghost"]) .pg-btn--active{background:var(--bg-surface);border-color:transparent;color:var(--text-primary);font-weight:500}.pg-info{font-family:var(--lib-font-mono);font-size:var(--text-xs);letter-spacing:var(--tracking-wide);color:var(--text-muted);white-space:nowrap}:host([dark]) .pg-btn{background:var(--color-washi-800);border-color:var(--color-washi-700);color:var(--color-washi-400)}:host([dark]) .pg-btn:hover:not(:disabled,.pg-btn--active){background:var(--color-washi-700);border-color:var(--color-washi-600);color:var(--color-washi-100)}:host([dark]) .pg-btn--active{background:var(--color-washi-50);border-color:var(--color-washi-50);color:var(--color-washi-950)}:host([dark]) .pg-ellipsis{color:var(--color-washi-600)}:host([dark]) .pg-info{color:var(--color-washi-600)}}';
1
+ const stackCss = '@layer tokens,reset,components;@layer reset{:host{display:block;padding:10vh 0}*,*:before,*:after{box-sizing:border-box}}@layer components{.pts-container{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--lib-space-md)}.pts-layer{display:block;will-change:transform;transition:transform var(--duration-fast) var(--ease-out);white-space:nowrap;line-height:.9;text-transform:uppercase;-webkit-user-select:none;user-select:none}:host([size="sm"]) .pts-layer{font-size:clamp(2rem,6vw,4rem)}:host([size="md"]) .pts-layer{font-size:clamp(3rem,8vw,6rem)}:host([size="lg"]) .pts-layer,:host(:not([size])) .pts-layer{font-size:clamp(4rem,10vw,8rem)}:host([size="xl"]) .pts-layer{font-size:clamp(5rem,13vw,10rem)}:host([size="2xl"]) .pts-layer{font-size:clamp(6rem,16vw,14rem)}.pts-layer--outline{font-family:var(--lib-font-display);font-weight:300;letter-spacing:var(--tracking-tight);-webkit-text-stroke:1px var(--text-primary);color:transparent}.pts-layer--italic{font-family:var(--lib-font-body);font-style:italic;font-weight:400;letter-spacing:var(--tracking-tight);color:var(--text-primary)}:host([color="muted"]) .pts-layer--outline{-webkit-text-stroke-color:var(--text-muted)}:host([color="muted"]) .pts-layer--italic{color:var(--text-muted)}:host([color="kaki"]) .pts-layer--outline{-webkit-text-stroke-color:var(--color-kaki-500)}:host([color="kaki"]) .pts-layer--italic{color:var(--color-kaki-500)}:host([color="celadon"]) .pts-layer--outline{-webkit-text-stroke-color:var(--color-celadon-500)}:host([color="celadon"]) .pts-layer--italic{color:var(--color-celadon-500)}@media(prefers-reduced-motion:reduce){.pts-layer{transition:none;transform:none!important}}}';
2
2
  export {
3
- paginationCss as default
3
+ stackCss as default
4
4
  };
5
5
  //# sourceMappingURL=index254.js.map
package/dist/index255.js CHANGED
@@ -1,136 +1,157 @@
1
- import { nothing, html } from "lit";
2
- function renderValue(v, unit) {
3
- return html`${v}${unit ? html`<span class="rs-value-unit">${unit}</span>` : nothing}`;
1
+ import { html, nothing } from "lit";
2
+ const svgSearch = html`
3
+ <svg width="11" height="11" viewBox="0 0 16 16" fill="none"
4
+ stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
5
+ <circle cx="7" cy="7" r="5"/><line x1="11" y1="11" x2="14" y2="14"/>
6
+ </svg>`;
7
+ const svgLogout = html`
8
+ <svg width="11" height="11" viewBox="0 0 14 14" fill="none"
9
+ stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
10
+ <path d="M6 2H3a1 1 0 00-1 1v8a1 1 0 001 1h3"/>
11
+ <polyline points="10,4 12,7 10,10"/>
12
+ <line x1="4" y1="7" x2="12" y2="7"/>
13
+ </svg>`;
14
+ const svgMenu = html`
15
+ <svg width="18" height="18" viewBox="0 0 16 16" fill="none"
16
+ stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
17
+ <line x1="2" y1="4" x2="14" y2="4"/>
18
+ <line x1="2" y1="8" x2="14" y2="8"/>
19
+ <line x1="2" y1="12" x2="14" y2="12"/>
20
+ </svg>`;
21
+ const svgClose = html`
22
+ <svg width="18" height="18" viewBox="0 0 14 14" fill="none"
23
+ stroke="currentColor" stroke-width="1.6" stroke-linecap="round">
24
+ <line x1="2" y1="2" x2="12" y2="12"/>
25
+ <line x1="12" y1="2" x2="2" y2="12"/>
26
+ </svg>`;
27
+ function renderBadge(badge) {
28
+ if (badge === void 0 || badge === null || badge === "") return nothing;
29
+ if (badge === "dot") {
30
+ return html`<span class="sb-badge sb-badge--dot" aria-hidden="true"></span>`;
31
+ }
32
+ const n = typeof badge === "number" ? badge : parseInt(String(badge), 10);
33
+ const cls = !isNaN(n) && n > 9 || isNaN(n) ? "sb-badge--kaki" : "sb-badge--muted";
34
+ return html`<span class="sb-badge ${cls}">${badge}</span>`;
4
35
  }
5
- function renderMarks(marks, pct) {
6
- if (!marks.length) return html``;
36
+ function renderHeader(p) {
37
+ const isGlitch = p.variant === "glitch";
38
+ const isKintsugi = p.variant === "kintsugi";
7
39
  return html`
8
- <div class="rs-marks">
9
- ${marks.map((m) => html`
10
- <div
11
- class="rs-mark ${m.pct <= pct ? "is-filled" : ""}"
12
- style="left: ${m.pct}%"
13
- >
14
- ${m.label ? html`<span class="rs-mark-label">${m.label}</span>` : nothing}
15
- </div>
16
- `)}
40
+ <div class="sb-header" part="header">
41
+ <div class="sb-logo-mark" part="logo-mark">
42
+ ${isKintsugi ? html`<span>${p.logoMark}</span>` : p.logoMark}
43
+ </div>
44
+ ${isGlitch ? html`<span class="sb-brand">⌗ ${p.brandName.toUpperCase()}</span>
45
+ <span class="sb-version">v0.1</span>` : html`<span class="sb-brand">${p.brandName}</span>`}
17
46
  </div>
18
47
  `;
19
48
  }
20
- function renderLimits(show, low, high) {
21
- if (!show) return html``;
49
+ function renderSearch(p) {
50
+ if (!p.showSearch) return nothing;
22
51
  return html`
23
- <div class="rs-limits">
24
- <span class="rs-limit">${low}</span>
25
- <span class="rs-limit">${high}</span>
52
+ <div class="sb-search" part="search">
53
+ <div class="sb-search-inner">
54
+ ${svgSearch}
55
+ <input
56
+ class="sb-search-input"
57
+ type="search"
58
+ placeholder="${p.searchPlaceholder}"
59
+ aria-label="Buscar"
60
+ @input="${(e) => p.onSearchInput(e.target.value)}"
61
+ />
62
+ <span class="sb-search-kbd">⌘K</span>
63
+ </div>
26
64
  </div>
27
65
  `;
28
66
  }
29
- function renderTooltip(show, pct, value, unit) {
30
- if (!show) return html``;
67
+ function renderNav(p) {
68
+ const isGlitch = p.variant === "glitch";
31
69
  return html`
32
- <div class="rs-tooltip-wrap" style="left: ${pct}%">
33
- <span class="rs-tooltip-bubble">${value}${unit}</span>
34
- </div>
70
+ <nav class="sb-nav" part="nav" aria-label="Navegación principal">
71
+ <div class="sb-indicator" part="indicator"></div>
72
+
73
+ ${p.links.map((link) => html`
74
+ ${link.group ? html`
75
+ <div class="sb-group" part="group">
76
+ ${isGlitch ? `// ${link.group}` : link.group}
77
+ </div>
78
+ ` : nothing}
79
+
80
+ <button
81
+ class="sb-link ${link.id === p.active ? "is-active" : ""}"
82
+ part="link${link.id === p.active ? " link-active" : ""}"
83
+ data-id="${link.id}"
84
+ ?disabled="${link.disabled}"
85
+ aria-current="${link.id === p.active ? "page" : nothing}"
86
+ @click="${() => {
87
+ if (!link.disabled) p.onLinkClick(link.id);
88
+ }}"
89
+ >
90
+ <span class="sb-link-icon">
91
+ <lib-icon name="${link.icon}" size="sm"></lib-icon>
92
+ </span>
93
+
94
+ ${isGlitch ? html`<span class="sb-link-prefix">›</span>` : nothing}
95
+
96
+ <span class="sb-link-label">${link.label}</span>
97
+
98
+ ${renderBadge(link.badge)}
99
+ </button>
100
+ `)}
101
+ </nav>
35
102
  `;
36
103
  }
37
- function renderTrack(p) {
38
- if (p.dual) {
39
- return html`
40
- <div class="rs-track-wrap">
41
- <div class="rs-track">
42
- <div
43
- class="rs-fill-dual"
44
- style="left: ${p.minPct}%; right: ${100 - p.maxPct}%"
45
- ></div>
46
- </div>
47
- <input
48
- type="range"
49
- class="rs-input-min"
50
- min=${p.min} max=${p.max} step=${p.step}
51
- .value=${String(p.valueMin)}
52
- ?disabled=${p.disabled}
53
- aria-label="Mínimo"
54
- @input=${p.onInputMin}
55
- >
56
- <input
57
- type="range"
58
- class="rs-input-max"
59
- min=${p.min} max=${p.max} step=${p.step}
60
- .value=${String(p.valueMax)}
61
- ?disabled=${p.disabled}
62
- aria-label="Máximo"
63
- @input=${p.onInputMax}
64
- >
65
- </div>
66
- `;
67
- }
68
- if (p.vertical) {
69
- return html`
70
- <div class="rs-vert-wrap">
71
- <div class="rs-track-wrap">
72
- <div class="rs-track">
73
- <div class="rs-fill" style="width: ${p.pct}%"></div>
74
- </div>
75
- <input
76
- type="range"
77
- min=${p.min} max=${p.max} step=${p.step}
78
- .value=${String(p.value)}
79
- ?disabled=${p.disabled}
80
- @input=${p.onInput}
81
- >
82
- </div>
83
- </div>
84
- `;
85
- }
104
+ function renderUser(p) {
105
+ const isDark = p.variant === "dark" || !p.variant;
86
106
  return html`
87
- <div class="rs-track-wrap">
88
- <div class="rs-track">
89
- <div class="rs-fill" style="width: ${p.pct}%"></div>
107
+ <div class="sb-user" part="user">
108
+ <div class="sb-user-avatar" part="user-avatar">
109
+ ${p.userAvatar ? html`<img src="${p.userAvatar}" alt="${p.userName}">` : p.userInitials || p.userName.slice(0, 1)}
90
110
  </div>
91
- <input
92
- type="range"
93
- min=${p.min} max=${p.max} step=${p.step}
94
- .value=${String(p.value)}
95
- ?disabled=${p.disabled}
96
- @input=${p.onInput}
97
- >
98
- ${renderTooltip(p.tooltip, p.pct, p.value, p.unit)}
111
+
112
+ <div class="sb-user-info">
113
+ <div class="sb-user-name">${p.userName}</div>
114
+ ${p.userRole ? html`<div class="sb-user-role">${p.userRole}</div>` : nothing}
115
+ </div>
116
+
117
+ ${isDark ? html`<span class="sb-user-dot" aria-hidden="true"></span>` : p.showUserAction ? html`
118
+ <button
119
+ class="sb-user-action"
120
+ aria-label="Acción de usuario"
121
+ @click="${p.onUserAction}"
122
+ >${svgLogout}</button>` : nothing}
99
123
  </div>
100
124
  `;
101
125
  }
102
- function rangeSliderTemplate(p) {
103
- const valueDisplay = p.dual ? html`<span class="rs-value">
104
- ${p.valueMin} — ${p.valueMax}
105
- ${p.unit ? html`<span class="rs-value-unit">${p.unit}</span>` : nothing}
106
- </span>` : html`<span class="rs-value">${renderValue(p.value, p.unit)}</span>`;
126
+ function sidebarTemplate(p) {
107
127
  return html`
108
- <div class="rs">
109
-
110
- ${!p.vertical && (p.label || p.dual) ? html`
111
- <div class="rs-label-row">
112
- ${p.label ? html`<span class="rs-label">${p.label}</span>` : nothing}
113
- ${valueDisplay}
114
- </div>
115
- ` : nothing}
128
+ <div
129
+ class="sb-overlay ${p.mobileOpen ? "is-open" : ""}"
130
+ @click="${p.onOverlayClick}"
131
+ aria-hidden="true"
132
+ ></div>
116
133
 
117
- ${renderTrack(p)}
134
+ <aside
135
+ class="sidebar
136
+ ${p.mobileOpen ? "is-open" : ""}
137
+ ${p.collapsed ? "is-collapsed" : ""}"
138
+ part="sidebar"
139
+ >
140
+ ${renderHeader(p)}
141
+ ${renderSearch(p)}
142
+ ${renderNav(p)}
143
+ ${renderUser(p)}
144
+ </aside>
118
145
 
119
- ${p.vertical ? html`
120
- <div class="rs-label-row">
121
- ${p.label ? html`<span class="rs-label">${p.label}</span>` : nothing}
122
- ${valueDisplay}
123
- </div>
124
- ` : nothing}
125
-
126
- ${renderMarks(p.marks, p.pct)}
127
-
128
- ${renderLimits(p.showLimits, p.limitMinText, p.limitMaxText)}
129
-
130
- </div>
146
+ <button
147
+ class="sb-toggle"
148
+ aria-label="${p.mobileOpen ? "Cerrar menú" : "Abrir menú"}"
149
+ aria-expanded="${p.mobileOpen}"
150
+ @click="${p.onToggleClick}"
151
+ >${p.mobileOpen ? svgClose : svgMenu}</button>
131
152
  `;
132
153
  }
133
154
  export {
134
- rangeSliderTemplate
155
+ sidebarTemplate
135
156
  };
136
157
  //# sourceMappingURL=index255.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index255.js","sources":["../src/components/molecules/range-slider/lib-range-slider.html.ts"],"sourcesContent":["import { html, nothing, TemplateResult } from 'lit';\nimport type { RsSize, RsTone, RsMark } from './lib-range-slider.component';\n\nexport interface RangeSliderTemplateProps {\n /* sizing / modes */\n size: RsSize;\n tone: RsTone;\n dual: boolean;\n vertical: boolean;\n disabled: boolean;\n tooltip: boolean;\n\n /* range attrs */\n min: number;\n max: number;\n step: number;\n\n /* values */\n value: number; // single mode\n valueMin: number; // dual low\n valueMax: number; // dual high\n\n /* computed pcts (0–100) */\n pct: number; // single fill\n minPct: number; // dual fill left\n maxPct: number; // dual fill right\n\n /* display */\n label: string;\n unit: string;\n showLimits: boolean;\n limitMinText: string;\n limitMaxText: string;\n marks: RsMark[];\n\n /* handlers */\n onInput: (e: Event) => void;\n onInputMin: (e: Event) => void;\n onInputMax: (e: Event) => void;\n}\n\n/* ── Value display ───────────────────────────────────────── */\nfunction renderValue(v: number | string, unit: string): TemplateResult {\n return html`${v}${unit ? html`<span class=\"rs-value-unit\">${unit}</span>` : nothing}`;\n}\n\n/* ── Marks ───────────────────────────────────────────────── */\nfunction renderMarks(marks: RsMark[], pct: number): TemplateResult {\n if (!marks.length) return html``;\n return html`\n <div class=\"rs-marks\">\n ${marks.map(m => html`\n <div\n class=\"rs-mark ${m.pct <= pct ? 'is-filled' : ''}\"\n style=\"left: ${m.pct}%\"\n >\n ${m.label ? html`<span class=\"rs-mark-label\">${m.label}</span>` : nothing}\n </div>\n `)}\n </div>\n `;\n}\n\n/* ── Limits ──────────────────────────────────────────────── */\nfunction renderLimits(show: boolean, low: string, high: string): TemplateResult {\n if (!show) return html``;\n return html`\n <div class=\"rs-limits\">\n <span class=\"rs-limit\">${low}</span>\n <span class=\"rs-limit\">${high}</span>\n </div>\n `;\n}\n\n/* ── Tooltip ─────────────────────────────────────────────── */\nfunction renderTooltip(show: boolean, pct: number, value: number, unit: string): TemplateResult {\n if (!show) return html``;\n return html`\n <div class=\"rs-tooltip-wrap\" style=\"left: ${pct}%\">\n <span class=\"rs-tooltip-bubble\">${value}${unit}</span>\n </div>\n `;\n}\n\n/* ── Track content ───────────────────────────────────────── */\nfunction renderTrack(p: RangeSliderTemplateProps): TemplateResult {\n if (p.dual) {\n return html`\n <div class=\"rs-track-wrap\">\n <div class=\"rs-track\">\n <div\n class=\"rs-fill-dual\"\n style=\"left: ${p.minPct}%; right: ${100 - p.maxPct}%\"\n ></div>\n </div>\n <input\n type=\"range\"\n class=\"rs-input-min\"\n min=${p.min} max=${p.max} step=${p.step}\n .value=${String(p.valueMin)}\n ?disabled=${p.disabled}\n aria-label=\"Mínimo\"\n @input=${p.onInputMin}\n >\n <input\n type=\"range\"\n class=\"rs-input-max\"\n min=${p.min} max=${p.max} step=${p.step}\n .value=${String(p.valueMax)}\n ?disabled=${p.disabled}\n aria-label=\"Máximo\"\n @input=${p.onInputMax}\n >\n </div>\n `;\n }\n\n if (p.vertical) {\n return html`\n <div class=\"rs-vert-wrap\">\n <div class=\"rs-track-wrap\">\n <div class=\"rs-track\">\n <div class=\"rs-fill\" style=\"width: ${p.pct}%\"></div>\n </div>\n <input\n type=\"range\"\n min=${p.min} max=${p.max} step=${p.step}\n .value=${String(p.value)}\n ?disabled=${p.disabled}\n @input=${p.onInput}\n >\n </div>\n </div>\n `;\n }\n\n /* single horizontal */\n return html`\n <div class=\"rs-track-wrap\">\n <div class=\"rs-track\">\n <div class=\"rs-fill\" style=\"width: ${p.pct}%\"></div>\n </div>\n <input\n type=\"range\"\n min=${p.min} max=${p.max} step=${p.step}\n .value=${String(p.value)}\n ?disabled=${p.disabled}\n @input=${p.onInput}\n >\n ${renderTooltip(p.tooltip, p.pct, p.value, p.unit)}\n </div>\n `;\n}\n\n/**\n * Template principal de lib-range-slider.\n */\nexport function rangeSliderTemplate(p: RangeSliderTemplateProps): TemplateResult {\n /* Dual value display: \"120 — 480 €\" */\n const valueDisplay = p.dual\n ? html`<span class=\"rs-value\">\n ${p.valueMin} ${p.valueMax}\n ${p.unit ? html`<span class=\"rs-value-unit\">${p.unit}</span>` : nothing}\n </span>`\n : html`<span class=\"rs-value\">${renderValue(p.value, p.unit)}</span>`;\n\n return html`\n <div class=\"rs\">\n\n ${!p.vertical && (p.label || p.dual) ? html`\n <div class=\"rs-label-row\">\n ${p.label ? html`<span class=\"rs-label\">${p.label}</span>` : nothing}\n ${valueDisplay}\n </div>\n ` : nothing}\n\n ${renderTrack(p)}\n\n ${p.vertical ? html`\n <div class=\"rs-label-row\">\n ${p.label ? html`<span class=\"rs-label\">${p.label}</span>` : nothing}\n ${valueDisplay}\n </div>\n ` : nothing}\n\n ${renderMarks(p.marks, p.pct)}\n\n ${renderLimits(p.showLimits, p.limitMinText, p.limitMaxText)}\n\n </div>\n `;\n}"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index255.js","sources":["../src/components/organisms/sidebar/lib-sidebar.html.ts"],"sourcesContent":["import { html, nothing, TemplateResult } from 'lit';\nimport type { SidebarLink } from '../../../types';\n\nexport interface SidebarTemplateProps {\n /* Header */\n logoMark: string;\n brandName: string;\n /* Search */\n showSearch: boolean;\n searchPlaceholder: string;\n /* Nav */\n links: SidebarLink[];\n active: string;\n /* User footer */\n userName: string;\n userRole: string;\n userAvatar: string;\n userInitials:string;\n showUserAction: boolean;\n /* State */\n variant: string;\n collapsed: boolean;\n mobileOpen: boolean;\n /* Handlers */\n onLinkClick: (id: string) => void;\n onUserAction: () => void;\n onSearchInput: (q: string) => void;\n onOverlayClick: () => void;\n onToggleClick: () => void;\n}\n\n/* ── SVG icons inline — no lib-icon dependency for shell elements ── */\nconst svgSearch = html`\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 16 16\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\">\n <circle cx=\"7\" cy=\"7\" r=\"5\"/><line x1=\"11\" y1=\"11\" x2=\"14\" y2=\"14\"/>\n </svg>`;\n\nconst svgLogout = html`\n <svg width=\"11\" height=\"11\" viewBox=\"0 0 14 14\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\">\n <path d=\"M6 2H3a1 1 0 00-1 1v8a1 1 0 001 1h3\"/>\n <polyline points=\"10,4 12,7 10,10\"/>\n <line x1=\"4\" y1=\"7\" x2=\"12\" y2=\"7\"/>\n </svg>`;\n\nconst svgMenu = html`\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\">\n <line x1=\"2\" y1=\"4\" x2=\"14\" y2=\"4\"/>\n <line x1=\"2\" y1=\"8\" x2=\"14\" y2=\"8\"/>\n <line x1=\"2\" y1=\"12\" x2=\"14\" y2=\"12\"/>\n </svg>`;\n\nconst svgClose = html`\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 14 14\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\">\n <line x1=\"2\" y1=\"2\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"2\" x2=\"2\" y2=\"12\"/>\n </svg>`;\n\n/* ── Badge ── */\nfunction renderBadge(badge: string | number | undefined): TemplateResult | typeof nothing {\n if (badge === undefined || badge === null || badge === '') return nothing;\n if (badge === 'dot') {\n return html`<span class=\"sb-badge sb-badge--dot\" aria-hidden=\"true\"></span>`;\n }\n const n = typeof badge === 'number' ? badge : parseInt(String(badge), 10);\n const cls = (!isNaN(n) && n > 9) || isNaN(n) ? 'sb-badge--kaki' : 'sb-badge--muted';\n return html`<span class=\"sb-badge ${cls}\">${badge}</span>`;\n}\n\n/* ── Header ── */\nfunction renderHeader(p: SidebarTemplateProps): TemplateResult {\n const isGlitch = p.variant === 'glitch';\n const isKintsugi = p.variant === 'kintsugi';\n\n return html`\n <div class=\"sb-header\" part=\"header\">\n <div class=\"sb-logo-mark\" part=\"logo-mark\">\n ${isKintsugi\n ? html`<span>${p.logoMark}</span>`\n : p.logoMark}\n </div>\n ${isGlitch\n ? html`<span class=\"sb-brand\">⌗ ${p.brandName.toUpperCase()}</span>\n <span class=\"sb-version\">v0.1</span>`\n : html`<span class=\"sb-brand\">${p.brandName}</span>`}\n </div>\n `;\n}\n\n/* ── Search ── */\nfunction renderSearch(p: SidebarTemplateProps): TemplateResult | typeof nothing {\n if (!p.showSearch) return nothing;\n return html`\n <div class=\"sb-search\" part=\"search\">\n <div class=\"sb-search-inner\">\n ${svgSearch}\n <input\n class=\"sb-search-input\"\n type=\"search\"\n placeholder=\"${p.searchPlaceholder}\"\n aria-label=\"Buscar\"\n @input=\"${(e: Event): void =>\n p.onSearchInput((e.target as HTMLInputElement).value)}\"\n />\n <span class=\"sb-search-kbd\">⌘K</span>\n </div>\n </div>\n `;\n}\n\n/* ── Nav ── */\nfunction renderNav(p: SidebarTemplateProps): TemplateResult {\n const isGlitch = p.variant === 'glitch';\n\n return html`\n <nav class=\"sb-nav\" part=\"nav\" aria-label=\"Navegación principal\">\n <div class=\"sb-indicator\" part=\"indicator\"></div>\n\n ${p.links.map(link => html`\n ${link.group ? html`\n <div class=\"sb-group\" part=\"group\">\n ${isGlitch ? `// ${link.group}` : link.group}\n </div>\n ` : nothing}\n\n <button\n class=\"sb-link ${link.id === p.active ? 'is-active' : ''}\"\n part=\"link${link.id === p.active ? ' link-active' : ''}\"\n data-id=\"${link.id}\"\n ?disabled=\"${link.disabled}\"\n aria-current=\"${link.id === p.active ? 'page' : nothing}\"\n @click=\"${(): void => { if (!link.disabled) p.onLinkClick(link.id); }}\"\n >\n <span class=\"sb-link-icon\">\n <lib-icon name=\"${link.icon}\" size=\"sm\"></lib-icon>\n </span>\n\n ${isGlitch\n ? html`<span class=\"sb-link-prefix\">›</span>`\n : nothing}\n\n <span class=\"sb-link-label\">${link.label}</span>\n\n ${renderBadge(link.badge)}\n </button>\n `)}\n </nav>\n `;\n}\n\n/* ── User footer ── */\nfunction renderUser(p: SidebarTemplateProps): TemplateResult {\n const isDark = p.variant === 'dark' || !p.variant;\n\n return html`\n <div class=\"sb-user\" part=\"user\">\n <div class=\"sb-user-avatar\" part=\"user-avatar\">\n ${p.userAvatar\n ? html`<img src=\"${p.userAvatar}\" alt=\"${p.userName}\">`\n : p.userInitials || p.userName.slice(0, 1)}\n </div>\n\n <div class=\"sb-user-info\">\n <div class=\"sb-user-name\">${p.userName}</div>\n ${p.userRole ? html`<div class=\"sb-user-role\">${p.userRole}</div>` : nothing}\n </div>\n\n ${isDark\n ? html`<span class=\"sb-user-dot\" aria-hidden=\"true\"></span>`\n : p.showUserAction\n ? html`\n <button\n class=\"sb-user-action\"\n aria-label=\"Acción de usuario\"\n @click=\"${p.onUserAction}\"\n >${svgLogout}</button>`\n : nothing}\n </div>\n `;\n}\n\n/* ── Template principal ── */\nexport function sidebarTemplate(p: SidebarTemplateProps): TemplateResult {\n return html`\n <div\n class=\"sb-overlay ${p.mobileOpen ? 'is-open' : ''}\"\n @click=\"${p.onOverlayClick}\"\n aria-hidden=\"true\"\n ></div>\n\n <aside\n class=\"sidebar\n ${p.mobileOpen ? 'is-open' : ''}\n ${p.collapsed ? 'is-collapsed' : ''}\"\n part=\"sidebar\"\n >\n ${renderHeader(p)}\n ${renderSearch(p)}\n ${renderNav(p)}\n ${renderUser(p)}\n </aside>\n\n <button\n class=\"sb-toggle\"\n aria-label=\"${p.mobileOpen ? 'Cerrar menú' : 'Abrir menú'}\"\n aria-expanded=\"${p.mobileOpen}\"\n @click=\"${p.onToggleClick}\"\n >${p.mobileOpen ? svgClose : svgMenu}</button>\n `;\n}"],"names":[],"mappings":"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"}