svelte-fluentui 1.3.2 → 1.4.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/README.md +8 -9
- package/dist/components/Accordion.svelte +1 -1
- package/dist/components/AccordionItem.svelte +7 -3
- package/dist/components/Anchor.svelte +12 -12
- package/dist/components/BreadcrumbItem.svelte +1 -1
- package/dist/components/Button.svelte +16 -16
- package/dist/components/Checkbox.svelte +10 -10
- package/dist/components/Combobox.svelte +13 -13
- package/dist/components/DataGrid.svelte +4 -4
- package/dist/components/DataGridCell.svelte +8 -8
- package/dist/components/DataGridRow.svelte +3 -3
- package/dist/components/Dialog.svelte +5 -5
- package/dist/components/Listbox.svelte +3 -3
- package/dist/components/MenuButton.svelte +3 -3
- package/dist/components/NumberField.svelte +15 -15
- package/dist/components/Option.svelte +6 -6
- package/dist/components/Paginator.svelte +4 -4
- package/dist/components/QuickGrid.svelte +1 -1
- package/dist/components/Select.svelte +13 -0
- package/dist/components/Slider.svelte +12 -12
- package/dist/components/Switch.svelte +8 -8
- package/dist/components/TabPanel.svelte +1 -1
- package/dist/components/TextField.svelte +14 -14
- package/dist/components/Textarea.svelte +16 -16
- package/dist/components/Toolbar.svelte +3 -3
- package/dist/components/layout/MultiSplitter.svelte +1152 -157
- package/dist/components/layout/MultiSplitter.svelte.d.ts +19 -9
- package/dist/components/layout/MultiSplitterPane.svelte +78 -99
- package/dist/components/layout/MultiSplitterPane.svelte.d.ts +7 -4
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/types/multi-splitter.d.ts +35 -0
- package/dist/types/multi-splitter.js +9 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,18 +2,17 @@
|
|
|
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.
|
|
5
|
+
## What's New in v1.4.0
|
|
6
6
|
|
|
7
|
-
- **`
|
|
8
|
-
- **`
|
|
9
|
-
- **`
|
|
7
|
+
- **`MultiSplitter` — full rewrite as a Svelte 5 port of pureadmin.io's `pa-splitter`** — The old wrapper was a near-empty shell; the new component (`src/lib/components/layout/MultiSplitter.svelte` + `MultiSplitterPane.svelte`) is a real N-pane resizable container with drag-to-resize using a REBALANCE model (CLASSIC + TUNNEL absorbers so slack can punch through a rail wall), minimize-to-rail via the `minimize` prop with a configurable snap threshold, full keyboard nav + ARIA on the gutter, `localStorage` persistence via the `id` prop, and auto-accordion mode when the container can't fit all panes' mins. Drag math is rAF-throttled with a 2px jitter floor; pane Cards auto-adapt to railed state with the first child becoming a rotated rail title in horizontal orientation. Three callbacks (`onresize`, `oncollapse`, `onexpand`) and full type exports (`MultiSplitterResizeDetail`, `MultiSplitterToggleDetail`).
|
|
8
|
+
- **`MultiSplitter` — gutter drag against a railed pane is a one-way valve: inward inert, outward expands** — Earlier iterations either flipped the rail open instantly on `pointerdown` (the user saw the card "expand" just from pressing the gutter) or refused to expand from any drag at all. Final behaviour: inward drag (toward the rail) bails before reaching the drag math so the gutter doesn't move; outward drag past 2px releases the rail, fires `onexpand`, and grows the pane following the cursor with the rail floor clamping until `primary.min` is reached. Dblclick and rail-body click stay as alternative expand gestures. The result matches what users actually expect from a collapsed pane — you can pull it open but you can't accidentally crush it further.
|
|
9
|
+
- **`Select` — encapsulated in a single render root via `display: contents`** — The component renders 2-4 sibling elements at root depending on mode (label + hidden source mirror + trigger + optional hidden form input in single mode; label + inline listbox in multi mode). That meant a consumer dropping `<Select>` into a flex or grid had to reason about the internal sibling structure to align it. Wrapped everything in `<div class="select-root">` with `display: contents` so the wrapper is invisible to flex/grid layout (children still participate as direct items of the consumer's container), but the component now reads as a single logical root from the outside. Zero behaviour change for existing layout code.
|
|
10
10
|
|
|
11
|
-
## What's New in v1.3.
|
|
11
|
+
## What's New in v1.3.3
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- **`TopNav` — tightened horizontal padding from `1.5rem` to `0.5rem`** — the bar's inside edges felt cramped relative to the rest of the content. Brand + hamburger now sit closer to the inline-start edge and the action slot sits closer to the inline-end edge.
|
|
13
|
+
- **Custom-element attribute bindings stop stringifying `undefined` / `null` / `false`** — Recurring regression (last fixed ~5 months ago, reintroduced during the structural rework) that affected 22 wrappers including `TextField`, `Textarea`, `Switch`, `Slider`, `Checkbox`, `Button`, `Anchor`, `Accordion(Item)`, `BreadcrumbItem`, `DataGrid(Row/Cell)`, `Dialog`, `Listbox`, `MenuButton`, `Option`, `TabPanel`, `Toolbar`, `NumberField`, `Combobox`, plus `Paginator` and `QuickGrid` sub-buttons. Svelte 5 sets properties on custom elements rather than attributes, and FAST's `@attr` decorators stringify whatever they receive — so unset props were rendering as `title="undefined"`, `readonly="false"`, `disabled="false"`, etc. The `readonly`/`disabled` cases were the worst symptom because `[readonly]` and `[disabled]` CSS attribute-presence selectors match regardless of value, leaving an enabled field with a not-allowed cursor. All affected wrappers converted to the conditional-spread pattern (`{...(title ? { title } : {})}`) which physically omits the attribute from the template when unset. Variants `{...(value != null ? { value } : {})}` for inputs (so `value=""` still renders) and `{...(attr !== undefined ? { attr } : {})}` for numeric props (so `0` survives) are used where falsy values are meaningful.
|
|
14
|
+
|
|
15
|
+
- **`TextField` demo page — new Readonly and Disabled example sections** — The `/components/forms/text-field` showcase previously demonstrated only the basic input and `autocomplete` variants; the readonly and disabled states (the surface that exposed the bug above) had no live example. Added Readonly with outline + filled variants and Disabled with three variants (outline + placeholder, outline + value, filled + value).
|
|
17
16
|
|
|
18
17
|
## Features
|
|
19
18
|
|
|
@@ -43,14 +43,18 @@
|
|
|
43
43
|
|
|
44
44
|
onchange?.(ev, target.getAttribute("expanded") === "")
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
const isExpanded = $derived(
|
|
48
|
+
expanded === undefined && ctx.value !== undefined ? !!ctx.value?.includes(id) : expanded
|
|
49
|
+
)
|
|
46
50
|
</script>
|
|
47
51
|
|
|
48
52
|
<!-- todo: investigate flicker during switching of accordions -->
|
|
49
53
|
<fluent-accordion-item
|
|
50
|
-
{id}
|
|
54
|
+
{...(id ? { id } : {})}
|
|
51
55
|
data-custom-id={id}
|
|
52
|
-
heading-level
|
|
53
|
-
|
|
56
|
+
{...(headingLevel !== undefined ? { "heading-level": headingLevel } : {})}
|
|
57
|
+
{...(isExpanded ? { expanded: isExpanded } : {})}
|
|
54
58
|
onchange={handleOnChange}
|
|
55
59
|
>
|
|
56
60
|
<div slot="heading">
|
|
@@ -68,18 +68,18 @@
|
|
|
68
68
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
69
69
|
<fluent-anchor
|
|
70
70
|
bind:this={element}
|
|
71
|
-
{id}
|
|
72
|
-
|
|
73
|
-
{style}
|
|
74
|
-
{download}
|
|
75
|
-
{href}
|
|
76
|
-
{hreflang}
|
|
77
|
-
{ping}
|
|
78
|
-
{referrerpolicy}
|
|
79
|
-
{rel}
|
|
80
|
-
{target}
|
|
81
|
-
{type}
|
|
82
|
-
{appearance}
|
|
71
|
+
{...(id ? { id } : {})}
|
|
72
|
+
{...(className ? { class: className } : {})}
|
|
73
|
+
{...(style ? { style } : {})}
|
|
74
|
+
{...(download ? { download } : {})}
|
|
75
|
+
{...(href ? { href } : {})}
|
|
76
|
+
{...(hreflang ? { hreflang } : {})}
|
|
77
|
+
{...(ping ? { ping } : {})}
|
|
78
|
+
{...(referrerpolicy ? { referrerpolicy } : {})}
|
|
79
|
+
{...(rel ? { rel } : {})}
|
|
80
|
+
{...(target ? { target } : {})}
|
|
81
|
+
{...(type ? { type } : {})}
|
|
82
|
+
{...(appearance ? { appearance } : {})}
|
|
83
83
|
onclick={handleClick}
|
|
84
84
|
>
|
|
85
85
|
{#if iconStart}
|
|
@@ -56,22 +56,22 @@
|
|
|
56
56
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
57
57
|
<!-- svelte-ignore a11y_autofocus -->
|
|
58
58
|
<fluent-button
|
|
59
|
-
{type}
|
|
60
|
-
{name}
|
|
61
|
-
{value}
|
|
62
|
-
{appearance}
|
|
63
|
-
{autofocus}
|
|
64
|
-
{formaction}
|
|
65
|
-
{form}
|
|
66
|
-
{formenctype}
|
|
67
|
-
{formmethod}
|
|
68
|
-
{formnovalidate}
|
|
69
|
-
{formtarget}
|
|
70
|
-
{disabled}
|
|
71
|
-
{style}
|
|
72
|
-
|
|
73
|
-
aria-label
|
|
74
|
-
{title}
|
|
59
|
+
{...(type ? { type } : {})}
|
|
60
|
+
{...(name ? { name } : {})}
|
|
61
|
+
{...(value != null ? { value } : {})}
|
|
62
|
+
{...(appearance ? { appearance } : {})}
|
|
63
|
+
{...(autofocus ? { autofocus } : {})}
|
|
64
|
+
{...(formaction ? { formaction } : {})}
|
|
65
|
+
{...(form ? { form } : {})}
|
|
66
|
+
{...(formenctype ? { formenctype } : {})}
|
|
67
|
+
{...(formmethod ? { formmethod } : {})}
|
|
68
|
+
{...(formnovalidate ? { formnovalidate } : {})}
|
|
69
|
+
{...(formtarget ? { formtarget } : {})}
|
|
70
|
+
{...(disabled ? { disabled } : {})}
|
|
71
|
+
{...(style ? { style } : {})}
|
|
72
|
+
{...(className ? { class: className } : {})}
|
|
73
|
+
{...(ariaLabel ? { "aria-label": ariaLabel } : {})}
|
|
74
|
+
{...(title ? { title } : {})}
|
|
75
75
|
{onclick}
|
|
76
76
|
>
|
|
77
77
|
{#if start}
|
|
@@ -155,17 +155,17 @@
|
|
|
155
155
|
<!-- svelte-ignore a11y_autofocus -->
|
|
156
156
|
<fluent-checkbox
|
|
157
157
|
bind:this={element}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
{autofocus}
|
|
161
|
-
{readonly}
|
|
162
|
-
{disabled}
|
|
163
|
-
{required}
|
|
158
|
+
{...(checked === true ? { checked: true } : {})}
|
|
159
|
+
{...(checked === null ? { indeterminate: true } : {})}
|
|
160
|
+
{...(autofocus ? { autofocus } : {})}
|
|
161
|
+
{...(readonly ? { readonly } : {})}
|
|
162
|
+
{...(disabled ? { disabled } : {})}
|
|
163
|
+
{...(required ? { required } : {})}
|
|
164
164
|
id={effectiveId}
|
|
165
|
-
{name}
|
|
166
|
-
aria-label
|
|
167
|
-
|
|
168
|
-
style
|
|
165
|
+
{...(name ? { name } : {})}
|
|
166
|
+
{...(ariaLabel || label ? { "aria-label": ariaLabel || label } : {})}
|
|
167
|
+
{...(className ? { class: className } : {})}
|
|
168
|
+
{...(style ? { style } : {})}
|
|
169
169
|
onclick={handleOnClick}
|
|
170
170
|
></fluent-checkbox>
|
|
171
171
|
|
|
@@ -254,19 +254,19 @@
|
|
|
254
254
|
<fluent-combobox
|
|
255
255
|
bind:this={element}
|
|
256
256
|
class={className}
|
|
257
|
-
|
|
258
|
-
{id}
|
|
259
|
-
autocomplete
|
|
260
|
-
open
|
|
261
|
-
current-value
|
|
262
|
-
placeholder
|
|
263
|
-
position
|
|
264
|
-
disabled
|
|
265
|
-
appearance
|
|
266
|
-
required
|
|
267
|
-
autofocus
|
|
268
|
-
name
|
|
269
|
-
aria-label
|
|
257
|
+
{...(computedStyle() ? { style: computedStyle() } : {})}
|
|
258
|
+
{...(id ? { id } : {})}
|
|
259
|
+
{...(autocomplete ? { autocomplete } : {})}
|
|
260
|
+
{...(open ? { open } : {})}
|
|
261
|
+
{...(currentValue ? { "current-value": currentValue } : {})}
|
|
262
|
+
{...(placeholder ? { placeholder } : {})}
|
|
263
|
+
{...(position ? { position } : {})}
|
|
264
|
+
{...(disabled ? { disabled } : {})}
|
|
265
|
+
{...(appearance ? { appearance } : {})}
|
|
266
|
+
{...(required ? { required } : {})}
|
|
267
|
+
{...(autofocus ? { autofocus } : {})}
|
|
268
|
+
{...(name ? { name } : {})}
|
|
269
|
+
{...(ariaLabel || label ? { "aria-label": ariaLabel ?? label } : {})}
|
|
270
270
|
{...titleProps}
|
|
271
271
|
onchange={handleChange}
|
|
272
272
|
>
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
|
|
40
40
|
<fluent-data-grid
|
|
41
41
|
class={className}
|
|
42
|
-
{style}
|
|
43
|
-
{id}
|
|
44
|
-
aria-rowcount
|
|
45
|
-
generate-header
|
|
42
|
+
{...(style ? { style } : {})}
|
|
43
|
+
{...(id ? { id } : {})}
|
|
44
|
+
{...(ariaRowCount !== undefined ? { "aria-rowcount": ariaRowCount } : {})}
|
|
45
|
+
{...(generateHeader ? { "generate-header": generateHeader } : {})}
|
|
46
46
|
role={role}
|
|
47
47
|
onclosecolumnoptions={handleCloseColumnOptions}
|
|
48
48
|
onclosecolumnresize={handleCloseColumnResize}
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
<!-- svelte-ignore a11y_no_noninteractive_tabindex a11y_click_events_have_key_events -->
|
|
53
53
|
<fluent-data-grid-cell
|
|
54
54
|
class={className}
|
|
55
|
-
{style}
|
|
56
|
-
grid-column
|
|
57
|
-
cell-type
|
|
58
|
-
col-index
|
|
59
|
-
{role}
|
|
60
|
-
|
|
61
|
-
{title}
|
|
62
|
-
aria-label
|
|
55
|
+
{...(style ? { style } : {})}
|
|
56
|
+
{...(gridColumn !== undefined ? { "grid-column": gridColumn } : {})}
|
|
57
|
+
{...(cellType ? { "cell-type": cellType } : {})}
|
|
58
|
+
{...(colIndex !== undefined ? { "col-index": colIndex } : {})}
|
|
59
|
+
{...(role ? { role } : {})}
|
|
60
|
+
{...(tabIndex !== undefined ? { tabindex: tabIndex } : {})}
|
|
61
|
+
{...(title ? { title } : {})}
|
|
62
|
+
{...(ariaLabel ? { "aria-label": ariaLabel } : {})}
|
|
63
63
|
onkeydown={handleKeyDown}
|
|
64
64
|
onclick={handleClick}
|
|
65
65
|
onfocus={handleFocus}
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
<!-- svelte-ignore a11y_interactive_supports_focus -->
|
|
49
49
|
<fluent-data-grid-row
|
|
50
50
|
class={className}
|
|
51
|
-
{style}
|
|
52
|
-
data-row-index
|
|
53
|
-
row-type
|
|
51
|
+
{...(style ? { style } : {})}
|
|
52
|
+
{...(rowIndex !== undefined ? { "data-row-index": rowIndex } : {})}
|
|
53
|
+
{...(rowType ? { "row-type": rowType } : {})}
|
|
54
54
|
role="row"
|
|
55
55
|
onkeydown={handleKeyDown}
|
|
56
56
|
onclick={handleClick}
|
|
@@ -229,12 +229,12 @@
|
|
|
229
229
|
<fluent-dialog
|
|
230
230
|
use:portal
|
|
231
231
|
bind:this={element}
|
|
232
|
-
{modal}
|
|
232
|
+
{...(modal ? { modal } : {})}
|
|
233
233
|
hidden={!visible}
|
|
234
|
-
{trapFocus}
|
|
235
|
-
{ariaDescribedby}
|
|
236
|
-
{ariaLabelledby}
|
|
237
|
-
{ariaLabel}
|
|
234
|
+
{...(trapFocus ? { trapFocus } : {})}
|
|
235
|
+
{...(ariaDescribedby ? { ariaDescribedby } : {})}
|
|
236
|
+
{...(ariaLabelledby ? { ariaLabelledby } : {})}
|
|
237
|
+
{...(ariaLabel ? { ariaLabel } : {})}
|
|
238
238
|
class="dialog-positioned"
|
|
239
239
|
style={dialogStyle + (style ? ` ${style}` : '')}
|
|
240
240
|
>
|
|
@@ -97,9 +97,9 @@
|
|
|
97
97
|
<fluent-listbox
|
|
98
98
|
bind:this={element}
|
|
99
99
|
selected-options={selectedOptionsAttr}
|
|
100
|
-
{disabled}
|
|
101
|
-
{autofocus}
|
|
102
|
-
{name}
|
|
100
|
+
{...(disabled ? { disabled } : {})}
|
|
101
|
+
{...(autofocus ? { autofocus } : {})}
|
|
102
|
+
{...(name ? { name } : {})}
|
|
103
103
|
{...(size !== undefined ? { size } : {})}
|
|
104
104
|
aria-label={ariaLabel || null}
|
|
105
105
|
class={className || null}
|
|
@@ -207,10 +207,10 @@
|
|
|
207
207
|
<span bind:this={anchorEl} class="fluent-menu-button-anchor">
|
|
208
208
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
209
209
|
<fluent-button
|
|
210
|
-
{appearance}
|
|
211
|
-
{disabled}
|
|
210
|
+
{...(appearance ? { appearance } : {})}
|
|
211
|
+
{...(disabled ? { disabled } : {})}
|
|
212
212
|
class={className}
|
|
213
|
-
{style}
|
|
213
|
+
{...(style ? { style } : {})}
|
|
214
214
|
aria-haspopup="menu"
|
|
215
215
|
aria-expanded={open}
|
|
216
216
|
onclick={toggleMenu}
|
|
@@ -187,27 +187,27 @@
|
|
|
187
187
|
<!-- svelte-ignore a11y_autofocus -->
|
|
188
188
|
<fluent-number-field
|
|
189
189
|
bind:this={element}
|
|
190
|
-
{id}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
placeholder
|
|
194
|
-
appearance
|
|
195
|
-
disabled
|
|
196
|
-
readonly
|
|
197
|
-
required
|
|
198
|
-
autofocus
|
|
199
|
-
autocomplete
|
|
190
|
+
{...(id ? { id } : {})}
|
|
191
|
+
{...(className ? { class: className } : {})}
|
|
192
|
+
{...(computedStyle ? { style: computedStyle } : {})}
|
|
193
|
+
{...(placeholder ? { placeholder } : {})}
|
|
194
|
+
{...(appearance ? { appearance } : {})}
|
|
195
|
+
{...(disabled ? { disabled } : {})}
|
|
196
|
+
{...(readonly ? { readonly } : {})}
|
|
197
|
+
{...(required ? { required } : {})}
|
|
198
|
+
{...(autofocus ? { autofocus } : {})}
|
|
199
|
+
{...(autocomplete ? { autocomplete } : {})}
|
|
200
200
|
{...(step !== undefined ? { step } : {})}
|
|
201
201
|
{...(min !== undefined ? { min } : {})}
|
|
202
202
|
{...(max !== undefined ? { max } : {})}
|
|
203
203
|
{...(minlength !== undefined ? { minlength } : {})}
|
|
204
204
|
{...(maxlength !== undefined ? { maxlength } : {})}
|
|
205
205
|
{...(size !== undefined ? { size } : {})}
|
|
206
|
-
list
|
|
207
|
-
hide-step
|
|
208
|
-
name
|
|
209
|
-
aria-label
|
|
210
|
-
value
|
|
206
|
+
{...(list ? { list } : {})}
|
|
207
|
+
{...(hideStep ? { "hide-step": hideStep } : {})}
|
|
208
|
+
{...(name ? { name } : {})}
|
|
209
|
+
{...(ariaLabel || label ? { "aria-label": ariaLabel ?? label } : {})}
|
|
210
|
+
{...(value != null ? { value } : {})}
|
|
211
211
|
{...titleProps}
|
|
212
212
|
oninput={handleOnInput}
|
|
213
213
|
onchange={handleOnChange}
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
56
56
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
57
57
|
<fluent-option
|
|
58
|
-
{value}
|
|
59
|
-
|
|
58
|
+
{...(value != null ? { value } : {})}
|
|
59
|
+
{...((selected !== undefined ? selected : selectedValue?.value?.includes(value)) ? { selected: true } : {})}
|
|
60
60
|
class={className}
|
|
61
|
-
{style}
|
|
62
|
-
data-option-label
|
|
63
|
-
data-option-context
|
|
64
|
-
{disabled}
|
|
61
|
+
{...(style ? { style } : {})}
|
|
62
|
+
{...(label ? { "data-option-label": label } : {})}
|
|
63
|
+
{...(data ? { "data-option-context": JSON.stringify(data) } : {})}
|
|
64
|
+
{...(disabled ? { disabled } : {})}
|
|
65
65
|
onclick={handleOnClick}
|
|
66
66
|
>
|
|
67
67
|
{#if icon}
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
56
56
|
<fluent-button
|
|
57
57
|
onclick={() => onFirst?.()}
|
|
58
|
-
|
|
58
|
+
{...(!canGoBack || disabled ? { disabled: true } : {})}
|
|
59
59
|
title="Go to first page"
|
|
60
60
|
aria-label="Go to first page"
|
|
61
61
|
>
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
67
67
|
<fluent-button
|
|
68
68
|
onclick={() => onPrevious?.()}
|
|
69
|
-
|
|
69
|
+
{...(!canGoBack || disabled ? { disabled: true } : {})}
|
|
70
70
|
title="Go to previous page"
|
|
71
71
|
aria-label="Go to previous page"
|
|
72
72
|
>
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
86
86
|
<fluent-button
|
|
87
87
|
onclick={() => onNext?.()}
|
|
88
|
-
|
|
88
|
+
{...(!canGoForwards || disabled ? { disabled: true } : {})}
|
|
89
89
|
title="Go to next page"
|
|
90
90
|
aria-label="Go to next page"
|
|
91
91
|
>
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
97
97
|
<fluent-button
|
|
98
98
|
onclick={() => onLast?.()}
|
|
99
|
-
|
|
99
|
+
{...(!canGoForwards || disabled ? { disabled: true } : {})}
|
|
100
100
|
title="Go to last page"
|
|
101
101
|
aria-label="Go to last page"
|
|
102
102
|
>
|
|
@@ -2194,7 +2194,7 @@
|
|
|
2194
2194
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
2195
2195
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
2196
2196
|
<fluent-menu-item
|
|
2197
|
-
|
|
2197
|
+
{...(isDisabled ? { disabled: true } : {})}
|
|
2198
2198
|
class:danger={menuItem.danger}
|
|
2199
2199
|
onclick={() => handleContextMenuItemClick(menuItem)}
|
|
2200
2200
|
>
|
|
@@ -468,6 +468,10 @@
|
|
|
468
468
|
const listboxId = $derived(id ? `${id}-listbox` : undefined)
|
|
469
469
|
</script>
|
|
470
470
|
|
|
471
|
+
<!-- Single DOM root so consumers see one element, not 2–4 siblings. Uses
|
|
472
|
+
display:contents so it's transparent to flex/grid layout in the parent. -->
|
|
473
|
+
<div class="select-root">
|
|
474
|
+
|
|
471
475
|
<!-- svelte-ignore a11y_label_has_associated_control -->
|
|
472
476
|
{#if hasLabel}
|
|
473
477
|
<label class="fluent-label" for={id}>
|
|
@@ -568,7 +572,16 @@
|
|
|
568
572
|
{/if}
|
|
569
573
|
{/if}
|
|
570
574
|
|
|
575
|
+
</div>
|
|
576
|
+
|
|
571
577
|
<style>
|
|
578
|
+
/* Transparent to layout — wraps label + trigger + mirror + portal anchor
|
|
579
|
+
* so consumers only see one root, but parent flex/grid still lays out the
|
|
580
|
+
* inner elements directly. */
|
|
581
|
+
.select-root {
|
|
582
|
+
display: contents;
|
|
583
|
+
}
|
|
584
|
+
|
|
572
585
|
.required-indicator {
|
|
573
586
|
color: var(--error-foreground-rest, #d13438);
|
|
574
587
|
margin-left: 0.25rem;
|
|
@@ -91,18 +91,18 @@
|
|
|
91
91
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
92
92
|
<fluent-slider
|
|
93
93
|
bind:this={element}
|
|
94
|
-
{id}
|
|
95
|
-
{min}
|
|
96
|
-
{max}
|
|
97
|
-
{step}
|
|
98
|
-
{orientation}
|
|
99
|
-
{disabled}
|
|
100
|
-
{readonly}
|
|
101
|
-
{required}
|
|
102
|
-
{name}
|
|
103
|
-
aria-label
|
|
104
|
-
|
|
105
|
-
style
|
|
94
|
+
{...(id ? { id } : {})}
|
|
95
|
+
{...(min !== undefined ? { min } : {})}
|
|
96
|
+
{...(max !== undefined ? { max } : {})}
|
|
97
|
+
{...(step !== undefined ? { step } : {})}
|
|
98
|
+
{...(orientation ? { orientation } : {})}
|
|
99
|
+
{...(disabled ? { disabled } : {})}
|
|
100
|
+
{...(readonly ? { readonly } : {})}
|
|
101
|
+
{...(required ? { required } : {})}
|
|
102
|
+
{...(name ? { name } : {})}
|
|
103
|
+
{...(ariaLabel || label ? { "aria-label": ariaLabel || label } : {})}
|
|
104
|
+
{...(className ? { class: className } : {})}
|
|
105
|
+
{...(style ? { style } : {})}
|
|
106
106
|
onchange={handleChange}
|
|
107
107
|
oninput={handleInput}
|
|
108
108
|
>
|
|
@@ -99,15 +99,15 @@
|
|
|
99
99
|
mere presence as `true`. -->
|
|
100
100
|
<fluent-switch
|
|
101
101
|
class={className}
|
|
102
|
-
{style}
|
|
103
|
-
{readonly}
|
|
102
|
+
{...(style ? { style } : {})}
|
|
103
|
+
{...(readonly ? { readonly } : {})}
|
|
104
104
|
id={effectiveId}
|
|
105
|
-
{disabled}
|
|
106
|
-
{autofocus}
|
|
107
|
-
{name}
|
|
108
|
-
aria-label
|
|
109
|
-
{required}
|
|
110
|
-
checked
|
|
105
|
+
{...(disabled ? { disabled } : {})}
|
|
106
|
+
{...(autofocus ? { autofocus } : {})}
|
|
107
|
+
{...(name ? { name } : {})}
|
|
108
|
+
{...(ariaLabel || label ? { "aria-label": ariaLabel || label } : {})}
|
|
109
|
+
{...(required ? { required } : {})}
|
|
110
|
+
{...(checked ? { checked } : {})}
|
|
111
111
|
aria-checked={checked ? "true" : "false"}
|
|
112
112
|
onchange={handleChange}
|
|
113
113
|
role="switch"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
}: Props = $props()
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
|
-
<fluent-tab-panel class={className} {style} {id} hidden={!active} >
|
|
26
|
+
<fluent-tab-panel class={className} {...(style ? { style } : {})} {...(id ? { id } : {})} hidden={!active} >
|
|
27
27
|
{#if children}
|
|
28
28
|
{@render children?.()}
|
|
29
29
|
{/if}
|
|
@@ -179,20 +179,20 @@
|
|
|
179
179
|
<!-- svelte-ignore a11y_autofocus -->
|
|
180
180
|
<fluent-text-field
|
|
181
181
|
bind:this={element}
|
|
182
|
-
{id}
|
|
183
|
-
{value}
|
|
184
|
-
{placeholder}
|
|
185
|
-
{appearance}
|
|
186
|
-
{disabled}
|
|
187
|
-
{readonly}
|
|
188
|
-
{required}
|
|
189
|
-
{type}
|
|
190
|
-
{name}
|
|
191
|
-
{autofocus}
|
|
192
|
-
{autocomplete}
|
|
193
|
-
{style}
|
|
194
|
-
{title}
|
|
195
|
-
|
|
182
|
+
{...(id ? { id } : {})}
|
|
183
|
+
{...(value != null ? { value } : {})}
|
|
184
|
+
{...(placeholder ? { placeholder } : {})}
|
|
185
|
+
{...(appearance ? { appearance } : {})}
|
|
186
|
+
{...(disabled ? { disabled } : {})}
|
|
187
|
+
{...(readonly ? { readonly } : {})}
|
|
188
|
+
{...(required ? { required } : {})}
|
|
189
|
+
{...(type ? { type } : {})}
|
|
190
|
+
{...(name ? { name } : {})}
|
|
191
|
+
{...(autofocus ? { autofocus } : {})}
|
|
192
|
+
{...(autocomplete ? { autocomplete } : {})}
|
|
193
|
+
{...(style ? { style } : {})}
|
|
194
|
+
{...(title ? { title } : {})}
|
|
195
|
+
{...(label || labelTemplate ? { "aria-label": label } : {})}
|
|
196
196
|
oninput={handleOnInput}
|
|
197
197
|
onchange={handleOnChange}
|
|
198
198
|
onkeydown={handleOnKeyDown}
|
|
@@ -164,26 +164,26 @@
|
|
|
164
164
|
<fluent-text-area
|
|
165
165
|
bind:this={element}
|
|
166
166
|
class={className}
|
|
167
|
-
{style}
|
|
168
|
-
{readonly}
|
|
169
|
-
{resize}
|
|
170
|
-
{autofocus}
|
|
171
|
-
autocomplete
|
|
172
|
-
{form}
|
|
173
|
-
{list}
|
|
167
|
+
{...(style ? { style } : {})}
|
|
168
|
+
{...(readonly ? { readonly } : {})}
|
|
169
|
+
{...(resize ? { resize } : {})}
|
|
170
|
+
{...(autofocus ? { autofocus } : {})}
|
|
171
|
+
{...(autocomplete ? { autocomplete } : {})}
|
|
172
|
+
{...(form ? { form } : {})}
|
|
173
|
+
{...(list ? { list } : {})}
|
|
174
174
|
{...(maxlength !== undefined ? { maxlength } : {})}
|
|
175
175
|
{...(minlength !== undefined ? { minlength } : {})}
|
|
176
|
-
{placeholder}
|
|
176
|
+
{...(placeholder ? { placeholder } : {})}
|
|
177
177
|
{...(cols !== undefined ? { cols } : {})}
|
|
178
178
|
{...(rows !== undefined ? { rows } : {})}
|
|
179
|
-
{spellcheck}
|
|
180
|
-
{id}
|
|
181
|
-
{name}
|
|
182
|
-
{disabled}
|
|
183
|
-
{required}
|
|
184
|
-
{appearance}
|
|
185
|
-
{value}
|
|
186
|
-
aria-label
|
|
179
|
+
{...(spellcheck != null ? { spellcheck } : {})}
|
|
180
|
+
{...(id ? { id } : {})}
|
|
181
|
+
{...(name ? { name } : {})}
|
|
182
|
+
{...(disabled ? { disabled } : {})}
|
|
183
|
+
{...(required ? { required } : {})}
|
|
184
|
+
{...(appearance ? { appearance } : {})}
|
|
185
|
+
{...(value != null ? { value } : {})}
|
|
186
|
+
{...(ariaLabel ? { "aria-label": ariaLabel } : {})}
|
|
187
187
|
oninput={handleInput}
|
|
188
188
|
onchange={handleChange}
|
|
189
189
|
>
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
24
|
<fluent-toolbar
|
|
25
|
-
id
|
|
25
|
+
{...(id ? { id } : {})}
|
|
26
26
|
class={className}
|
|
27
|
-
style
|
|
28
|
-
orientation
|
|
27
|
+
{...(style ? { style } : {})}
|
|
28
|
+
{...(orientation ? { orientation } : {})}
|
|
29
29
|
>
|
|
30
30
|
{#if children}
|
|
31
31
|
{@render children?.()}
|