@w5-ui/svelte 0.5.0 → 0.6.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w5-ui/svelte",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Svelte 5 components for the Dash UI design system - mirrors the @w5-ui/react API 1:1. Part of Webber's design systems.",
5
5
  "keywords": [
6
6
  "svelte",
@@ -48,7 +48,7 @@
48
48
  "@w5-ui/tokens": "^0.5.0"
49
49
  },
50
50
  "devDependencies": {
51
- "svelte": "^5.55.9",
51
+ "svelte": "^5.56.4",
52
52
  "typescript": "^5.5.0"
53
53
  },
54
54
  "files": [
@@ -1,5 +1,6 @@
1
1
  <script module lang="ts">
2
2
  let counter = 0;
3
+ export type PopoverWidth = 'sm' | 'md' | 'lg' | 'xl';
3
4
  </script>
4
5
 
5
6
  <script lang="ts">
@@ -13,6 +14,14 @@
13
14
  variant?: 'ghost' | 'primary';
14
15
  title?: string | undefined;
15
16
  placement?: 'bottom-start' | 'bottom-end' | 'bottom';
17
+ /**
18
+ * Panel max-width. `sm` (320px) is the default and suits menus /
19
+ * option lists. Wider sizes suit content-dense panels (e.g. a
20
+ * folder picker with a path field, breadcrumb and file rows).
21
+ * The panel still shrinks to its content and is kept on-screen by
22
+ * the viewport-clamp in `recomputePosition`.
23
+ */
24
+ width?: PopoverWidth;
16
25
  /**
17
26
  * Controlled open state. Default uncontrolled (`$bindable(false)`):
18
27
  * the trigger button toggles it and outside-clicks close it.
@@ -42,10 +51,20 @@
42
51
  title = undefined,
43
52
  placement = 'bottom-start',
44
53
  open = $bindable(false),
54
+ width = 'sm',
45
55
  trigger,
46
56
  children,
47
57
  }: Props = $props();
48
58
 
59
+ // Pre-composed width utilities so Tailwind's static scanner keeps
60
+ // each class in the build (mirrors `Modal`'s `size` scale).
61
+ const WIDTH: Record<PopoverWidth, string> = {
62
+ sm: 'max-w-[320px]',
63
+ md: 'max-w-[400px]',
64
+ lg: 'max-w-[480px]',
65
+ xl: 'max-w-[560px]',
66
+ };
67
+
49
68
  const uid = `dash-ui-pop-${++counter}`;
50
69
  const titleId = `${uid}-title`;
51
70
 
@@ -181,7 +200,7 @@
181
200
  use:portal
182
201
  role="dialog"
183
202
  aria-labelledby={title ? titleId : undefined}
184
- class="fixed z-[9100] min-w-[200px] max-w-[320px] rounded-[10px] border border-border-3 bg-bg-2 shadow-[0_8px_32px_rgba(0,0,0,0.5)] focus:outline-none"
203
+ class={`fixed z-[9100] min-w-[200px] ${WIDTH[width]} rounded-[10px] border border-border-3 bg-bg-2 shadow-[0_8px_32px_rgba(0,0,0,0.5)] focus:outline-none`}
185
204
  style={`top: ${panelTop}px; left: ${panelLeft}px`}
186
205
  tabindex={-1}
187
206
  >
@@ -144,7 +144,7 @@
144
144
  {#if siteSwitchable}
145
145
  <button
146
146
  type="button"
147
- class="flex cursor-pointer items-center gap-2 rounded-md px-2.5 py-1.5 hover:bg-row-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-05"
147
+ class="flex shrink-0 cursor-pointer items-center gap-2 rounded-md px-2.5 py-1.5 hover:bg-row-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-05 max-md:px-1.5"
148
148
  aria-label="Switch site: {siteName}"
149
149
  aria-haspopup="menu"
150
150
  title={`${siteName} — status: ${status}`}
@@ -164,12 +164,12 @@
164
164
  {:else}
165
165
  <span class={ringWrapClass}><span class={ringDotClass}></span></span>
166
166
  {/if}
167
- <span class="text-13 font-medium text-text-1" aria-hidden="true">{siteName}</span>
168
- <CaretIcon class="h-3.5 w-3.5 text-text-3" />
167
+ <span class="text-13 font-medium text-text-1 max-md:hidden" aria-hidden="true">{siteName}</span>
168
+ <CaretIcon class="h-3.5 w-3.5 text-text-3 max-md:hidden" />
169
169
  </button>
170
170
  {:else}
171
171
  <div
172
- class="flex items-center gap-2 px-2.5 py-1.5"
172
+ class="flex shrink-0 items-center gap-2 px-2.5 py-1.5 max-md:px-1.5"
173
173
  role="presentation"
174
174
  title={`${siteName} — status: ${status}`}
175
175
  >
@@ -188,11 +188,21 @@
188
188
  {:else}
189
189
  <span class={ringWrapClass}><span class={ringDotClass}></span></span>
190
190
  {/if}
191
- <span class="text-13 font-medium text-text-1">{siteName}</span>
191
+ <span class="text-13 font-medium text-text-1 max-md:hidden">{siteName}</span>
192
192
  </div>
193
193
  {/if}
194
194
 
195
- <nav class="ml-3.5 flex h-12 items-center gap-0.5" aria-label="Apps">
195
+ <!--
196
+ Apps nav. On phones (< md) the fixed-width app buttons can exceed
197
+ the viewport, so the strip becomes a horizontally swipeable rail
198
+ (`flex-1 min-w-0 overflow-x-auto`, scrollbar hidden) instead of
199
+ overflowing the header. Desktop keeps its natural auto width with
200
+ the flex spacer pushing the actions to the right edge.
201
+ -->
202
+ <nav
203
+ class="ml-3.5 flex h-12 items-center gap-0.5 max-md:ml-1 max-md:min-w-0 max-md:flex-1 max-md:overflow-x-auto max-md:[scrollbar-width:none] max-md:[&::-webkit-scrollbar]:hidden"
204
+ aria-label="Apps"
205
+ >
196
206
  {#each apps as a (a.id)}
197
207
  <button
198
208
  type="button"
@@ -213,14 +223,14 @@
213
223
  ? 'opacity-100 dark:brightness-[1.6]'
214
224
  : 'opacity-65 hover:opacity-90 dark:hover:brightness-[1.4]'}"
215
225
  />
216
- <span class="mt-0.5 text-[10px] font-medium leading-none">{a.label}</span>
226
+ <span class="mt-0.5 text-[10px] font-medium leading-none max-md:hidden">{a.label}</span>
217
227
  </button>
218
228
  {/each}
219
229
  </nav>
220
230
 
221
- <div class="flex-1"></div>
231
+ <div class="flex-1 max-md:hidden"></div>
222
232
 
223
- <div class="flex items-center gap-1 pr-2">
233
+ <div class="flex shrink-0 items-center gap-1 pr-2">
224
234
  {#if actions}
225
235
  {@render actions()}
226
236
  {:else}
package/src/lib/index.ts CHANGED
@@ -68,6 +68,7 @@ export type { StepperStep } from './components/Stepper.svelte'
68
68
  export { default as SegmentedControl } from './components/SegmentedControl.svelte'
69
69
  export type { SegmentOption } from './components/SegmentedControl.svelte'
70
70
  export { default as Popover } from './components/Popover.svelte'
71
+ export type { PopoverWidth } from './components/Popover.svelte'
71
72
  export { default as FileUpload } from './components/FileUpload.svelte'
72
73
  export { default as Combobox } from './components/Combobox.svelte'
73
74
  export type { ComboboxOption } from './components/Combobox.svelte'