fluentui-svelte 0.1.2 → 0.2.1
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 +0 -6
- package/dist/components/auto-suggest-box/auto-suggest-box.svelte +74 -56
- package/dist/components/auto-suggest-box/docs/llms.md +46 -13
- package/dist/components/auto-suggest-box/option.svelte +2 -1
- package/dist/components/auto-suggest-box/types.d.ts +5 -0
- package/dist/components/avatar/avatar.svelte +1 -1
- package/dist/components/avatar/docs/llms.md +20 -14
- package/dist/components/badge/badge-icon.svelte +5 -8
- package/dist/components/badge/badge.svelte +6 -2
- package/dist/components/badge/docs/llms.md +29 -16
- package/dist/components/button/button.svelte +13 -7
- package/dist/components/button/docs/llms.md +33 -24
- package/dist/components/button/types.d.ts +5 -1
- package/dist/components/calendar-date-picker/docs/llms.md +17 -7
- package/dist/components/calendar-view/calendar-view-header.svelte +2 -2
- package/dist/components/calendar-view/calendar-view-header.svelte.d.ts +2 -17
- package/dist/components/calendar-view/calendar-view-months.svelte +1 -1
- package/dist/components/calendar-view/calendar-view-years.svelte +1 -1
- package/dist/components/calendar-view/calendar-view.svelte +66 -52
- package/dist/components/calendar-view/docs/llms.md +42 -30
- package/dist/components/card/card-context.svelte.d.ts +2 -0
- package/dist/components/card/card-context.svelte.js +2 -0
- package/dist/components/card/card-footer.svelte +37 -0
- package/dist/components/card/card-footer.svelte.d.ts +4 -0
- package/dist/components/card/card-header.svelte +81 -0
- package/dist/components/card/card-header.svelte.d.ts +4 -0
- package/dist/components/card/card-preview.svelte +64 -0
- package/dist/components/card/card-preview.svelte.d.ts +4 -0
- package/dist/components/card/card.svelte +242 -0
- package/dist/components/card/card.svelte.d.ts +39 -0
- package/dist/components/card/docs/llms.md +226 -0
- package/dist/components/card/types.d.ts +129 -0
- package/dist/components/card/types.js +1 -0
- package/dist/components/checkbox/checkbox.svelte +5 -3
- package/dist/components/checkbox/docs/llms.md +18 -12
- package/dist/components/date-picker/docs/llms.md +25 -15
- package/dist/components/dialog/dialog-surface.svelte +8 -8
- package/dist/components/dialog/dialog.svelte +41 -39
- package/dist/components/dialog/docs/llms.md +59 -34
- package/dist/components/divider/docs/llms.md +14 -9
- package/dist/components/dropdown/docs/llms.md +34 -15
- package/dist/components/dropdown/dropdown.svelte +4 -2
- package/dist/components/dropdown-select/docs/llms.md +28 -14
- package/dist/components/expander/docs/llms.md +19 -12
- package/dist/components/flyout/docs/llms.md +17 -11
- package/dist/components/hyperlink/docs/llms.md +11 -7
- package/dist/components/info-bar/docs/llms.md +15 -9
- package/dist/components/label/docs/llms.md +15 -11
- package/dist/components/list-view/docs/llms.md +34 -24
- package/dist/components/list-view/list-view-item.svelte +10 -4
- package/dist/components/list-view/list-view.svelte +68 -63
- package/dist/components/menu/context-menu-trigger.svelte +45 -40
- package/dist/components/menu/docs/llms.md +63 -34
- package/dist/components/menu/menu-item-checkbox.svelte +4 -2
- package/dist/components/menu/menu-item-radio.svelte +4 -2
- package/dist/components/menu/menu-item-switch.svelte +4 -2
- package/dist/components/menu/menu-item.svelte +6 -2
- package/dist/components/menu/menu-popover.svelte +21 -10
- package/dist/components/menu/menu-trigger.svelte +22 -9
- package/dist/components/menu/menu.svelte +98 -87
- package/dist/components/number-box/docs/llms.md +10 -6
- package/dist/components/persona/docs/llms.md +19 -14
- package/dist/components/progress-bar/docs/llms.md +18 -10
- package/dist/components/progress-ring/docs/llms.md +19 -12
- package/dist/components/radio-button/docs/llms.md +13 -8
- package/dist/components/skeleton/docs/llms.md +13 -8
- package/dist/components/slider/docs/llms.md +33 -21
- package/dist/components/slider/slider.svelte +13 -11
- package/dist/components/text-box/docs/llms.md +23 -17
- package/dist/components/textarea/docs/llms.md +16 -7
- package/dist/components/time-picker/docs/llms.md +20 -10
- package/dist/components/toggle-switch/docs/llms.md +13 -9
- package/dist/components/tooltip/docs/llms.md +24 -10
- package/dist/components/tree-view/docs/llms.md +53 -35
- package/dist/components/tree-view/tree-view-item-content.svelte +1 -1
- package/dist/components/tree-view/tree-view-item.svelte +3 -3
- package/dist/components/tree-view/tree-view.svelte +89 -93
- package/dist/css/class-darkmode.css +3 -1
- package/dist/css/media-darkmode.css +3 -1
- package/dist/css/theme.css +3 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/internal/components/render-soc/render-soc.svelte +17 -23
- package/dist/internal/components/render-soc/render-soc.svelte.d.ts +16 -16
- package/dist/providers/fluentui-svelte/fluentui-svelte.svelte +15 -15
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
<script lang="ts" generics="Tag extends CardTagTypes = 'div'">
|
|
2
|
+
import type { Horientation } from '../../types/index.js';
|
|
3
|
+
import { invokeHandlers } from '../../internal/utils.js';
|
|
4
|
+
import { setCardContext } from './card-context.svelte.js';
|
|
5
|
+
import Checkbox from '../checkbox/checkbox.svelte';
|
|
6
|
+
import type { CardContext, CardProps, CardTagTypes } from './types.js';
|
|
7
|
+
import { PREFIX } from '../../internal/constants.js';
|
|
8
|
+
|
|
9
|
+
const _ID = $props.id();
|
|
10
|
+
const FALLBACK_ID = PREFIX + '-card-' + _ID;
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
as = 'div' as Tag,
|
|
14
|
+
ref = $bindable(),
|
|
15
|
+
orientation = 'horizontal',
|
|
16
|
+
id = FALLBACK_ID,
|
|
17
|
+
selectable = false,
|
|
18
|
+
showFloatingAction = false,
|
|
19
|
+
selected = $bindable(false),
|
|
20
|
+
disabled = false,
|
|
21
|
+
appearance = 'filled',
|
|
22
|
+
class: classes,
|
|
23
|
+
children,
|
|
24
|
+
onclick,
|
|
25
|
+
onSelectionChange,
|
|
26
|
+
...attributes
|
|
27
|
+
}: CardProps<Tag> = $props();
|
|
28
|
+
|
|
29
|
+
const context: CardContext = $state({
|
|
30
|
+
config: {
|
|
31
|
+
get as() {
|
|
32
|
+
return as;
|
|
33
|
+
},
|
|
34
|
+
get appearance() {
|
|
35
|
+
return appearance;
|
|
36
|
+
},
|
|
37
|
+
get selectable() {
|
|
38
|
+
return selectable;
|
|
39
|
+
},
|
|
40
|
+
get showFloatingAction() {
|
|
41
|
+
return showFloatingAction;
|
|
42
|
+
},
|
|
43
|
+
get id() {
|
|
44
|
+
return id;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
state: {
|
|
48
|
+
get selected() {
|
|
49
|
+
return selected;
|
|
50
|
+
},
|
|
51
|
+
set selected(value: boolean) {
|
|
52
|
+
selected = value;
|
|
53
|
+
},
|
|
54
|
+
get disabled() {
|
|
55
|
+
return disabled;
|
|
56
|
+
},
|
|
57
|
+
set disabled(value: boolean) {
|
|
58
|
+
disabled = value;
|
|
59
|
+
},
|
|
60
|
+
get orientation() {
|
|
61
|
+
return orientation;
|
|
62
|
+
},
|
|
63
|
+
set orientation(value: Horientation) {
|
|
64
|
+
orientation = value;
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
events: null,
|
|
68
|
+
methods: {
|
|
69
|
+
handleAction(e) {
|
|
70
|
+
if (selectable && !disabled) {
|
|
71
|
+
selected = !selected;
|
|
72
|
+
onSelectionChange?.(id, selected);
|
|
73
|
+
}
|
|
74
|
+
onclick?.(e as any);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
setCardContext(context);
|
|
80
|
+
|
|
81
|
+
let actionable = $derived(!disabled && (selectable || as === 'a'));
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The props the invariants rule over. The markup renders them through here, so reading any of
|
|
85
|
+
* them validates the whole set during SSR and on every prop update.
|
|
86
|
+
*/
|
|
87
|
+
const _card = $derived.by(() => {
|
|
88
|
+
if (showFloatingAction && !selectable)
|
|
89
|
+
throw new Error('Floating action can only be shown if the card is selectable.');
|
|
90
|
+
if (selected && !selectable) throw new Error('A card cannot be selected if it is not selectable.');
|
|
91
|
+
if (as === 'a' && selectable) throw new Error('A card cannot be both a link and selectable.');
|
|
92
|
+
return { as, selected, showFloatingAction };
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
let isLink = $derived(as === 'a');
|
|
96
|
+
|
|
97
|
+
/** The root carries the selection semantics itself when no floating checkbox is there to carry them. */
|
|
98
|
+
let isRootControl = $derived(selectable && !isLink && !_card.showFloatingAction);
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A focusable root needs an accessible name. The title of the header provides it, unless the
|
|
102
|
+
* consumer named the card itself.
|
|
103
|
+
*/
|
|
104
|
+
let rootLabelledBy = $derived(
|
|
105
|
+
isRootControl && !attributes['aria-label'] && !attributes['aria-labelledby'] ? `${id}-title` : undefined
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
/** Enter and Space toggle the selection, the same way a pointer click does. */
|
|
109
|
+
const handleKeydown = (e: KeyboardEvent) => {
|
|
110
|
+
if (e.key !== 'Enter' && e.key !== ' ') return;
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
if (e.currentTarget instanceof HTMLElement) e.currentTarget.click();
|
|
113
|
+
};
|
|
114
|
+
</script>
|
|
115
|
+
|
|
116
|
+
<!--
|
|
117
|
+
@component
|
|
118
|
+
A card is a container that displays content and actions on a single topic.
|
|
119
|
+
- Usage:
|
|
120
|
+
```tsx
|
|
121
|
+
<script>
|
|
122
|
+
import { Card, CardHeader } from 'fluentui-svelte';
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<Card>
|
|
126
|
+
<CardHeader title="Card title" />
|
|
127
|
+
<p>Content goes here</p>
|
|
128
|
+
</Card>
|
|
129
|
+
```
|
|
130
|
+
-->
|
|
131
|
+
<svelte:element
|
|
132
|
+
this={_card.as}
|
|
133
|
+
class={['fs-card', { actionable, disabled, selected: _card.selected }, orientation, appearance, classes]}
|
|
134
|
+
bind:this={ref}
|
|
135
|
+
{id}
|
|
136
|
+
role={isLink ? undefined : isRootControl ? 'checkbox' : 'group'}
|
|
137
|
+
aria-checked={isRootControl ? _card.selected : undefined}
|
|
138
|
+
aria-labelledby={rootLabelledBy}
|
|
139
|
+
aria-disabled={disabled || undefined}
|
|
140
|
+
tabindex={isRootControl && !disabled ? 0 : undefined}
|
|
141
|
+
onclick={(e: MouseEvent) => invokeHandlers(e, [disabled], [context.methods.handleAction])}
|
|
142
|
+
onkeydown={isRootControl ? handleKeydown : undefined}
|
|
143
|
+
{...attributes}
|
|
144
|
+
>
|
|
145
|
+
{#if selectable && _card.showFloatingAction && as !== 'a'}
|
|
146
|
+
<Checkbox
|
|
147
|
+
wrapperAs="div"
|
|
148
|
+
aria-labelledby={`${id}-title`}
|
|
149
|
+
bind:checked={selected}
|
|
150
|
+
{disabled}
|
|
151
|
+
onclick={(e) => e.stopPropagation()}
|
|
152
|
+
onchange={(e) => onSelectionChange?.(id, e.currentTarget.checked)}
|
|
153
|
+
/>
|
|
154
|
+
{/if}
|
|
155
|
+
{@render children?.()}
|
|
156
|
+
</svelte:element>
|
|
157
|
+
|
|
158
|
+
<style>
|
|
159
|
+
.fs-card {
|
|
160
|
+
display: flex;
|
|
161
|
+
position: relative;
|
|
162
|
+
border-radius: var(--fs-control-overlay-border-radius);
|
|
163
|
+
background-clip: padding-box;
|
|
164
|
+
color: var(--fs-text-primary);
|
|
165
|
+
transition: box-shadow var(--fs-fast-duration) var(--fs-point-to-point);
|
|
166
|
+
text-decoration: none;
|
|
167
|
+
@media (prefers-reduced-motion: reduce) {
|
|
168
|
+
transition: none;
|
|
169
|
+
}
|
|
170
|
+
&.filled {
|
|
171
|
+
background: var(--fs-card-background-default);
|
|
172
|
+
box-shadow: var(--fs-shadow-card);
|
|
173
|
+
}
|
|
174
|
+
&.filled,
|
|
175
|
+
&.outlined {
|
|
176
|
+
border: 1px solid var(--fs-control-stroke-default);
|
|
177
|
+
}
|
|
178
|
+
&.disabled {
|
|
179
|
+
user-select: none;
|
|
180
|
+
box-shadow: unset;
|
|
181
|
+
&.filled {
|
|
182
|
+
background: var(--fs-control-fill-disabled);
|
|
183
|
+
border-color: var(--fs-control-stroke-secondary);
|
|
184
|
+
color: var(--fs-text-disabled);
|
|
185
|
+
}
|
|
186
|
+
&:hover {
|
|
187
|
+
cursor: not-allowed;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
&:hover {
|
|
191
|
+
&.filled:not(.disabled) {
|
|
192
|
+
box-shadow: var(--fs-shadow-card-hover);
|
|
193
|
+
}
|
|
194
|
+
&.outlined:not(.disabled) {
|
|
195
|
+
border-color: var(--fs-control-stroke-secondary);
|
|
196
|
+
}
|
|
197
|
+
&.subtle:not(.disabled) {
|
|
198
|
+
background: var(--fs-subtle-fill-secondary);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
&:active.actionable:not(.disabled) {
|
|
202
|
+
box-shadow: unset;
|
|
203
|
+
&.filled {
|
|
204
|
+
background: var(--fs-card-background-tertiary);
|
|
205
|
+
border-color: var(--fs-control-surface-stroke-default);
|
|
206
|
+
color: var(--fs-text-secondary);
|
|
207
|
+
}
|
|
208
|
+
&.outlined {
|
|
209
|
+
border-color: var(--fs-control-surface-stroke-default);
|
|
210
|
+
color: var(--fs-text-secondary);
|
|
211
|
+
}
|
|
212
|
+
&.subtle {
|
|
213
|
+
background: var(--fs-subtle-fill-tertiary);
|
|
214
|
+
color: var(--fs-text-tertiary);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
&.actionable {
|
|
218
|
+
cursor: pointer;
|
|
219
|
+
}
|
|
220
|
+
&.selected {
|
|
221
|
+
&.filled {
|
|
222
|
+
background: var(--fs-card-background-tertiary);
|
|
223
|
+
box-shadow: var(--fs-shadow-card);
|
|
224
|
+
}
|
|
225
|
+
&.outlined {
|
|
226
|
+
background: var(--fs-card-background-default);
|
|
227
|
+
}
|
|
228
|
+
&.subtle {
|
|
229
|
+
background: var(--fs-subtle-fill-tertiary);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
&.vertical {
|
|
233
|
+
flex-direction: column;
|
|
234
|
+
}
|
|
235
|
+
& :global(.fs-checkbox) {
|
|
236
|
+
position: absolute;
|
|
237
|
+
top: 0.5rem;
|
|
238
|
+
right: 0.5rem;
|
|
239
|
+
z-index: 2;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CardProps, CardTagTypes } from './types.js';
|
|
2
|
+
declare function $$render<Tag extends CardTagTypes = 'div'>(): {
|
|
3
|
+
props: CardProps<Tag>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "ref" | "selected";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
9
|
+
declare class __sveltets_Render<Tag extends CardTagTypes = 'div'> {
|
|
10
|
+
props(): ReturnType<typeof $$render<Tag>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<Tag>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<Tag>>['slots'];
|
|
13
|
+
bindings(): "ref" | "selected";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <Tag extends CardTagTypes = 'div'>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<Tag>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<Tag>['props']>, ReturnType<__sveltets_Render<Tag>['events']>, ReturnType<__sveltets_Render<Tag>['slots']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<Tag>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<Tag>['exports']>;
|
|
20
|
+
<Tag extends CardTagTypes = 'div'>(internal: unknown, props: ReturnType<__sveltets_Render<Tag>['props']> & {}): ReturnType<__sveltets_Render<Tag>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A card is a container that displays content and actions on a single topic.
|
|
25
|
+
* - Usage:
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <script>
|
|
28
|
+
* import { Card, CardHeader } from 'fluentui-svelte';
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <Card>
|
|
32
|
+
* <CardHeader title="Card title" />
|
|
33
|
+
* <p>Content goes here</p>
|
|
34
|
+
* </Card>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare const Card: $$IsomorphicComponent;
|
|
38
|
+
type Card<Tag extends CardTagTypes = 'div'> = InstanceType<typeof Card<Tag>>;
|
|
39
|
+
export default Card;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
A card is a container that groups content and actions about a single topic, and can optionally be selected.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```svelte
|
|
8
|
+
<script>
|
|
9
|
+
import { Card, CardPreview, CardHeader, CardFooter, Button } from 'fluentui-svelte';
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{#snippet footerActions()}
|
|
13
|
+
<Button>Like</Button>
|
|
14
|
+
<Button appearance="standard">Share</Button>
|
|
15
|
+
{/snippet}
|
|
16
|
+
|
|
17
|
+
<Card orientation="vertical">
|
|
18
|
+
<CardPreview logoSrc="/logo.png">
|
|
19
|
+
<img src="/preview.png" alt="Preview" />
|
|
20
|
+
</CardPreview>
|
|
21
|
+
<CardHeader title="FluentUI Svelte" description="5h ago · About us - Overview" />
|
|
22
|
+
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
|
23
|
+
<CardFooter action={footerActions} />
|
|
24
|
+
</Card>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Component API
|
|
28
|
+
|
|
29
|
+
A card is built out of the following components:
|
|
30
|
+
|
|
31
|
+
- `Card`: the root component. It creates all the state, provides context to its parts and handles the selection.
|
|
32
|
+
- `CardPreview`: the media shown at one edge of the card, with an optional logo overlaid on it.
|
|
33
|
+
- `CardHeader`: the title of the card, with an optional image, description and action.
|
|
34
|
+
- `CardFooter`: the actions shown at the bottom of the card.
|
|
35
|
+
|
|
36
|
+
`CardPreview`, `CardHeader` and `CardFooter` read the card context, so they throw when rendered outside a `Card`.
|
|
37
|
+
They are all optional, and the card renders any other content passed to it as is.
|
|
38
|
+
|
|
39
|
+
The following combinations are rejected at runtime, because they cannot be resolved visually:
|
|
40
|
+
|
|
41
|
+
- `showFloatingAction` without `selectable`.
|
|
42
|
+
- `selected` without `selectable`.
|
|
43
|
+
- `as="a"` together with `selectable`.
|
|
44
|
+
- `action` on `CardHeader` or `CardFooter` inside a selectable card.
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
### Appearance
|
|
49
|
+
|
|
50
|
+
A card can have its background and borders styled for greater emphasis or to be subtle.
|
|
51
|
+
|
|
52
|
+
```svelte
|
|
53
|
+
<Card appearance="filled">Filled</Card>
|
|
54
|
+
<Card appearance="outlined">Outlined</Card>
|
|
55
|
+
<Card appearance="subtle">Subtle</Card>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Orientation
|
|
59
|
+
|
|
60
|
+
A card lays its parts out horizontally by default. Set `orientation` to `vertical` to stack them instead.
|
|
61
|
+
|
|
62
|
+
```svelte
|
|
63
|
+
<Card orientation="horizontal">
|
|
64
|
+
<CardPreview logoSrc="/logo.png">
|
|
65
|
+
<img src="/preview.png" alt="Preview" />
|
|
66
|
+
</CardPreview>
|
|
67
|
+
<CardHeader title="Horizontal" description="The default orientation" />
|
|
68
|
+
</Card>
|
|
69
|
+
|
|
70
|
+
<Card orientation="vertical">
|
|
71
|
+
<CardPreview logoSrc="/logo.png">
|
|
72
|
+
<img src="/preview.png" alt="Preview" />
|
|
73
|
+
</CardPreview>
|
|
74
|
+
<CardHeader title="Vertical" description="Stacks every part" />
|
|
75
|
+
</Card>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Selection
|
|
79
|
+
|
|
80
|
+
A selectable card toggles its selection when clicked anywhere, and reports it through `onSelectionChange`. Set
|
|
81
|
+
`showFloatingAction` to float a checkbox over the top right corner.
|
|
82
|
+
|
|
83
|
+
```svelte
|
|
84
|
+
<script>
|
|
85
|
+
let selected = $state(false);
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<Card selectable showFloatingAction bind:selected onSelectionChange={(id, selected) => console.log(id, selected)}>
|
|
89
|
+
<CardHeader title="Selectable card" description={selected ? 'Selected' : 'Not selected'} />
|
|
90
|
+
</Card>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Header
|
|
94
|
+
|
|
95
|
+
The header takes a `title`, and optionally an `image`, a `description` and an `action`. A string title renders inside
|
|
96
|
+
a heading; a snippet or a component receives the id the floating checkbox is labelled by.
|
|
97
|
+
|
|
98
|
+
```svelte
|
|
99
|
+
<script>
|
|
100
|
+
import { Card, CardHeader, Button } from 'fluentui-svelte';
|
|
101
|
+
import { MoreHorizontalRegular } from 'fluentui-icons-svelte';
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
{#snippet title(attrs)}
|
|
105
|
+
<h4 class="body" {...attrs}><b>FluentUI Svelte</b> mentioned you</h4>
|
|
106
|
+
{/snippet}
|
|
107
|
+
|
|
108
|
+
{#snippet action()}
|
|
109
|
+
<Button appearance="subtle" aria-label="More actions"><MoreHorizontalRegular width="1em" height="1em" /></Button>
|
|
110
|
+
{/snippet}
|
|
111
|
+
|
|
112
|
+
<Card>
|
|
113
|
+
<CardHeader image="/logo.png" {title} description="5h ago · About us - Overview" {action} />
|
|
114
|
+
</Card>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Preview
|
|
118
|
+
|
|
119
|
+
The preview holds the media of the card and rounds the corners it sits against. The `logoSrc` prop overlays a logo on
|
|
120
|
+
the bottom left corner.
|
|
121
|
+
|
|
122
|
+
```svelte
|
|
123
|
+
<Card orientation="vertical">
|
|
124
|
+
<CardPreview logoSrc="/logo.png">
|
|
125
|
+
<img src="/preview.png" alt="Preview" />
|
|
126
|
+
</CardPreview>
|
|
127
|
+
</Card>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Footer
|
|
131
|
+
|
|
132
|
+
The footer renders the actions of the card at the bottom, spread across the available width.
|
|
133
|
+
|
|
134
|
+
```svelte
|
|
135
|
+
<script>
|
|
136
|
+
import { Card, CardHeader, CardFooter, Button } from 'fluentui-svelte';
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
{#snippet action()}
|
|
140
|
+
<Button>Like</Button>
|
|
141
|
+
<Button appearance="standard">Share</Button>
|
|
142
|
+
{/snippet}
|
|
143
|
+
|
|
144
|
+
<Card orientation="vertical">
|
|
145
|
+
<CardHeader title="FluentUI Svelte" description="5h ago · About us - Overview" />
|
|
146
|
+
<CardFooter {action} />
|
|
147
|
+
</Card>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Component Props
|
|
151
|
+
|
|
152
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
153
|
+
<!-- props:CardProps -->
|
|
154
|
+
|
|
155
|
+
| Name | Type | Default | Description |
|
|
156
|
+
| --------------------- | ---------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------- |
|
|
157
|
+
| `ref` _bindable_ | `CardElementDOMType[Tag]` | | The DOM reference of the card element. |
|
|
158
|
+
| `as` | `'div'` | `'article'` | `'section'` | `'a'` | `'div'` | The DOM element to render. |
|
|
159
|
+
| `orientation` | `'horizontal'` | `'vertical'` | `'horizontal'` | The axis the card lays its parts out on. |
|
|
160
|
+
| `selectable` | `boolean` | `false` | Lets the user select the card by clicking anywhere on it. |
|
|
161
|
+
| `showFloatingAction` | `boolean` | `false` | Floats the selection checkbox over the top right corner of the card. |
|
|
162
|
+
| `id` | `string` | | The id of the card element. Falls back to a generated one. |
|
|
163
|
+
| `selected` _bindable_ | `boolean` | `false` | Whether the card is selected. Only available on selectable cards. |
|
|
164
|
+
| `disabled` | `boolean` | `false` | Disables the user interaction. |
|
|
165
|
+
| `appearance` | `'filled'` | `'outlined'` | `'subtle'` | `'filled'` | A card can have its background and borders styled for greater emphasis or to be subtle. |
|
|
166
|
+
| `onSelectionChange` | `(id: string, selected: boolean) => void` | | Called with the id of the card whenever its selection changes. |
|
|
167
|
+
| HTML Attributes | | | |
|
|
168
|
+
|
|
169
|
+
<!-- /props:CardProps -->
|
|
170
|
+
|
|
171
|
+
## CardPreview
|
|
172
|
+
|
|
173
|
+
The media shown at one edge of the card, with an optional logo overlaid on it.
|
|
174
|
+
|
|
175
|
+
### Component Props
|
|
176
|
+
|
|
177
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
178
|
+
<!-- props:CardPreviewProps -->
|
|
179
|
+
|
|
180
|
+
| Name | Type | Default | Description |
|
|
181
|
+
| --------------------------------------------------- | ---------------- | ------- | --------------------------------------------------------------------------------------- |
|
|
182
|
+
| `ref` _bindable_ | `HTMLDivElement` | | The DOM reference of the preview element. |
|
|
183
|
+
| `logoSrc` | `string` | | The URL of the logo overlaid on the bottom left corner of the preview. |
|
|
184
|
+
| `logoAlt` | `string` | `''` | The alternative text of the logo. Empty by default, which marks the logo as decorative. |
|
|
185
|
+
| `children` | `Snippet` | | The media to preview, usually an image. |
|
|
186
|
+
| `HTMLAttributes<HTMLDivElement>` without `children` | | | |
|
|
187
|
+
|
|
188
|
+
<!-- /props:CardPreviewProps -->
|
|
189
|
+
|
|
190
|
+
## CardHeader
|
|
191
|
+
|
|
192
|
+
The title of the card, with an optional image, description and action.
|
|
193
|
+
|
|
194
|
+
### Component Props
|
|
195
|
+
|
|
196
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
197
|
+
<!-- props:CardHeaderProps -->
|
|
198
|
+
|
|
199
|
+
| Name | Type | Default | Description |
|
|
200
|
+
| ------------------------------------------------------------ | -------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------- |
|
|
201
|
+
| `ref` _bindable_ | `HTMLDivElement` | | The DOM reference of the header element. |
|
|
202
|
+
| `title` | `Snippet` | `Component` | `string` | | The title of the card. A snippet or a component receives the id the floating checkbox is labelled by. |
|
|
203
|
+
| `image` | `Snippet` | `Component` | `string` | | The image rendered before the title. A string is used as the `src` of an `<img>`. |
|
|
204
|
+
| `imageAlt` | `string` | `''` | The alternative text of a string image. Empty by default, which marks the image as decorative. |
|
|
205
|
+
| `description` | `Snippet` | `Component` | `string` | | A second line of text below the title. |
|
|
206
|
+
| `action` | `Snippet` | `Component` | | The action rendered at the end of the header. Not available on selectable cards. |
|
|
207
|
+
| `HTMLAttributes<HTMLDivElement>` without `children`, `title` | | | |
|
|
208
|
+
|
|
209
|
+
<!-- /props:CardHeaderProps -->
|
|
210
|
+
|
|
211
|
+
## CardFooter
|
|
212
|
+
|
|
213
|
+
The actions shown at the bottom of the card.
|
|
214
|
+
|
|
215
|
+
### Component Props
|
|
216
|
+
|
|
217
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
218
|
+
<!-- props:CardFooterProps -->
|
|
219
|
+
|
|
220
|
+
| Name | Type | Default | Description |
|
|
221
|
+
| --------------------------------------------------- | ---------------------------- | ------- | -------------------------------------------------------------------------- |
|
|
222
|
+
| `ref` _bindable_ | `HTMLDivElement` | | The DOM reference of the footer element. |
|
|
223
|
+
| `action` | `Snippet` | `Component` | | The actions rendered inside the footer. Not available on selectable cards. |
|
|
224
|
+
| `HTMLAttributes<HTMLDivElement>` without `children` | | | |
|
|
225
|
+
|
|
226
|
+
<!-- /props:CardFooterProps -->
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Horientation, PolymorphicProps } from '../../types/index.js';
|
|
2
|
+
import type { FSContext } from '../../internal/index.js';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { Component, Snippet } from 'svelte';
|
|
5
|
+
export type CardTagTypes = 'div' | 'article' | 'section' | 'a';
|
|
6
|
+
/** @propsmith CardProps */
|
|
7
|
+
export type CardProps<Tag extends CardTagTypes = 'div'> = {
|
|
8
|
+
/** The DOM reference of the card element.
|
|
9
|
+
* @type CardElementDOMType[Tag]
|
|
10
|
+
* @bindable
|
|
11
|
+
*/
|
|
12
|
+
ref?: CardElementDOMType[Tag];
|
|
13
|
+
/** The DOM element to render.
|
|
14
|
+
* @type 'div' | 'article' | 'section' | 'a'
|
|
15
|
+
* @default 'div'
|
|
16
|
+
*/
|
|
17
|
+
as?: Tag;
|
|
18
|
+
/** The axis the card lays its parts out on.
|
|
19
|
+
* @default 'horizontal'
|
|
20
|
+
*/
|
|
21
|
+
orientation?: Horientation;
|
|
22
|
+
/** Lets the user select the card by clicking anywhere on it.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
selectable?: boolean;
|
|
26
|
+
/** Floats the selection checkbox over the top right corner of the card.
|
|
27
|
+
*
|
|
28
|
+
* Only available on selectable cards, and ignored when the card renders as a link.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
showFloatingAction?: boolean;
|
|
32
|
+
/** The id of the card element. Falls back to a generated one. */
|
|
33
|
+
id?: string;
|
|
34
|
+
/** Whether the card is selected. Only available on selectable cards.
|
|
35
|
+
* @default false
|
|
36
|
+
* @bindable
|
|
37
|
+
*/
|
|
38
|
+
selected?: boolean;
|
|
39
|
+
/** Disables the user interaction.
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
/** A card can have its background and borders styled for greater emphasis or to be subtle.
|
|
44
|
+
* @default 'filled'
|
|
45
|
+
*/
|
|
46
|
+
appearance?: 'filled' | 'outlined' | 'subtle';
|
|
47
|
+
/** Called with the id of the card whenever its selection changes.
|
|
48
|
+
* @type (id: string, selected: boolean) => void
|
|
49
|
+
*/
|
|
50
|
+
onSelectionChange?: (id: string, selected: boolean) => void;
|
|
51
|
+
} & PolymorphicProps<Tag>;
|
|
52
|
+
export type CardElementDOMType = {
|
|
53
|
+
div: HTMLDivElement;
|
|
54
|
+
article: HTMLElement;
|
|
55
|
+
section: HTMLElement;
|
|
56
|
+
a: HTMLAnchorElement;
|
|
57
|
+
};
|
|
58
|
+
export type CardContext = FSContext<{
|
|
59
|
+
readonly as?: CardTagTypes;
|
|
60
|
+
readonly showFloatingAction?: boolean;
|
|
61
|
+
readonly appearance?: 'filled' | 'outlined' | 'subtle';
|
|
62
|
+
readonly selectable?: boolean;
|
|
63
|
+
/** The id of the card, which every part uses to build its own ids. */
|
|
64
|
+
readonly id?: string;
|
|
65
|
+
}, {
|
|
66
|
+
orientation?: Horientation;
|
|
67
|
+
selected?: boolean;
|
|
68
|
+
disabled?: boolean;
|
|
69
|
+
}, null, {
|
|
70
|
+
/** Toggles the selection and forwards the click to the consumer. */
|
|
71
|
+
handleAction?: (e: MouseEvent) => void;
|
|
72
|
+
}>;
|
|
73
|
+
/** @propsmith CardPreviewProps */
|
|
74
|
+
export type CardPreviewProps = {
|
|
75
|
+
/** The DOM reference of the preview element.
|
|
76
|
+
* @bindable
|
|
77
|
+
*/
|
|
78
|
+
ref?: HTMLDivElement;
|
|
79
|
+
/** The URL of the logo overlaid on the bottom left corner of the preview. */
|
|
80
|
+
logoSrc: string;
|
|
81
|
+
/** The alternative text of the logo. Empty by default, which marks the logo as decorative.
|
|
82
|
+
* @default ''
|
|
83
|
+
*/
|
|
84
|
+
logoAlt?: string;
|
|
85
|
+
/** The media to preview, usually an image. */
|
|
86
|
+
children?: Snippet;
|
|
87
|
+
} & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
|
|
88
|
+
/** @propsmith CardHeaderProps */
|
|
89
|
+
export type CardHeaderProps = {
|
|
90
|
+
/** The DOM reference of the header element.
|
|
91
|
+
* @bindable
|
|
92
|
+
*/
|
|
93
|
+
ref?: HTMLDivElement;
|
|
94
|
+
/** The title of the card. A snippet or a component receives the id the floating checkbox is labelled by.
|
|
95
|
+
* @type Snippet | Component | string
|
|
96
|
+
*/
|
|
97
|
+
title: Snippet<[attrs: {
|
|
98
|
+
id: string;
|
|
99
|
+
}]> | Component<{
|
|
100
|
+
id: string;
|
|
101
|
+
}> | string;
|
|
102
|
+
/** The image rendered before the title. A string is used as the `src` of an `<img>`.
|
|
103
|
+
* @type Snippet | Component | string
|
|
104
|
+
*/
|
|
105
|
+
image?: Snippet | Component | string;
|
|
106
|
+
/** The alternative text of a string image. Empty by default, which marks the image as decorative.
|
|
107
|
+
* @default ''
|
|
108
|
+
*/
|
|
109
|
+
imageAlt?: string;
|
|
110
|
+
/** A second line of text below the title.
|
|
111
|
+
* @type Snippet | Component | string
|
|
112
|
+
*/
|
|
113
|
+
description?: Snippet | Component | string;
|
|
114
|
+
/** The action rendered at the end of the header. Not available on selectable cards.
|
|
115
|
+
* @type Snippet | Component
|
|
116
|
+
*/
|
|
117
|
+
action?: Snippet | Component;
|
|
118
|
+
} & Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'title'>;
|
|
119
|
+
/** @propsmith CardFooterProps */
|
|
120
|
+
export type CardFooterProps = {
|
|
121
|
+
/** The DOM reference of the footer element.
|
|
122
|
+
* @bindable
|
|
123
|
+
*/
|
|
124
|
+
ref?: HTMLDivElement;
|
|
125
|
+
/** The actions rendered inside the footer. Not available on selectable cards.
|
|
126
|
+
* @type Snippet | Component
|
|
127
|
+
*/
|
|
128
|
+
action?: Snippet | Component;
|
|
129
|
+
} & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -101,8 +101,8 @@
|
|
|
101
101
|
-moz-appearance: none;
|
|
102
102
|
&:indeterminate + div :global(svg.indeterminate),
|
|
103
103
|
&:checked + div :global(svg.checked) {
|
|
104
|
-
|
|
105
|
-
transition: var(--fs-slower-duration, 1s) cubic-bezier(0.55, 0, 0, 1)
|
|
104
|
+
mask-size: 100% 100%;
|
|
105
|
+
transition: var(--fs-slower-duration, 1s) cubic-bezier(0.55, 0, 0, 1) mask-size;
|
|
106
106
|
}
|
|
107
107
|
&:is(:checked, :indeterminate) {
|
|
108
108
|
& + div {
|
|
@@ -148,7 +148,9 @@
|
|
|
148
148
|
width: 0;
|
|
149
149
|
fill: var(--fs-text-on-accent-primary);
|
|
150
150
|
transform-origin: 80% 20%;
|
|
151
|
-
|
|
151
|
+
mask-image: linear-gradient(black, black);
|
|
152
|
+
mask-repeat: no-repeat;
|
|
153
|
+
mask-size: 0% 100%;
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
&:has(input:disabled) {
|