svelte-fluentui 1.0.0-rc21 → 1.0.0-rc22

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/README.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  A comprehensive Svelte wrapper library for Microsoft FluentUI web components (v2.6.x), providing a seamless way to use FluentUI components in Svelte applications.
4
4
 
5
+ ## What's New in v1.0.0-rc22
6
+
7
+ - **`InputFile` chips mode now has an overall progress footer** — the same `Pause all` / `Resume all` / `Retry all` controls plus the aggregate progress bar that list/popover modes already had. Works for both `chipsPosition` values; rendered as a sibling below the chips so layout stays sane regardless of position.
8
+ - **`package.json` `homepage` points at the docs site** — npm's "Homepage" sidebar link now goes to `svelte-fluentui.keenmate.dev` instead of duplicating the GitHub repo link. Two distinct destinations on the package page.
9
+ - **InputFile demo playground persists in localStorage** — the live selector × list × cardSize × chipsPosition mixer at `/components/inputfile` remembers your last configuration across page reloads. Files themselves are not persisted (File objects don't survive JSON).
10
+
5
11
  ## What's New in v1.0.0-rc21
6
12
 
7
13
  - **`InputFile` — `appearance` split into `selectorAppearance` + `listAppearance` + new `cardSize` prop** — the single `appearance` union baked the trigger visual and the file-list visual together, so combinations like "button trigger with popover list" or "card with chips below" weren't expressible. Now `selectorAppearance: "card" | "button" | "minimal"` and `listAppearance: "list" | "chips" | "popover" | "none"` are independent. All previous presets still expressible (`card + list`, `button + list`, `minimal + popover`, `card + chips`). New `cardSize: "minimal" | "compact" | "big"` resizes the card — `big` is the original tall vertical card, `compact` is a 2-row grid layout for forms where 200px felt enormous, and `minimal` collapses everything to a single inline wrapping row (icon · message · hint · hint · Browse) with `·` separators between hints
@@ -13,23 +19,6 @@ A comprehensive Svelte wrapper library for Microsoft FluentUI web components (v2
13
19
  - **Border-radius consolidated into a six-tier CSS-variable scale** — ~40 hardcoded `border-radius` declarations across 12 components were swept into `--fluent-border-radius-{sm,md,lg,xl,pill,circle}` (2/4/6/8/999/50%) on `:root`, backed by matching SCSS tokens (`$border-radius-sm/md/lg/xl/pill/circle`). The pre-existing `--fluent-border-radius` is preserved as a back-compat alias of `md`. Pixel-identical to the prior visual — drove tier choice off existing values per call site (4px → md, 2px → sm, etc.). Theming the library's entire corner-rounding is now a six-line variable override instead of a 40-line search-and-replace
14
20
  - **`InputFile` popover `max-height` was being silently overridden — fixed** — Floating UI's `size` middleware ran on every reposition and unconditionally wrote `floating.style.maxHeight = ${availableHeight - 16}px`, so on any window taller than the CSS cap the inline style won and the popover ballooned to ~viewport height (sticky footer ended up pinned far below the visible scroll region, looking like it was floating mid-list). Middleware now clears the inline cap, reads the CSS-rule-driven `max-height` via `getComputedStyle`, and only re-applies an inline cap when the viewport is actually tighter than the ceiling. CSS variable wins on tall screens, viewport wins on short screens
15
21
 
16
- ## What's New in v1.0.0-rc20
17
-
18
- - **`Calendar` / `DatePicker` — visual states finally render + 7 new DatePicker passthroughs + `cellSize` / `gap` resize knobs** — the CSS for today's accent circle, selected border, out-of-range strikethrough, faded-inactive days, and multi-select range fills was copied from FluentUI Blazor with attribute selectors that never matched the Svelte port's a11y-correct `data-*` / `aria-*` attributes — all silently dead. Selectors now aligned across all three views (days / months / years) and disabled months/years got a strikethrough treatment to match. DatePicker forwards seven previously-internal Calendar capabilities — `selectableDates` (inverse predicate), `disabledSelectable`, `disabledCheckAllDaysOfMonthYear`, `dayFormat`, `animatePeriodChanges`, `day` snippet (custom cell rendering), `onPickerMonthChange` callback. New `cellSize` / `gap` props on Calendar (and forwarded by DatePicker) resize the whole picker uniformly — accepts numbers (px) or any CSS length string
19
- - **`TimePicker` — booking-style disabled slots + UX polish** — new `disabledTimes: string[]` and `disabledTimeFunc: (h, m, s) => boolean` props for per-slot disabling beyond the existing `minTime`/`maxTime` range. Disabled cells render with strikethrough + dimmed and stop reacting to clicks; the OK button is gated on the current triplet's validity. Popup now auto-centers each column's selected (or first enabled) row on open, so 15-minute slots from 9–12 don't dump the user at hour 0 with everything above the fold disabled. Clock-icon button now actually opens the popup (was double-toggling due to event bubble); clear button no longer re-opens after clearing
20
- - **`TextField` — `maxlength` / `minlength` / `pattern` props + `start` snippet restored** — three native input validation attributes that `<fluent-text-field>` 2.6 doesn't forward to its shadow `<input>` are now wired via a generalized shadow-DOM helper (`setAttributeOnShadowInput`). They participate in `:invalid` styling and `ValidityState.{tooLong, tooShort, patternMismatch}`, so they compose with the existing `checkValidity()` / `<Field>` integration. The `start` slot — for leading icons / prefixes — was removed during an earlier refactor and is back, matching the `start`/`end` slot pair that Button / Search / NumberField / MenuButton already had
21
- - **`Checkbox` — external label + `labelPosition` to complete the form-control parity sweep** — closes the migration started in rc19 for `NumberField` and `Switch`. `Checkbox` now also emits a sibling `<label for={id} class="fluent-label">` (with shadow `::part(label)` hidden) and accepts `labelPosition: "top" | "start"` (default `"start"` keeps the historical inline layout). All `<Field>`-wrapped form controls now share a uniform label idiom regardless of which control is inside
22
- - **`InputFile` — drop-zone limit hints + `formatLimits` composer + `totalMaxSize` cap** — the card drop zone now advertises every configured constraint (`minFileSize`, `maxFileCount`, `minFiles`) instead of silently rejecting them post-pick. Five new `InputFileLabels` entries for full i18n. New `formatLimits?: (info) => string | null` composes the whole limits block into one line (returning a non-empty string replaces the four default lines). New `totalMaxSize: number` caps combined bytes across all accepted files — there was no clean way to express "the whole upload payload must stay under N bytes" before
23
- - **Smaller form-control additions** — `<Stack wrap>` for multi-line flex (Blazor `Wrap` parity), `<Button title="…">` for native HTML tooltips on hover (Blazor `Title` parity)
24
- - **Docs — `Ctrl/Cmd+K` command palette over the nav registry** — modal search with fuzzy scoring over a flattened list of every sidebar entry — so any new component page is automatically searchable, no separate index to maintain. Keyboard nav, scroll-into-view for the active row, group label chips. Topnav gets a "Search…" pill showing `⌘K` on Mac and `Ctrl K` elsewhere
25
- - **Popover scroll containers — `overscroll-behavior: contain`** — TimePicker columns, Autocomplete dropdown, ContextMenu, Select, MenuButton, GridCellEditor combobox, and the docs CommandPalette no longer let wheel/touch scroll leak through to the page when you hit the edge of the popover list
26
-
27
- ## What's New in v1.0.0-rc19
28
-
29
- - **`NumberField` external label rendering with new `id` and `labelTemplate` props** — `label` used to slot into the shadow `::part(label)`, which meant `NumberField` labels never matched the visual treatment of `TextField` / `Select` / `Autocomplete` (all of which render an external `.fluent-label`). Now `label` (string) and the new `labelTemplate` (Snippet) render as a sibling `<label for={id} class="fluent-label">` above the input, the shadow `::part(label)` is hidden, and a new `id` prop wires the external label to the input. Net effect: `<Field>`-wrapped NumberFields finally look identical to wrapped TextFields, and `labelTemplate` lets consumers mix icons / rich markup into the label
30
- - **`Switch` `labelPosition: "top" | "start"` prop + external label rendering** — same migration as NumberField: `label` / `labelTemplate` / `children` now render through a single external `.fluent-label`, the shadow `::part(label)` is hidden, and the new `labelPosition` flips between stacked-above (`"top"`, default) and inline-before (`"start"`) layouts. `checkedMessage` / `uncheckedMessage` slots inside the toggle are unchanged. Demo page at `/components/forms/switch` adds a radio control to flip positions side-by-side
31
- - **`<fluent-menu>` popover wrappers — gray-pixel corners + invisible elevation on dark themes** — `MenuButton`, `QuickGrid` context menu, and `Tabs` overflow menu all wrap `<fluent-menu>` in a portaled `<div>` that Floating UI's `size` middleware caps with `max-height` + `overflow-y: auto`. The wrapper had no `border-radius`, so its square corners peeked out behind the inner menu's rounded corners as gray pixels against any non-white surface. Same wrappers relied on `<fluent-menu>`'s shadow-DOM elevation, which is barely visible against dark themes. All three wrappers now paint `background: transparent` + matching `border-radius` (`var(--layer-corner-radius, …)`) + the same elevation shadow that `ContextMenu` already uses
32
-
33
22
  ## Features
34
23
 
35
24
  - 🎨 **Complete FluentUI Component Set** - Wraps all major FluentUI web components
@@ -1461,6 +1461,75 @@
1461
1461
  {/if}
1462
1462
  {/snippet}
1463
1463
 
1464
+ {#snippet overallFooter()}
1465
+ {#if uploadFileCallback && items.length > 0}
1466
+ <div class="file-list-footer">
1467
+ <div
1468
+ class="footer-progress"
1469
+ role="progressbar"
1470
+ aria-valuenow={Math.round(overallProgress)}
1471
+ aria-valuemin="0"
1472
+ aria-valuemax="100"
1473
+ >
1474
+ <div class="footer-progress-fill" style:width="{overallProgress}%"></div>
1475
+ </div>
1476
+ <div class="footer-stats">
1477
+ <span class="footer-stats-text">
1478
+ {labels.totalProgress({
1479
+ completed: completedCount,
1480
+ failed: failedCount,
1481
+ total: items.length,
1482
+ uploadedBytes,
1483
+ totalBytes,
1484
+ percent: overallProgress
1485
+ })}
1486
+ </span>
1487
+ {#if anyUploading || anyPaused || anyFailed}
1488
+ <div class="footer-actions">
1489
+ {#if anyUploading}
1490
+ <button
1491
+ type="button"
1492
+ class="footer-action-button"
1493
+ onclick={(e) => {
1494
+ e.stopPropagation()
1495
+ pauseAll()
1496
+ }}
1497
+ >
1498
+ {labels.pauseAll}
1499
+ </button>
1500
+ {/if}
1501
+ {#if anyPaused}
1502
+ <button
1503
+ type="button"
1504
+ class="footer-action-button"
1505
+ onclick={(e) => {
1506
+ e.stopPropagation()
1507
+ resumeAll()
1508
+ }}
1509
+ >
1510
+ {labels.resumeAll}
1511
+ </button>
1512
+ {/if}
1513
+ {#if anyFailed}
1514
+ <button
1515
+ type="button"
1516
+ class="footer-action-button"
1517
+ onclick={(e) => {
1518
+ e.stopPropagation()
1519
+ retryAll()
1520
+ }}
1521
+ >
1522
+ {labels.retryAll}
1523
+ </button>
1524
+ {/if}
1525
+ </div>
1526
+ {/if}
1527
+ <span class="footer-stats-percent">{Math.round(overallProgress)}%</span>
1528
+ </div>
1529
+ </div>
1530
+ {/if}
1531
+ {/snippet}
1532
+
1464
1533
  {#if listAppearance === "chips" && items.length > 0}
1465
1534
  <!-- chips-row only renders when there are items to show. With zero items,
1466
1535
  fall through to the plain selector-wrap so the card stays at its
@@ -1481,6 +1550,7 @@
1481
1550
  {@render chipsList()}
1482
1551
  </div>
1483
1552
  </div>
1553
+ {@render overallFooter()}
1484
1554
  {:else}
1485
1555
  <div class="fluent-inputfile__selector-wrap" bind:this={selectorWrapEl}>
1486
1556
  {@render selectorBlock()}
@@ -1687,72 +1757,7 @@
1687
1757
  {/if}
1688
1758
  </div>
1689
1759
 
1690
- {#if uploadFileCallback && items.length > 0}
1691
- <div class="file-list-footer">
1692
- <div
1693
- class="footer-progress"
1694
- role="progressbar"
1695
- aria-valuenow={Math.round(overallProgress)}
1696
- aria-valuemin="0"
1697
- aria-valuemax="100"
1698
- >
1699
- <div class="footer-progress-fill" style:width="{overallProgress}%"></div>
1700
- </div>
1701
- <div class="footer-stats">
1702
- <span class="footer-stats-text">
1703
- {labels.totalProgress({
1704
- completed: completedCount,
1705
- failed: failedCount,
1706
- total: items.length,
1707
- uploadedBytes,
1708
- totalBytes,
1709
- percent: overallProgress
1710
- })}
1711
- </span>
1712
- {#if anyUploading || anyPaused || anyFailed}
1713
- <div class="footer-actions">
1714
- {#if anyUploading}
1715
- <button
1716
- type="button"
1717
- class="footer-action-button"
1718
- onclick={(e) => {
1719
- e.stopPropagation()
1720
- pauseAll()
1721
- }}
1722
- >
1723
- {labels.pauseAll}
1724
- </button>
1725
- {/if}
1726
- {#if anyPaused}
1727
- <button
1728
- type="button"
1729
- class="footer-action-button"
1730
- onclick={(e) => {
1731
- e.stopPropagation()
1732
- resumeAll()
1733
- }}
1734
- >
1735
- {labels.resumeAll}
1736
- </button>
1737
- {/if}
1738
- {#if anyFailed}
1739
- <button
1740
- type="button"
1741
- class="footer-action-button"
1742
- onclick={(e) => {
1743
- e.stopPropagation()
1744
- retryAll()
1745
- }}
1746
- >
1747
- {labels.retryAll}
1748
- </button>
1749
- {/if}
1750
- </div>
1751
- {/if}
1752
- <span class="footer-stats-percent">{Math.round(overallProgress)}%</span>
1753
- </div>
1754
- </div>
1755
- {/if}
1760
+ {@render overallFooter()}
1756
1761
  </div>
1757
1762
  {/snippet}
1758
1763
 
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "1.0.0-rc21";
1
+ export declare const VERSION = "1.0.0-rc22";
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  // Auto-generated by scripts/pre-package.js — do NOT edit by hand.
2
2
  // In dev this file holds whatever value was committed last; on each `npm run package`
3
3
  // the pre-package script overwrites it with the current package.json version.
4
- export const VERSION = "1.0.0-rc21";
4
+ export const VERSION = "1.0.0-rc22";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-fluentui",
3
- "version": "1.0.0-rc21",
3
+ "version": "1.0.0-rc22",
4
4
  "description": "A Svelte wrapper library for Microsoft FluentUI web components",
5
5
  "license": "MIT",
6
6
  "author": "KeenMate",
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/KeenMate/svelte-fluentui/issues"
13
13
  },
14
- "homepage": "https://github.com/KeenMate/svelte-fluentui#readme",
14
+ "homepage": "https://svelte-fluentui.keenmate.dev",
15
15
  "scripts": {
16
16
  "dev": "svelte-package --watch",
17
17
  "package": "npm run package:pre-build && svelte-kit sync && svelte-package && npm run package:post-build && publint",