@r2digisolutions/components 0.16.0 → 0.16.2

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.
@@ -10,6 +10,8 @@
10
10
  align?: PopoverAlign;
11
11
  strategy?: 'fixed' | 'absolute';
12
12
  offset?: number;
13
+ /** Solo ancla/posiciona; sin fondo, borde ni padding (el contenido aporta el chrome). */
14
+ unstyled?: boolean;
13
15
  class?: string;
14
16
  panelClass?: string;
15
17
  trigger?: Snippet;
@@ -23,6 +25,7 @@
23
25
  align = 'center',
24
26
  strategy = 'fixed',
25
27
  offset = 8,
28
+ unstyled = false,
26
29
  class: className = '',
27
30
  panelClass = '',
28
31
  trigger,
@@ -83,8 +86,8 @@
83
86
  const viewTop = vv?.offsetTop ?? 0;
84
87
  const pad = 8;
85
88
 
86
- const panelW = Math.max(panelEl.offsetWidth, 280);
87
- const panelH = Math.max(panelEl.offsetHeight, 120);
89
+ const panelW = Math.max(panelEl.offsetWidth || 0, unstyled ? 1 : 280);
90
+ const panelH = Math.max(panelEl.offsetHeight || 0, unstyled ? 1 : 120);
88
91
 
89
92
  let place: PopoverPlacement = placement;
90
93
  if (place === 'top' || place === 'bottom') {
@@ -123,8 +126,15 @@
123
126
  `left:${Math.round(left)}px`,
124
127
  'right:auto',
125
128
  'bottom:auto',
126
- `width:${Math.round(panelW)}px`
127
- ].join(';');
129
+ unstyled ? 'width:max-content' : `width:${Math.round(panelW)}px`,
130
+ unstyled ? 'height:max-content' : null,
131
+ unstyled ? 'background:transparent' : null,
132
+ unstyled ? 'border:none' : null,
133
+ unstyled ? 'padding:0' : null,
134
+ unstyled ? 'overflow:visible' : null
135
+ ]
136
+ .filter(Boolean)
137
+ .join(';');
128
138
  }
129
139
 
