fluentui-svelte 0.4.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/README.md +1 -1
- package/dist/components/auto-suggest-box/docs/llms.md +76 -15
- package/dist/components/card/card-header.svelte +2 -2
- package/dist/components/dialog/dialog-actions.svelte +17 -2
- package/dist/components/dialog/dialog-content.svelte +2 -2
- package/dist/components/dialog/dialog-content.svelte.d.ts +1 -1
- package/dist/components/dialog/dialog-surface.svelte +32 -3
- package/dist/components/dialog/dialog-title.svelte +23 -6
- package/dist/components/dialog/dialog-trigger.svelte +8 -2
- package/dist/components/dialog/dialog-trigger.svelte.d.ts +1 -1
- package/dist/components/dialog/docs/llms.md +2 -2
- package/dist/components/dialog/types.d.ts +6 -2
- package/dist/components/dialog/utils.d.ts +2 -0
- package/dist/components/dialog/utils.js +1 -0
- package/dist/components/dropdown/dropdown.svelte +1 -0
- package/dist/components/list-view/docs/llms.md +79 -27
- package/dist/components/list-view/list-view-item.svelte +14 -11
- package/dist/components/list-view/list-view.svelte +3 -2
- package/dist/components/list-view/types.d.ts +5 -1
- package/dist/components/menu/docs/llms.md +16 -0
- package/dist/components/menu/menu-popover.svelte +7 -12
- package/dist/components/menu/menu-popover.svelte.d.ts +2 -10
- package/dist/components/menu/types.d.ts +21 -0
- package/dist/components/rating/docs/llms.md +110 -0
- package/dist/components/rating/rating.svelte +210 -0
- package/dist/components/rating/rating.svelte.d.ts +19 -0
- package/dist/components/rating/types.d.ts +44 -0
- package/dist/components/rating/types.js +1 -0
- package/dist/components/tag/docs/llms.md +383 -0
- package/dist/components/tag/tag-group.d.ts +2 -0
- package/dist/components/tag/tag-group.js +2 -0
- package/dist/components/tag/tag-group.svelte +117 -0
- package/dist/components/tag/tag-group.svelte.d.ts +20 -0
- package/dist/components/tag/tag.svelte +458 -0
- package/dist/components/tag/tag.svelte.d.ts +19 -0
- package/dist/components/tag/types.d.ts +135 -0
- package/dist/components/tag/types.js +1 -0
- package/dist/components/tag-picker/docs/llms.md +292 -0
- package/dist/components/tag-picker/option-group.svelte +38 -0
- package/dist/components/tag-picker/option-group.svelte.d.ts +4 -0
- package/dist/components/tag-picker/option.svelte +71 -0
- package/dist/components/tag-picker/option.svelte.d.ts +4 -0
- package/dist/components/tag-picker/tag-picker.d.ts +2 -0
- package/dist/components/tag-picker/tag-picker.js +2 -0
- package/dist/components/tag-picker/tag-picker.svelte +644 -0
- package/dist/components/tag-picker/tag-picker.svelte.d.ts +21 -0
- package/dist/components/tag-picker/types.d.ts +122 -0
- package/dist/components/tag-picker/types.js +1 -0
- package/dist/components/tree-view/docs/llms.md +166 -1
- package/dist/components/tree-view/tree-view-item-content.svelte +41 -8
- package/dist/components/tree-view/tree-view-item.svelte +10 -1
- package/dist/components/tree-view/tree-view.svelte +17 -2
- package/dist/components/tree-view/tree-view.svelte.js +4 -2
- package/dist/components/tree-view/types.d.ts +4 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +12 -0
- package/dist/internal/constants.d.ts +0 -4
- package/dist/internal/constants.js +0 -4002
- package/package.json +3 -2
|
@@ -140,6 +140,22 @@ This variant of the `MenuTrigger` component allows you to create context menus t
|
|
|
140
140
|
|
|
141
141
|
<!-- /props:MenuProps -->
|
|
142
142
|
|
|
143
|
+
## Component Props (MenuPopover)
|
|
144
|
+
|
|
145
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
146
|
+
<!-- props:MenuPopoverProps -->
|
|
147
|
+
|
|
148
|
+
| Name | Type | Default | Description |
|
|
149
|
+
| ----------------- | ------------------------------------ | ------- | -------------------------------------------------------- |
|
|
150
|
+
| `ref` | `HTMLElement` | | The element used to position the popover. |
|
|
151
|
+
| `open` _bindable_ | `boolean` | | Controls the open state of the popover. |
|
|
152
|
+
| `keepMounted` | `boolean` | `false` | Keeps the popover mounted in the DOM while it is closed. |
|
|
153
|
+
| `placement` | `ComputePositionConfig['placement']` | | Where the popover is positioned relative to its trigger. |
|
|
154
|
+
| `positionConfig` | `ComputePositionConfig` | | The position configuration handed over to floating-ui. |
|
|
155
|
+
| `children` | `Snippet` | | The content of the popover. |
|
|
156
|
+
|
|
157
|
+
<!-- /props:MenuPopoverProps -->
|
|
158
|
+
|
|
143
159
|
## Component Props (MenuTrigger)
|
|
144
160
|
|
|
145
161
|
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
import { useDebounce } from 'runed';
|
|
7
7
|
import { floating, flyToOffset, getCSSDuration, reactiveBoundingRect } from '../../internal/index.js';
|
|
8
8
|
import { getReducedMotion } from '../../providers/fluentui-svelte/fluentui-svelte.js';
|
|
9
|
-
import type {
|
|
10
|
-
import type { ComputePositionConfig } from '@floating-ui/dom';
|
|
9
|
+
import type { MenuPopoverProps } from './types.js';
|
|
11
10
|
|
|
12
11
|
let {
|
|
13
12
|
ref: _ref,
|
|
14
13
|
open: _open = $bindable(),
|
|
14
|
+
keepMounted = false,
|
|
15
15
|
placement,
|
|
16
16
|
positionConfig: floatingPosition = {
|
|
17
17
|
placement,
|
|
@@ -19,13 +19,7 @@
|
|
|
19
19
|
strategy: 'fixed'
|
|
20
20
|
},
|
|
21
21
|
children
|
|
22
|
-
}:
|
|
23
|
-
ref?: HTMLElement;
|
|
24
|
-
open?: boolean;
|
|
25
|
-
placement?: ComputePositionConfig['placement'];
|
|
26
|
-
positionConfig?: Partial<ComputePositionConfig>;
|
|
27
|
-
children: Snippet;
|
|
28
|
-
} = $props();
|
|
22
|
+
}: MenuPopoverProps = $props();
|
|
29
23
|
|
|
30
24
|
const context = getMenuContext();
|
|
31
25
|
|
|
@@ -90,16 +84,17 @@
|
|
|
90
84
|
});
|
|
91
85
|
</script>
|
|
92
86
|
|
|
93
|
-
{#if opened && ref}
|
|
87
|
+
{#if keepMounted || (opened && ref)}
|
|
94
88
|
{@const isRefAnElement = ref instanceof HTMLElement}
|
|
95
89
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
96
90
|
<div
|
|
97
91
|
bind:this={element}
|
|
98
92
|
class="fs-menu-popover"
|
|
93
|
+
hidden={!opened}
|
|
99
94
|
onmouseleave={openOnHover ? (e: MouseEvent) => debounced(e) : undefined}
|
|
100
|
-
{@attach ref ? floating(ref, config) : undefined}
|
|
95
|
+
{@attach opened && ref ? floating(ref, config) : undefined}
|
|
101
96
|
style={`--position=${isSubMenu ? 'absolute' : 'fixed'} --min-width=${isRefAnElement && !isSubMenu ? `${boundingElement.rect.width}px` : 'max-content'}`}
|
|
102
|
-
in:flyToOffset={isRefAnElement
|
|
97
|
+
in:flyToOffset={opened && isRefAnElement
|
|
103
98
|
? {
|
|
104
99
|
...getIntroTransition({ config, anchor: boundingElement.rect, element, ref, isSubMenu }),
|
|
105
100
|
duration: duration,
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
type $$ComponentProps = {
|
|
4
|
-
ref?: HTMLElement;
|
|
5
|
-
open?: boolean;
|
|
6
|
-
placement?: ComputePositionConfig['placement'];
|
|
7
|
-
positionConfig?: Partial<ComputePositionConfig>;
|
|
8
|
-
children: Snippet;
|
|
9
|
-
};
|
|
10
|
-
declare const MenuPopover: import("svelte").Component<$$ComponentProps, {}, "open">;
|
|
1
|
+
import type { MenuPopoverProps } from './types.ts';
|
|
2
|
+
declare const MenuPopover: import("svelte").Component<MenuPopoverProps, {}, "open">;
|
|
11
3
|
type MenuPopover = ReturnType<typeof MenuPopover>;
|
|
12
4
|
export default MenuPopover;
|
|
@@ -59,6 +59,27 @@ export type MenuProps = {
|
|
|
59
59
|
/** The parts of the menu: a trigger and a popover. */
|
|
60
60
|
children?: Snippet;
|
|
61
61
|
};
|
|
62
|
+
/** @propsmith MenuPopoverProps */
|
|
63
|
+
export type MenuPopoverProps = {
|
|
64
|
+
/** The element used to position the popover. */
|
|
65
|
+
ref?: HTMLElement;
|
|
66
|
+
/** Controls the open state of the popover.
|
|
67
|
+
* @bindable
|
|
68
|
+
*/
|
|
69
|
+
open?: boolean;
|
|
70
|
+
/** Keeps the popover mounted in the DOM while it is closed.
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
keepMounted?: boolean;
|
|
74
|
+
/** Where the popover is positioned relative to its trigger. */
|
|
75
|
+
placement?: ComputePositionConfig['placement'];
|
|
76
|
+
/** The position configuration handed over to floating-ui.
|
|
77
|
+
* @type ComputePositionConfig
|
|
78
|
+
*/
|
|
79
|
+
positionConfig?: Partial<ComputePositionConfig>;
|
|
80
|
+
/** The content of the popover. */
|
|
81
|
+
children: Snippet;
|
|
82
|
+
};
|
|
62
83
|
/** @propsmith MenuTriggerProps */
|
|
63
84
|
export type MenuTriggerProps = {
|
|
64
85
|
/** Disables the user interaction. */
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Rating
|
|
2
|
+
|
|
3
|
+
A rating lets users give a value to an item by selecting one of a row of stars. It supports half-filled stars, four sizes and a custom number of items.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```svelte
|
|
8
|
+
<script>
|
|
9
|
+
import { Rating } from 'fluentui-svelte';
|
|
10
|
+
|
|
11
|
+
let value = $state(3);
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<Rating bind:value />
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Component API
|
|
18
|
+
|
|
19
|
+
A rating lets users give a value to an item, using a row of symbols such as stars. It supports half-filled items and four sizes.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
### Bind the value
|
|
24
|
+
|
|
25
|
+
Use `bind:value` to read the rating the user picks.
|
|
26
|
+
|
|
27
|
+
```svelte
|
|
28
|
+
<script>
|
|
29
|
+
let value = $state(3);
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<Rating bind:value />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Half stars
|
|
36
|
+
|
|
37
|
+
Set `step={0.5}` to let users pick half-filled stars.
|
|
38
|
+
|
|
39
|
+
```svelte
|
|
40
|
+
<Rating value={2.5} step={0.5} />
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Quarter stars
|
|
44
|
+
|
|
45
|
+
Until the user rates, a fractional `value` is drawn in quarters, which is handy to show an average. Once the user picks a star, the rating snaps to the `step`.
|
|
46
|
+
|
|
47
|
+
```svelte
|
|
48
|
+
<Rating value={3.75} />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Size
|
|
52
|
+
|
|
53
|
+
Use `size` to choose between `small`, `medium`, `large` and `extra-large`.
|
|
54
|
+
|
|
55
|
+
```svelte
|
|
56
|
+
<Rating value={3} size="small" />
|
|
57
|
+
<Rating value={3} size="medium" />
|
|
58
|
+
<Rating value={3} size="large" />
|
|
59
|
+
<Rating value={3} size="extra-large" />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Shape
|
|
63
|
+
|
|
64
|
+
Use `iconFilled` and `iconOutline` to replace the stars with any other icon component. Both fall back to the star when omitted, and partially filled items are clipped, so custom shapes also work with `step={0.5}`.
|
|
65
|
+
|
|
66
|
+
```svelte
|
|
67
|
+
<script>
|
|
68
|
+
import { HeartFilled, HeartRegular } from 'fluentui-icons-svelte';
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<Rating value={3} iconFilled={HeartFilled} iconOutline={HeartRegular} />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Max
|
|
75
|
+
|
|
76
|
+
Use `max` to change the number of stars.
|
|
77
|
+
|
|
78
|
+
```svelte
|
|
79
|
+
<Rating value={4} max={10} />
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Item label
|
|
83
|
+
|
|
84
|
+
Use `itemLabel` to customize the accessible label of each radio input.
|
|
85
|
+
|
|
86
|
+
```svelte
|
|
87
|
+
<Rating value={3} itemLabel={(rating) => `${rating} out of 5 stars`} />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Component Props
|
|
91
|
+
|
|
92
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
93
|
+
<!-- props:RatingProps -->
|
|
94
|
+
|
|
95
|
+
| Name | Type | Default | Description |
|
|
96
|
+
| --------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `value` _bindable_ | `number` | `0` | The current rating. Fractions are drawn in quarters until the user rates. |
|
|
98
|
+
| `max` | `number` | `5` | The number of items displayed. Must be a whole number greater than 1. |
|
|
99
|
+
| `step` | `1` | `0.5` | `1` | The precision of the rating. `0.5` allows half-filled items. |
|
|
100
|
+
| `size` | `'small'` | `'medium'` | `'large'` | `'extra-large'` | `'extra-large'` | The size of the rating items. |
|
|
101
|
+
| `iconFilled` | `Component` | | The icon of a filled item. Falls back to a filled star. Partially filled items are clipped, so it also works with half steps. |
|
|
102
|
+
| `iconOutline` | `Component` | | The icon of an empty item. Falls back to an outlined star. |
|
|
103
|
+
| `name` | `string` | | The name of the radio inputs. Generated when not provided. |
|
|
104
|
+
| `itemLabel` | `(rating: number) => string` | `` (rating) => `${rating}` `` | Generates the accessible label of the radio input for a rating value. |
|
|
105
|
+
| `onChange` | `(value: number) => void` | | Called when the user changes the rating. |
|
|
106
|
+
| `class` | `string` | | The class to apply to the rating. |
|
|
107
|
+
| `ref` _bindable_ | `HTMLElement` | | The DOM reference of the rating element. |
|
|
108
|
+
| `HTMLAttributes<HTMLDivElement>` without `onchange` | | | |
|
|
109
|
+
|
|
110
|
+
<!-- /props:RatingProps -->
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PREFIX } from '../../internal/constants.js';
|
|
3
|
+
import StarFilled from 'fluentui-icons-svelte/StarFilled.svelte';
|
|
4
|
+
import StarHalfFilled from 'fluentui-icons-svelte/StarHalfFilled.svelte';
|
|
5
|
+
import StarOneQuarterFilled from 'fluentui-icons-svelte/StarOneQuarterFilled.svelte';
|
|
6
|
+
import StarRegular from 'fluentui-icons-svelte/StarRegular.svelte';
|
|
7
|
+
import StarThreeQuarterFilled from 'fluentui-icons-svelte/StarThreeQuarterFilled.svelte';
|
|
8
|
+
import type { RatingProps } from './types.js';
|
|
9
|
+
|
|
10
|
+
const FALLBACK_ID = $props.id();
|
|
11
|
+
const COMPONENT_NAME = 'rating';
|
|
12
|
+
const ID = `${PREFIX}${COMPONENT_NAME}-${FALLBACK_ID}`;
|
|
13
|
+
const VALUE_ID = `${ID}-value`;
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
value = $bindable(0),
|
|
17
|
+
max = 5,
|
|
18
|
+
step = 1,
|
|
19
|
+
size = 'extra-large',
|
|
20
|
+
iconFilled,
|
|
21
|
+
iconOutline,
|
|
22
|
+
name = ID,
|
|
23
|
+
itemLabel = (rating) => `${rating}`,
|
|
24
|
+
onChange,
|
|
25
|
+
class: classes,
|
|
26
|
+
ref = $bindable(),
|
|
27
|
+
role = 'radiogroup',
|
|
28
|
+
...attributes
|
|
29
|
+
}: RatingProps = $props();
|
|
30
|
+
|
|
31
|
+
/** Until the user rates, the value is only displayed, so it is drawn with the precision of a quarter. */
|
|
32
|
+
let rated = $state(false);
|
|
33
|
+
let hovered = $state<number>();
|
|
34
|
+
|
|
35
|
+
const _max = $derived.by(() => {
|
|
36
|
+
if (!Number.isInteger(max) || max <= 1) throw new Error('Max must be a whole number greater than 1');
|
|
37
|
+
return max;
|
|
38
|
+
});
|
|
39
|
+
const items = $derived(Array.from({ length: _max }, (_, index) => index + 1));
|
|
40
|
+
const shown = $derived(hovered ?? value);
|
|
41
|
+
const checkedValue = $derived(value === 0 ? 0 : Math.min(_max, Math.max(step, Math.round(value / step) * step)));
|
|
42
|
+
|
|
43
|
+
const custom = $derived(!!(iconFilled || iconOutline));
|
|
44
|
+
|
|
45
|
+
/** How much of the item is filled, snapped to the precision it is shown with. */
|
|
46
|
+
function fillFor(item: number) {
|
|
47
|
+
const fill = Math.min(Math.max(shown - (item - 1), 0), 1);
|
|
48
|
+
const precision = hovered !== undefined || rated ? step / 2 : 0.25;
|
|
49
|
+
return Math.round(fill / precision) * precision;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function iconFor(snapped: number) {
|
|
53
|
+
if (snapped >= 1) return StarFilled;
|
|
54
|
+
if (snapped >= 0.75) return StarThreeQuarterFilled;
|
|
55
|
+
if (snapped >= 0.5) return StarHalfFilled;
|
|
56
|
+
if (snapped >= 0.25) return StarOneQuarterFilled;
|
|
57
|
+
return StarRegular;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function select(next: number) {
|
|
61
|
+
rated = true;
|
|
62
|
+
value = next;
|
|
63
|
+
onChange?.(next);
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<!--
|
|
68
|
+
@component
|
|
69
|
+
A rating lets users give a value to an item, using a row of symbols such as stars. It supports half-filled items and four sizes.
|
|
70
|
+
|
|
71
|
+
- Usage:
|
|
72
|
+
```tsx
|
|
73
|
+
<script>
|
|
74
|
+
import { Rating } from 'fluentui-svelte';
|
|
75
|
+
|
|
76
|
+
let value = $state(3);
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<Rating bind:value />
|
|
80
|
+
<Rating bind:value step={0.5} size="medium" />
|
|
81
|
+
```
|
|
82
|
+
-->
|
|
83
|
+
<div
|
|
84
|
+
class={['fs-rating', `size-${size}`, classes]}
|
|
85
|
+
bind:this={ref}
|
|
86
|
+
{role}
|
|
87
|
+
onpointerleave={() => (hovered = undefined)}
|
|
88
|
+
{...attributes}
|
|
89
|
+
aria-label={attributes['aria-label'] ?? (attributes['aria-labelledby'] ? undefined : 'Rating')}
|
|
90
|
+
aria-describedby={[attributes['aria-describedby'], VALUE_ID].filter(Boolean).join(' ')}
|
|
91
|
+
>
|
|
92
|
+
<span id={VALUE_ID} hidden>Current rating: {value} out of {_max}.</span>
|
|
93
|
+
{#each items as item (item)}
|
|
94
|
+
{@const fill = fillFor(item)}
|
|
95
|
+
<span class="rating-item">
|
|
96
|
+
{#if custom}
|
|
97
|
+
{@const Outline = iconOutline ?? StarRegular}
|
|
98
|
+
{@const Filled = iconFilled ?? StarFilled}
|
|
99
|
+
<span class="rating-icon custom" class:selected={fill > 0} style="--rating-fill: {fill * 100}%">
|
|
100
|
+
<Outline aria-hidden="true" />
|
|
101
|
+
<span class="filled"><Filled aria-hidden="true" /></span>
|
|
102
|
+
</span>
|
|
103
|
+
{:else}
|
|
104
|
+
{@const Icon = iconFor(fill)}
|
|
105
|
+
<span class="rating-icon" class:selected={fill > 0}><Icon aria-hidden="true" /></span>
|
|
106
|
+
{/if}
|
|
107
|
+
{#if step === 0.5}
|
|
108
|
+
<input
|
|
109
|
+
class="half-value"
|
|
110
|
+
type="radio"
|
|
111
|
+
{name}
|
|
112
|
+
value={item - 0.5}
|
|
113
|
+
checked={checkedValue === item - 0.5}
|
|
114
|
+
aria-label={itemLabel(item - 0.5)}
|
|
115
|
+
onclick={() => value !== item - 0.5 && select(item - 0.5)}
|
|
116
|
+
onpointerenter={() => (hovered = item - 0.5)}
|
|
117
|
+
/>
|
|
118
|
+
{/if}
|
|
119
|
+
<input
|
|
120
|
+
class="full-value"
|
|
121
|
+
type="radio"
|
|
122
|
+
{name}
|
|
123
|
+
value={item}
|
|
124
|
+
checked={checkedValue === item}
|
|
125
|
+
aria-label={itemLabel(item)}
|
|
126
|
+
onclick={() => value !== item && select(item)}
|
|
127
|
+
onpointerenter={() => (hovered = item)}
|
|
128
|
+
/>
|
|
129
|
+
</span>
|
|
130
|
+
{/each}
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<style>
|
|
134
|
+
.fs-rating {
|
|
135
|
+
--rating-size: 24px;
|
|
136
|
+
display: inline-flex;
|
|
137
|
+
align-items: center;
|
|
138
|
+
color: var(--fs-accent-fill-default);
|
|
139
|
+
|
|
140
|
+
&.size-small {
|
|
141
|
+
--rating-size: 12px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&.size-medium {
|
|
145
|
+
--rating-size: 16px;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
&.size-large {
|
|
149
|
+
--rating-size: 20px;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.rating-item {
|
|
154
|
+
display: inline-flex;
|
|
155
|
+
position: relative;
|
|
156
|
+
border-radius: var(--fs-control-border-radius);
|
|
157
|
+
padding: 2px;
|
|
158
|
+
|
|
159
|
+
&:has(input:focus-visible) {
|
|
160
|
+
box-shadow: var(--fs-focus-stroke-outer);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
& input {
|
|
164
|
+
appearance: none;
|
|
165
|
+
position: absolute;
|
|
166
|
+
inset-block: 0;
|
|
167
|
+
inset-inline-start: 0;
|
|
168
|
+
margin: 0;
|
|
169
|
+
outline: none;
|
|
170
|
+
cursor: pointer;
|
|
171
|
+
inline-size: 100%;
|
|
172
|
+
block-size: 100%;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
& .half-value {
|
|
176
|
+
z-index: 1;
|
|
177
|
+
inline-size: 50%;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.rating-icon {
|
|
182
|
+
display: inline-flex;
|
|
183
|
+
color: var(--fs-text-secondary);
|
|
184
|
+
|
|
185
|
+
&.selected {
|
|
186
|
+
color: var(--fs-accent-fill-default);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
& :global(svg) {
|
|
190
|
+
inline-size: var(--rating-size);
|
|
191
|
+
block-size: var(--rating-size);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&.custom {
|
|
195
|
+
position: relative;
|
|
196
|
+
|
|
197
|
+
& .filled {
|
|
198
|
+
display: inline-flex;
|
|
199
|
+
position: absolute;
|
|
200
|
+
inset: 0;
|
|
201
|
+
color: var(--fs-accent-fill-default);
|
|
202
|
+
clip-path: inset(0 calc(100% - var(--rating-fill)) 0 0);
|
|
203
|
+
|
|
204
|
+
&:dir(rtl) {
|
|
205
|
+
clip-path: inset(0 0 0 calc(100% - var(--rating-fill)));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RatingProps } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A rating lets users give a value to an item, using a row of symbols such as stars. It supports half-filled items and four sizes.
|
|
4
|
+
*
|
|
5
|
+
* - Usage:
|
|
6
|
+
* ```tsx
|
|
7
|
+
* <script>
|
|
8
|
+
* import { Rating } from 'fluentui-svelte';
|
|
9
|
+
*
|
|
10
|
+
* let value = $state(3);
|
|
11
|
+
* </script>
|
|
12
|
+
*
|
|
13
|
+
* <Rating bind:value />
|
|
14
|
+
* <Rating bind:value step={0.5} size="medium" />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare const Rating: import("svelte").Component<RatingProps, {}, "ref" | "value">;
|
|
18
|
+
type Rating = ReturnType<typeof Rating>;
|
|
19
|
+
export default Rating;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
/** @propsmith RatingProps */
|
|
4
|
+
export type RatingProps = {
|
|
5
|
+
/** The current rating. Fractions are drawn in quarters until the user rates.
|
|
6
|
+
* @default 0
|
|
7
|
+
* @bindable
|
|
8
|
+
*/
|
|
9
|
+
value?: number;
|
|
10
|
+
/** The number of items displayed. Must be a whole number greater than 1.
|
|
11
|
+
* @default 5
|
|
12
|
+
*/
|
|
13
|
+
max?: number;
|
|
14
|
+
/** The precision of the rating. `0.5` allows half-filled items.
|
|
15
|
+
* @default 1
|
|
16
|
+
*/
|
|
17
|
+
step?: 1 | 0.5;
|
|
18
|
+
/** The size of the rating items.
|
|
19
|
+
* @default 'extra-large'
|
|
20
|
+
*/
|
|
21
|
+
size?: 'small' | 'medium' | 'large' | 'extra-large';
|
|
22
|
+
/** The icon of a filled item. Falls back to a filled star. Partially filled items are clipped, so it also works with half steps.
|
|
23
|
+
* @type Component
|
|
24
|
+
*/
|
|
25
|
+
iconFilled?: Component;
|
|
26
|
+
/** The icon of an empty item. Falls back to an outlined star.
|
|
27
|
+
* @type Component
|
|
28
|
+
*/
|
|
29
|
+
iconOutline?: Component;
|
|
30
|
+
/** The name of the radio inputs. Generated when not provided. */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** Generates the accessible label of the radio input for a rating value.
|
|
33
|
+
* @default (rating) => `${rating}`
|
|
34
|
+
*/
|
|
35
|
+
itemLabel?: (rating: number) => string;
|
|
36
|
+
/** Called when the user changes the rating. */
|
|
37
|
+
onChange?: (value: number) => void;
|
|
38
|
+
/** The class to apply to the rating. */
|
|
39
|
+
class?: string;
|
|
40
|
+
/** The DOM reference of the rating element.
|
|
41
|
+
* @bindable
|
|
42
|
+
*/
|
|
43
|
+
ref?: HTMLElement;
|
|
44
|
+
} & Omit<HTMLAttributes<HTMLDivElement>, 'onchange'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|