130
140
  function syncNative() {
@@ -229,8 +239,12 @@
229
239
  role="dialog"
230
240
  ontoggle={onToggle}
231
241
  style={panelStyle}
242
+ data-unstyled={unstyled ? 'true' : undefined}
232
243
  class={[
233
- 'popover-panel m-0 rounded-xl border-border bg-surface-elevated p-3 shadow-xl max-w-[min(26rem,calc(100vw-1rem))] border outline-none',
244
+ 'popover-panel m-0 outline-none',
245
+ unstyled
246
+ ? 'border-0 bg-transparent p-0 shadow-none'
247
+ : 'rounded-xl border border-border bg-surface-elevated p-3 shadow-xl max-w-[min(26rem,calc(100vw-1rem))]',
234
248
  panelClass
235
249
  ]}
236
250
  >
@@ -241,7 +255,10 @@
241
255
  bind:this={panelEl}
242
256
  role="dialog"
243
257
  class={[
244
- 'min-w-48 rounded-xl border-border bg-surface-elevated p-3 shadow-xl absolute z-50 border',
258
+ 'absolute z-50 outline-none',
259
+ unstyled
260
+ ? 'border-0 bg-transparent p-0 shadow-none'
261
+ : 'min-w-48 rounded-xl border border-border bg-surface-elevated p-3 shadow-xl',
245
262
  absolutePos[placement],
246
263
  absoluteAlign[align][placement],
247
264
  panelClass
@@ -253,8 +270,19 @@
253
270
  </div>
254
271
 
255
272
  <style>
256
- /* UA popover defaults to inset:0force anchor via inline style */
273
+ /* UA popover paints a canvas background kill it for anchored panels */
274
+ .popover-panel {
275
+ background-color: transparent;
276
+ color: inherit;
277
+ }
257
278
  .popover-panel:popover-open {
258
279
  inset: unset;
259
280
  }
281
+ .popover-panel[data-unstyled='true'] {
282
+ background: transparent !important;
283
+ border: none !important;
284
+ padding: 0 !important;
285
+ box-shadow: none !important;
286
+ overflow: visible;
287
+ }
260
288
  </style>
@@ -7,6 +7,8 @@ interface PopoverProps {
7
7
  align?: PopoverAlign;
8
8
  strategy?: 'fixed' | 'absolute';
9
9
  offset?: number;
10
+ /** Solo ancla/posiciona; sin fondo, borde ni padding (el contenido aporta el chrome). */
11
+ unstyled?: boolean;
10
12
  class?: string;
11
13
  panelClass?: string;
12
14
  trigger?: Snippet;
@@ -248,23 +248,7 @@
248
248
 
249
249
  <!-- Footer -->
250
250
  <footer class="shrink-0 border-t border-border px-3 py-2.5">
251
- <div class="flex items-center gap-2">
252
- {#if voiceEnabled}
253
- <IconButton
254
- variant="ghost"
255
- size="sm"
256
- label={listening ? stopMicLabel : micLabel}
257
- onclick={() => onmicclick?.()}
258
- class={listening ? 'text-red-500 hover:text-red-600' : ''}
259
- >
260
- {#if listening}
261
- <MicOff size={16} strokeWidth={2} />
262
- {:else}
263
- <Mic size={16} strokeWidth={2} />
264
- {/if}
265
- </IconButton>
266
- {/if}
267
-
251
+ <div class="flex items-center gap-1.5">
268
252
  <input
269
253
  type="text"
270
254
  bind:value={draft}
@@ -275,30 +259,45 @@
275
259
  aria-label={placeholder}
276
260
  />
277
261
 
278
- {#if voiceEnabled}
262
+ <div class="flex shrink-0 items-center gap-0.5">
263
+ {#if voiceEnabled}
264
+ <IconButton
265
+ variant="ghost"
266
+ size="sm"
267
+ label={listening ? stopMicLabel : micLabel}
268
+ onclick={() => onmicclick?.()}
269
+ class={listening ? 'text-red-500 hover:text-red-600' : ''}
270
+ >
271
+ {#if listening}
272
+ <MicOff size={16} strokeWidth={2} />
273
+ {:else}
274
+ <Mic size={16} strokeWidth={2} />
275
+ {/if}
276
+ </IconButton>
277
+ <IconButton
278
+ variant="ghost"
279
+ size="sm"
280
+ label={voiceOutput ? voiceOnLabel : voiceOffLabel}
281
+ onclick={toggleVoice}
282
+ >
283
+ {#if voiceOutput}
284
+ <Volume2 size={16} strokeWidth={2} />
285
+ {:else}
286
+ <VolumeX size={16} strokeWidth={2} />
287
+ {/if}
288
+ </IconButton>
289
+ {/if}
290
+
279
291
  <IconButton
280
- variant="ghost"
292
+ variant={canSend ? 'primary' : 'ghost'}
281
293
  size="sm"
282
- label={voiceOutput ? voiceOnLabel : voiceOffLabel}
283
- onclick={toggleVoice}
294
+ label={sendLabel}
295
+ disabled={!canSend}
296
+ onclick={handleSend}
284
297
  >
285
- {#if voiceOutput}
286
- <Volume2 size={16} strokeWidth={2} />
287
- {:else}
288
- <VolumeX size={16} strokeWidth={2} />
289
- {/if}
298
+ <Send size={16} strokeWidth={2} />
290
299
  </IconButton>
291
- {/if}
292
-
293
- <IconButton
294
- variant={canSend ? 'primary' : 'ghost'}
295
- size="sm"
296
- label={sendLabel}
297
- disabled={!canSend}
298
- onclick={handleSend}
299
- >
300
- <Send size={16} strokeWidth={2} />
301
- </IconButton>
300
+ </div>
302
301
  </div>
303
302
 
304
303
  {#if footerExtra}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r2digisolutions/components",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "private": false,
5
5
  "description": "R2DigiSolutions Svelte 5 component library — Atomic Design, Tailwind 4, Light/Dark mode",
6
6
  "license": "MIT",