fluentui-svelte 0.3.0 → 0.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/dist/components/breadcrumb/breadcrumb-button.svelte +130 -0
- package/dist/components/breadcrumb/breadcrumb-button.svelte.d.ts +35 -0
- package/dist/components/breadcrumb/breadcrumb-divider.svelte +39 -0
- package/dist/components/breadcrumb/breadcrumb-divider.svelte.d.ts +14 -0
- package/dist/components/breadcrumb/breadcrumb-item.svelte +30 -0
- package/dist/components/breadcrumb/breadcrumb-item.svelte.d.ts +16 -0
- package/dist/components/breadcrumb/breadcrumb.svelte +101 -0
- package/dist/components/breadcrumb/breadcrumb.svelte.d.ts +25 -0
- package/dist/components/breadcrumb/docs/llms.md +193 -0
- package/dist/components/breadcrumb/types.d.ts +80 -0
- package/dist/components/breadcrumb/types.js +1 -0
- package/dist/components/tab-view/docs/llms.md +146 -0
- package/dist/components/tab-view/tab-view-tab.svelte +290 -0
- package/dist/components/tab-view/tab-view-tab.svelte.d.ts +20 -0
- package/dist/components/tab-view/tab-view.svelte +188 -0
- package/dist/components/tab-view/tab-view.svelte.d.ts +26 -0
- package/dist/components/tab-view/tab-view.svelte.js +15 -0
- package/dist/components/tab-view/types.d.ts +79 -0
- package/dist/components/tab-view/types.js +1 -0
- package/dist/components/top-nav/docs/llms.md +176 -0
- package/dist/components/top-nav/top-nav-item.svelte +234 -0
- package/dist/components/top-nav/top-nav-item.svelte.d.ts +41 -0
- package/dist/components/top-nav/top-nav.svelte +259 -0
- package/dist/components/top-nav/top-nav.svelte.d.ts +26 -0
- package/dist/components/top-nav/top-nav.svelte.js +18 -0
- package/dist/components/top-nav/types.d.ts +89 -0
- package/dist/components/top-nav/types.js +1 -0
- package/dist/css/class-darkmode.css +1 -1
- package/dist/css/media-darkmode.css +1 -1
- package/dist/css/theme.css +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends BreadcrumbItemGenerics = 'button'">
|
|
2
|
+
import { invokeHandlers, RenderSoC } from '../../internal/index.js';
|
|
3
|
+
import type { BreadcrumbButtonProps, BreadcrumbItemElementDOMType, BreadcrumbItemGenerics } from './types.js';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
as = 'button' as T,
|
|
7
|
+
ref = $bindable(),
|
|
8
|
+
icon,
|
|
9
|
+
iconPosition = 'before',
|
|
10
|
+
current = false,
|
|
11
|
+
disabled,
|
|
12
|
+
disabledFocusable = false,
|
|
13
|
+
onclick,
|
|
14
|
+
class: classes,
|
|
15
|
+
children,
|
|
16
|
+
...attributes
|
|
17
|
+
}: BreadcrumbButtonProps<T> = $props();
|
|
18
|
+
|
|
19
|
+
const _as = $derived.by(() => {
|
|
20
|
+
if (as !== 'button' && as !== 'a') throw new Error(`Invalid tag: ${as}. Must be one of button, a`);
|
|
21
|
+
return as;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const nativelyDisabled = $derived(_as === 'button' && disabled && !disabledFocusable);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<!--
|
|
28
|
+
@component
|
|
29
|
+
A step of a `Breadcrumb` that can be activated: an anchor when it goes somewhere, a button when
|
|
30
|
+
it does something. The last step is the page itself, and `current` is what announces it.
|
|
31
|
+
|
|
32
|
+
- Usage:
|
|
33
|
+
```tsx
|
|
34
|
+
<BreadcrumbButton as="a" href="/files" icon={FolderRegular}>Files</BreadcrumbButton>
|
|
35
|
+
<BreadcrumbButton current>This page</BreadcrumbButton>
|
|
36
|
+
```
|
|
37
|
+
-->
|
|
38
|
+
<svelte:element
|
|
39
|
+
this={_as}
|
|
40
|
+
bind:this={ref as BreadcrumbItemElementDOMType[T]}
|
|
41
|
+
type={_as === 'button' ? 'button' : undefined}
|
|
42
|
+
disabled={nativelyDisabled || undefined}
|
|
43
|
+
aria-disabled={disabled || undefined}
|
|
44
|
+
aria-current={current ? 'page' : undefined}
|
|
45
|
+
class={['fs-breadcrumb-button', { current, disabled }, classes]}
|
|
46
|
+
onclick={(e: MouseEvent) => invokeHandlers(e, disabled, [onclick])}
|
|
47
|
+
{...attributes}
|
|
48
|
+
>
|
|
49
|
+
{#if icon && iconPosition === 'before'}
|
|
50
|
+
<span class="fs-breadcrumb-button-icon">
|
|
51
|
+
<RenderSoC SoC={icon} />
|
|
52
|
+
</span>
|
|
53
|
+
{/if}
|
|
54
|
+
<span class="fs-breadcrumb-button-label">
|
|
55
|
+
{@render children?.()}
|
|
56
|
+
</span>
|
|
57
|
+
{#if icon && iconPosition === 'after'}
|
|
58
|
+
<span class="fs-breadcrumb-button-icon">
|
|
59
|
+
<RenderSoC SoC={icon} />
|
|
60
|
+
</span>
|
|
61
|
+
{/if}
|
|
62
|
+
</svelte:element>
|
|
63
|
+
|
|
64
|
+
<style>
|
|
65
|
+
.fs-breadcrumb-button {
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
align-items: center;
|
|
68
|
+
gap: var(--fs-breadcrumb-gap, 0.25rem);
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
min-width: 0;
|
|
71
|
+
height: var(--fs-breadcrumb-height, 1.5rem);
|
|
72
|
+
padding: 0 var(--fs-breadcrumb-padding-inline, 0.375rem);
|
|
73
|
+
border: none;
|
|
74
|
+
border-radius: var(--fs-control-border-radius);
|
|
75
|
+
background: transparent;
|
|
76
|
+
color: var(--fs-text-secondary);
|
|
77
|
+
font-family: inherit;
|
|
78
|
+
font-size: var(--fs-breadcrumb-font-size, var(--fs-body2-font-size));
|
|
79
|
+
line-height: var(--fs-breadcrumb-line-height, var(--fs-body2-line-height));
|
|
80
|
+
/* An anchor arrives underlined and in the colour of a link; a step is neither. */
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
outline: none;
|
|
84
|
+
transition:
|
|
85
|
+
color var(--fs-fast-duration) var(--fs-point-to-point),
|
|
86
|
+
background var(--fs-fast-duration) var(--fs-point-to-point);
|
|
87
|
+
&:hover:not(.disabled) {
|
|
88
|
+
background: var(--fs-subtle-fill-secondary);
|
|
89
|
+
color: var(--fs-text-primary);
|
|
90
|
+
}
|
|
91
|
+
&:active:not(.disabled) {
|
|
92
|
+
background: var(--fs-subtle-fill-tertiary);
|
|
93
|
+
color: var(--fs-text-secondary);
|
|
94
|
+
}
|
|
95
|
+
&:focus-visible {
|
|
96
|
+
outline: 0.125rem var(--fs-focus-stroke-outer) solid;
|
|
97
|
+
outline-offset: 0.125rem;
|
|
98
|
+
}
|
|
99
|
+
/* The end of the trail is where the reader already is, so it reads as text, not as a way out. */
|
|
100
|
+
&.current {
|
|
101
|
+
color: var(--fs-text-primary);
|
|
102
|
+
font-weight: 600;
|
|
103
|
+
cursor: default;
|
|
104
|
+
&:hover,
|
|
105
|
+
&:active {
|
|
106
|
+
background: transparent;
|
|
107
|
+
color: var(--fs-text-primary);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
&.disabled {
|
|
111
|
+
color: var(--fs-text-disabled);
|
|
112
|
+
cursor: not-allowed;
|
|
113
|
+
}
|
|
114
|
+
& .fs-breadcrumb-button-icon {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex: 0 0 auto;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
& :global(svg) {
|
|
120
|
+
width: var(--fs-breadcrumb-icon-size, 1rem);
|
|
121
|
+
height: var(--fs-breadcrumb-icon-size, 1rem);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
& .fs-breadcrumb-button-label {
|
|
125
|
+
overflow: hidden;
|
|
126
|
+
text-overflow: ellipsis;
|
|
127
|
+
white-space: nowrap;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BreadcrumbButtonProps, BreadcrumbItemGenerics } from './types.ts';
|
|
2
|
+
declare function $$render<T extends BreadcrumbItemGenerics = 'button'>(): {
|
|
3
|
+
props: BreadcrumbButtonProps<T>;
|
|
4
|
+
exports: {};
|
|
5
|
+
bindings: "ref";
|
|
6
|
+
slots: {};
|
|
7
|
+
events: {};
|
|
8
|
+
};
|
|
9
|
+
declare class __sveltets_Render<T extends BreadcrumbItemGenerics = 'button'> {
|
|
10
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
11
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
12
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
13
|
+
bindings(): "ref";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <T extends BreadcrumbItemGenerics = 'button'>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
20
|
+
<T extends BreadcrumbItemGenerics = 'button'>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A step of a `Breadcrumb` that can be activated: an anchor when it goes somewhere, a button when
|
|
25
|
+
* it does something. The last step is the page itself, and `current` is what announces it.
|
|
26
|
+
*
|
|
27
|
+
* - Usage:
|
|
28
|
+
* ```tsx
|
|
29
|
+
* <BreadcrumbButton as="a" href="/files" icon={FolderRegular}>Files</BreadcrumbButton>
|
|
30
|
+
* <BreadcrumbButton current>This page</BreadcrumbButton>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare const BreadcrumbButton: $$IsomorphicComponent;
|
|
34
|
+
type BreadcrumbButton<T extends BreadcrumbItemGenerics = 'button'> = InstanceType<typeof BreadcrumbButton<T>>;
|
|
35
|
+
export default BreadcrumbButton;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronRightRegular from 'fluentui-icons-svelte/ChevronRightRegular.svelte';
|
|
3
|
+
import type { BreadcrumbDividerProps } from './types.js';
|
|
4
|
+
|
|
5
|
+
let { ref = $bindable(), class: classes, children, ...attributes }: BreadcrumbDividerProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<!--
|
|
9
|
+
@component
|
|
10
|
+
The mark between two steps of a `Breadcrumb`. It is decoration, so it is held out of the
|
|
11
|
+
accessibility tree: a reader counting the steps of the trail should not be read a chevron
|
|
12
|
+
between each one, nor be told the list is twice as long as it is.
|
|
13
|
+
|
|
14
|
+
- Usage:
|
|
15
|
+
```tsx
|
|
16
|
+
<BreadcrumbDivider />
|
|
17
|
+
```
|
|
18
|
+
-->
|
|
19
|
+
<li bind:this={ref} aria-hidden="true" class={['fs-breadcrumb-divider', classes]} {...attributes}>
|
|
20
|
+
{#if children}
|
|
21
|
+
{@render children()}
|
|
22
|
+
{:else}
|
|
23
|
+
<ChevronRightRegular />
|
|
24
|
+
{/if}
|
|
25
|
+
</li>
|
|
26
|
+
|
|
27
|
+
<style>
|
|
28
|
+
.fs-breadcrumb-divider {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex: 0 0 auto;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
color: var(--fs-text-secondary);
|
|
34
|
+
& :global(svg) {
|
|
35
|
+
width: var(--fs-breadcrumb-divider-size, 0.75rem);
|
|
36
|
+
height: var(--fs-breadcrumb-divider-size, 0.75rem);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BreadcrumbDividerProps } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The mark between two steps of a `Breadcrumb`. It is decoration, so it is held out of the
|
|
4
|
+
* accessibility tree: a reader counting the steps of the trail should not be read a chevron
|
|
5
|
+
* between each one, nor be told the list is twice as long as it is.
|
|
6
|
+
*
|
|
7
|
+
* - Usage:
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <BreadcrumbDivider />
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
declare const BreadcrumbDivider: import("svelte").Component<BreadcrumbDividerProps, {}, "ref">;
|
|
13
|
+
type BreadcrumbDivider = ReturnType<typeof BreadcrumbDivider>;
|
|
14
|
+
export default BreadcrumbDivider;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { BreadcrumbItemProps } from './types.js';
|
|
3
|
+
|
|
4
|
+
let { ref = $bindable(), class: classes, children, ...attributes }: BreadcrumbItemProps = $props();
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
@component
|
|
9
|
+
One step of a `Breadcrumb`: the list item the step lives in. What goes inside is usually a
|
|
10
|
+
`BreadcrumbButton`, but it takes anything — a menu holding the steps that were folded away, for
|
|
11
|
+
instance.
|
|
12
|
+
|
|
13
|
+
- Usage:
|
|
14
|
+
```tsx
|
|
15
|
+
<BreadcrumbItem>
|
|
16
|
+
<BreadcrumbButton as="a" href="/">Home</BreadcrumbButton>
|
|
17
|
+
</BreadcrumbItem>
|
|
18
|
+
```
|
|
19
|
+
-->
|
|
20
|
+
<li bind:this={ref} class={['fs-breadcrumb-item', classes]} {...attributes}>
|
|
21
|
+
{@render children?.()}
|
|
22
|
+
</li>
|
|
23
|
+
|
|
24
|
+
<style>
|
|
25
|
+
.fs-breadcrumb-item {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
min-width: 0;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BreadcrumbItemProps } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* One step of a `Breadcrumb`: the list item the step lives in. What goes inside is usually a
|
|
4
|
+
* `BreadcrumbButton`, but it takes anything — a menu holding the steps that were folded away, for
|
|
5
|
+
* instance.
|
|
6
|
+
*
|
|
7
|
+
* - Usage:
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <BreadcrumbItem>
|
|
10
|
+
* <BreadcrumbButton as="a" href="/">Home</BreadcrumbButton>
|
|
11
|
+
* </BreadcrumbItem>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare const BreadcrumbItem: import("svelte").Component<BreadcrumbItemProps, {}, "ref">;
|
|
15
|
+
type BreadcrumbItem = ReturnType<typeof BreadcrumbItem>;
|
|
16
|
+
export default BreadcrumbItem;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getTabspotAttributes } from 'tabspot';
|
|
3
|
+
import type { BreadcrumbProps } from './types.js';
|
|
4
|
+
|
|
5
|
+
/** The steps a mover lands on when the trail takes a single tab stop. */
|
|
6
|
+
const TABSPOT_ITEMS = '.fs-breadcrumb-button';
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
ref = $bindable(),
|
|
10
|
+
listRef = $bindable(),
|
|
11
|
+
listProps,
|
|
12
|
+
size = 'medium',
|
|
13
|
+
focusMode = 'tab',
|
|
14
|
+
'aria-label': ariaLabel,
|
|
15
|
+
'aria-labelledby': ariaLabelledby,
|
|
16
|
+
class: classes,
|
|
17
|
+
children,
|
|
18
|
+
...attributes
|
|
19
|
+
}: BreadcrumbProps = $props();
|
|
20
|
+
|
|
21
|
+
const tabspotAttributes = $derived(
|
|
22
|
+
focusMode === 'arrow' &&
|
|
23
|
+
getTabspotAttributes({
|
|
24
|
+
root: { manageSpecialKeys: { Home: true, End: true } },
|
|
25
|
+
mover: { axis: 'horizontal', items: TABSPOT_ITEMS }
|
|
26
|
+
})
|
|
27
|
+
);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!--
|
|
31
|
+
@component
|
|
32
|
+
A breadcrumb shows where a page sits in the hierarchy above it, and gives the reader a way back
|
|
33
|
+
up. It renders a landmark of its own, so a screen reader can jump straight to it.
|
|
34
|
+
|
|
35
|
+
- Usage:
|
|
36
|
+
```tsx
|
|
37
|
+
<script>
|
|
38
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbButton, BreadcrumbDivider } from 'fluentui-svelte';
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<Breadcrumb>
|
|
42
|
+
<BreadcrumbItem>
|
|
43
|
+
<BreadcrumbButton as="a" href="/">Home</BreadcrumbButton>
|
|
44
|
+
</BreadcrumbItem>
|
|
45
|
+
<BreadcrumbDivider />
|
|
46
|
+
<BreadcrumbItem>
|
|
47
|
+
<BreadcrumbButton current>This page</BreadcrumbButton>
|
|
48
|
+
</BreadcrumbItem>
|
|
49
|
+
</Breadcrumb>
|
|
50
|
+
```
|
|
51
|
+
-->
|
|
52
|
+
<nav
|
|
53
|
+
bind:this={ref}
|
|
54
|
+
aria-label={ariaLabelledby ? undefined : (ariaLabel ?? 'Breadcrumb')}
|
|
55
|
+
aria-labelledby={ariaLabelledby}
|
|
56
|
+
class={['fs-breadcrumb', size, classes]}
|
|
57
|
+
{...attributes}
|
|
58
|
+
>
|
|
59
|
+
<ol bind:this={listRef} class="fs-breadcrumb-list" {...tabspotAttributes} {...listProps}>
|
|
60
|
+
{@render children?.()}
|
|
61
|
+
</ol>
|
|
62
|
+
</nav>
|
|
63
|
+
|
|
64
|
+
<style>
|
|
65
|
+
.fs-breadcrumb {
|
|
66
|
+
font-family: var(--fs-font-family-base);
|
|
67
|
+
color: var(--fs-text-primary);
|
|
68
|
+
/* Read by every step and divider */
|
|
69
|
+
--fs-breadcrumb-font-size: var(--fs-body2-font-size);
|
|
70
|
+
--fs-breadcrumb-line-height: var(--fs-body2-line-height);
|
|
71
|
+
--fs-breadcrumb-height: 1.5rem;
|
|
72
|
+
--fs-breadcrumb-padding-inline: 0.375rem;
|
|
73
|
+
--fs-breadcrumb-gap: 0.25rem;
|
|
74
|
+
--fs-breadcrumb-icon-size: 1rem;
|
|
75
|
+
--fs-breadcrumb-divider-size: 1rem;
|
|
76
|
+
&.small {
|
|
77
|
+
--fs-breadcrumb-font-size: var(--fs-caption-font-size);
|
|
78
|
+
--fs-breadcrumb-line-height: var(--fs-caption-line-height);
|
|
79
|
+
--fs-breadcrumb-height: 1.25rem;
|
|
80
|
+
--fs-breadcrumb-padding-inline: 0.25rem;
|
|
81
|
+
--fs-breadcrumb-icon-size: 0.875rem;
|
|
82
|
+
--fs-breadcrumb-divider-size: 0.625rem;
|
|
83
|
+
}
|
|
84
|
+
&.large {
|
|
85
|
+
--fs-breadcrumb-font-size: var(--fs-body-font-size);
|
|
86
|
+
--fs-breadcrumb-line-height: var(--fs-body-line-height);
|
|
87
|
+
--fs-breadcrumb-height: 2rem;
|
|
88
|
+
--fs-breadcrumb-padding-inline: 0.5rem;
|
|
89
|
+
--fs-breadcrumb-icon-size: 1.25rem;
|
|
90
|
+
--fs-breadcrumb-divider-size: 1.25rem;
|
|
91
|
+
}
|
|
92
|
+
& .fs-breadcrumb-list {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-wrap: wrap;
|
|
95
|
+
align-items: center;
|
|
96
|
+
margin: 0;
|
|
97
|
+
padding: 0;
|
|
98
|
+
list-style: none;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BreadcrumbProps } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A breadcrumb shows where a page sits in the hierarchy above it, and gives the reader a way back
|
|
4
|
+
* up. It renders a landmark of its own, so a screen reader can jump straight to it.
|
|
5
|
+
*
|
|
6
|
+
* - Usage:
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <script>
|
|
9
|
+
* import { Breadcrumb, BreadcrumbItem, BreadcrumbButton, BreadcrumbDivider } from 'fluentui-svelte';
|
|
10
|
+
* </script>
|
|
11
|
+
*
|
|
12
|
+
* <Breadcrumb>
|
|
13
|
+
* <BreadcrumbItem>
|
|
14
|
+
* <BreadcrumbButton as="a" href="/">Home</BreadcrumbButton>
|
|
15
|
+
* </BreadcrumbItem>
|
|
16
|
+
* <BreadcrumbDivider />
|
|
17
|
+
* <BreadcrumbItem>
|
|
18
|
+
* <BreadcrumbButton current>This page</BreadcrumbButton>
|
|
19
|
+
* </BreadcrumbItem>
|
|
20
|
+
* </Breadcrumb>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare const Breadcrumb: import("svelte").Component<BreadcrumbProps, {}, "ref" | "listRef">;
|
|
24
|
+
type Breadcrumb = ReturnType<typeof Breadcrumb>;
|
|
25
|
+
export default Breadcrumb;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Breadcrumb
|
|
2
|
+
|
|
3
|
+
A breadcrumb shows where a page sits in the hierarchy above it, and gives the reader a way back up. It renders a `nav` landmark around an ordered list, so a screen reader can jump straight to it.
|
|
4
|
+
|
|
5
|
+
The landmark names itself `Breadcrumb`, the trail is an `ol` so its order is part of the markup rather than of the styling, the last step carries `aria-current="page"`, and the dividers are held out of the accessibility tree — a trail of three steps reads as three, not as five. Every one of those can be overridden: pass your own `aria-label`, or an `aria-labelledby`, and the default steps aside.
|
|
6
|
+
|
|
7
|
+
To create a breadcrumb, you will need to use the following components:
|
|
8
|
+
|
|
9
|
+
- `Breadcrumb`: The landmark and the list. It creates the context the rest read.
|
|
10
|
+
- `BreadcrumbItem`: One step of the trail — the list item the step lives in. It takes anything, not only a step.
|
|
11
|
+
- `BreadcrumbButton`: A step that can be activated: an anchor when it goes somewhere, a button when it does something.
|
|
12
|
+
- `BreadcrumbDivider`: The mark between two steps. It is decoration, and is hidden from assistive technology.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
A breadcrumb is a list of steps with a divider between them. The last step is the page the reader is already on, so it is marked `current` rather than linked away.
|
|
17
|
+
|
|
18
|
+
```svelte
|
|
19
|
+
<script>
|
|
20
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbButton, BreadcrumbDivider } from 'fluentui-svelte';
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Breadcrumb>
|
|
24
|
+
<BreadcrumbItem>
|
|
25
|
+
<BreadcrumbButton as="a" href="/">Home</BreadcrumbButton>
|
|
26
|
+
</BreadcrumbItem>
|
|
27
|
+
<BreadcrumbDivider />
|
|
28
|
+
<BreadcrumbItem>
|
|
29
|
+
<BreadcrumbButton as="a" href="/files">Files</BreadcrumbButton>
|
|
30
|
+
</BreadcrumbItem>
|
|
31
|
+
<BreadcrumbDivider />
|
|
32
|
+
<BreadcrumbItem>
|
|
33
|
+
<BreadcrumbButton current>Quarterly report</BreadcrumbButton>
|
|
34
|
+
</BreadcrumbItem>
|
|
35
|
+
</Breadcrumb>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Size
|
|
41
|
+
|
|
42
|
+
`size` sets the type, the height and the divider of every step at once.
|
|
43
|
+
|
|
44
|
+
```svelte
|
|
45
|
+
<Breadcrumb size="small">...</Breadcrumb>
|
|
46
|
+
<Breadcrumb size="medium">...</Breadcrumb>
|
|
47
|
+
<Breadcrumb size="large">...</Breadcrumb>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Icon
|
|
51
|
+
|
|
52
|
+
`icon` takes a snippet or a component and renders it beside the label, on the side `iconPosition` asks for.
|
|
53
|
+
|
|
54
|
+
```svelte
|
|
55
|
+
<BreadcrumbItem>
|
|
56
|
+
<BreadcrumbButton as="a" href="/files" icon={FolderRegular}>Files</BreadcrumbButton>
|
|
57
|
+
</BreadcrumbItem>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Current Step
|
|
61
|
+
|
|
62
|
+
`current` marks the step as the page the trail ends at. It announces `aria-current="page"` and reads as text rather than as a way out, so the last step does not offer to take the reader where they already are.
|
|
63
|
+
|
|
64
|
+
```svelte
|
|
65
|
+
<BreadcrumbItem>
|
|
66
|
+
<BreadcrumbButton current>Quarterly report</BreadcrumbButton>
|
|
67
|
+
</BreadcrumbItem>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Overflow Menu
|
|
71
|
+
|
|
72
|
+
A step takes whatever you put in it, so a long trail folds its middle into a menu by making that menu a step of its own. Which steps fold is your call — slice the list wherever the layout needs it.
|
|
73
|
+
|
|
74
|
+
```svelte
|
|
75
|
+
<script>
|
|
76
|
+
// Keep the root and the last two steps; everything between them goes into the menu.
|
|
77
|
+
const head = trail.slice(0, 1);
|
|
78
|
+
const folded = trail.slice(1, -2);
|
|
79
|
+
const tail = trail.slice(-2);
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<Breadcrumb>
|
|
83
|
+
{#each head as item (item.name)}
|
|
84
|
+
<BreadcrumbItem>
|
|
85
|
+
<BreadcrumbButton as="a" href={item.href}>{item.name}</BreadcrumbButton>
|
|
86
|
+
</BreadcrumbItem>
|
|
87
|
+
<BreadcrumbDivider />
|
|
88
|
+
{/each}
|
|
89
|
+
|
|
90
|
+
<BreadcrumbItem>
|
|
91
|
+
<Menu>
|
|
92
|
+
<MenuTrigger>
|
|
93
|
+
{#snippet children({ state, menuTriggerProps })}
|
|
94
|
+
<Button bind:ref={state.ref} {...menuTriggerProps} appearance="subtle" aria-label="More steps">
|
|
95
|
+
<MoreHorizontalRegular />
|
|
96
|
+
</Button>
|
|
97
|
+
{/snippet}
|
|
98
|
+
</MenuTrigger>
|
|
99
|
+
<MenuPopover>
|
|
100
|
+
<MenuList>
|
|
101
|
+
<!-- A step that goes somewhere is a link, in the menu as much as in the trail. -->
|
|
102
|
+
{#each folded as item (item.name)}
|
|
103
|
+
<MenuItem href={item.href}>{item.name}</MenuItem>
|
|
104
|
+
{/each}
|
|
105
|
+
</MenuList>
|
|
106
|
+
</MenuPopover>
|
|
107
|
+
</Menu>
|
|
108
|
+
</BreadcrumbItem>
|
|
109
|
+
<BreadcrumbDivider />
|
|
110
|
+
|
|
111
|
+
{#each tail as item (item.name)}
|
|
112
|
+
<BreadcrumbItem>
|
|
113
|
+
<BreadcrumbButton current>{item.name}</BreadcrumbButton>
|
|
114
|
+
</BreadcrumbItem>
|
|
115
|
+
{/each}
|
|
116
|
+
</Breadcrumb>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The label on the menu button is yours to write, and it is worth writing: a trigger with only an icon says nothing to a screen reader. Note also that what lives inside a `MenuPopover` is not rendered until the menu opens, so the folded steps are not in the HTML a crawler reads.
|
|
120
|
+
|
|
121
|
+
### Focus Mode
|
|
122
|
+
|
|
123
|
+
`focusMode` decides how the focus walks the trail. `tab`, the default, leaves every step its own tab stop, which is what a reader expects of a row of links. `arrow` gives the whole trail a single tab stop and moves between steps with the arrow keys, with `Home` and `End` for the ends.
|
|
124
|
+
|
|
125
|
+
```svelte
|
|
126
|
+
<Breadcrumb focusMode="arrow">...</Breadcrumb>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Component Props (Breadcrumb)
|
|
130
|
+
|
|
131
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
132
|
+
<!-- props:BreadcrumbProps -->
|
|
133
|
+
|
|
134
|
+
| Name | Type | Default | Description |
|
|
135
|
+
| -------------------- | -------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `ref` _bindable_ | `HTMLElement` | | The DOM reference of the `nav`. |
|
|
137
|
+
| `listRef` _bindable_ | `HTMLOListElement` | | The DOM reference of the list. |
|
|
138
|
+
| `listProps` | `HTMLOlAttributes` | | The props to spread on the list element. |
|
|
139
|
+
| `size` | `'small'` | `'medium'` | `'large'` | `'medium'` | The size of every step and divider of the trail. |
|
|
140
|
+
| `focusMode` | `'tab'` | `'arrow'` | `'tab'` | How the focus walks the trail: `tab` leaves every step its own tab stop, `arrow` gives the trail a single one and moves between steps with the arrow keys. |
|
|
141
|
+
| Element Attributes | | | |
|
|
142
|
+
|
|
143
|
+
<!-- /props:BreadcrumbProps -->
|
|
144
|
+
|
|
145
|
+
## Component Props (BreadcrumbItem)
|
|
146
|
+
|
|
147
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
148
|
+
<!-- props:BreadcrumbItemProps -->
|
|
149
|
+
|
|
150
|
+
| Name | Type | Default | Description |
|
|
151
|
+
| ------------------------- | --------------- | ------- | ------------------------------ |
|
|
152
|
+
| `ref` _bindable_ | `HTMLLIElement` | | The DOM reference of the item. |
|
|
153
|
+
| Element Attributes (`li`) | | | |
|
|
154
|
+
|
|
155
|
+
<!-- /props:BreadcrumbItemProps -->
|
|
156
|
+
|
|
157
|
+
## Component Props (BreadcrumbButton)
|
|
158
|
+
|
|
159
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
160
|
+
<!-- props:BreadcrumbButtonProps -->
|
|
161
|
+
|
|
162
|
+
| Name | Type | Default | Description |
|
|
163
|
+
| ------------------- | --------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------ |
|
|
164
|
+
| `ref` _bindable_ | `BreadcrumbItemElementDOMType[T]` | | The DOM reference of the step. |
|
|
165
|
+
| `as` | `'button'` | `'a'` | `'button'` | The DOM element to render. A step that goes somewhere is an anchor and takes `href`. |
|
|
166
|
+
| `icon` | `Snippet` | `Component` | | The icon to display beside the label. |
|
|
167
|
+
| `iconPosition` | `'before'` | `'after'` | `'before'` | Which side of the label the icon sits on. |
|
|
168
|
+
| `current` | `boolean` | `false` | Marks the step as the page the trail ends at, which is what `aria-current` announces. |
|
|
169
|
+
| `disabled` | `boolean` | | Disables the user interaction. |
|
|
170
|
+
| `disabledFocusable` | `boolean` | `false` | Keeps a disabled step focusable, so the tab order stays the same for a keyboard or screen reader user. |
|
|
171
|
+
| HTML Attributes | | | |
|
|
172
|
+
|
|
173
|
+
<!-- /props:BreadcrumbButtonProps -->
|
|
174
|
+
|
|
175
|
+
## Component Props (BreadcrumbDivider)
|
|
176
|
+
|
|
177
|
+
<!-- DO NOT EDIT THIS SECTION (propsmith generated) -->
|
|
178
|
+
<!-- props:BreadcrumbDividerProps -->
|
|
179
|
+
|
|
180
|
+
| Name | Type | Default | Description |
|
|
181
|
+
| ------------------------- | --------------- | ------- | --------------------------------- |
|
|
182
|
+
| `ref` _bindable_ | `HTMLLIElement` | | The DOM reference of the divider. |
|
|
183
|
+
| Element Attributes (`li`) | | | |
|
|
184
|
+
|
|
185
|
+
<!-- /props:BreadcrumbDividerProps -->
|
|
186
|
+
|
|
187
|
+
## Accessibility
|
|
188
|
+
|
|
189
|
+
The landmark is named `Breadcrumb` by default, which is what a screen reader announces when jumping to it. Give it your own `aria-label` when a page carries more than one trail, so each is distinguishable, or an `aria-labelledby` pointing at a heading you already render — the default steps aside for both.
|
|
190
|
+
|
|
191
|
+
The dividers are decoration and are hidden, so the list reads as the number of steps it has. The last step carries `aria-current="page"`. A step with an icon and no label needs an `aria-label` of its own.
|
|
192
|
+
|
|
193
|
+
Structured data is left to you. A breadcrumb is one of the few components a search engine reads directly, through `BreadcrumbList` from schema.org, but the text of a step lives in your markup and the URLs live in your routing — so the trail you publish is yours to build, in whichever shape your site already uses.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { BeforeOrAfter, PolymorphicProps, Sizes } from '../../types/index.js';
|
|
2
|
+
import type { Snippet, Component } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes, HTMLOlAttributes } from 'svelte/elements';
|
|
4
|
+
/** How the focus walks the trail. */
|
|
5
|
+
export type BreadcrumbFocusMode = 'tab' | 'arrow';
|
|
6
|
+
export type BreadcrumbItemGenerics = 'button' | 'a';
|
|
7
|
+
export type BreadcrumbItemElementDOMType = {
|
|
8
|
+
button: HTMLButtonElement;
|
|
9
|
+
a: HTMLAnchorElement;
|
|
10
|
+
};
|
|
11
|
+
/** @propsmith BreadcrumbProps */
|
|
12
|
+
export type BreadcrumbProps = {
|
|
13
|
+
/** The DOM reference of the `nav`.
|
|
14
|
+
* @bindable
|
|
15
|
+
*/
|
|
16
|
+
ref?: HTMLElement;
|
|
17
|
+
/** The DOM reference of the list.
|
|
18
|
+
* @bindable
|
|
19
|
+
*/
|
|
20
|
+
listRef?: HTMLOListElement;
|
|
21
|
+
/** The props to spread on the list element.
|
|
22
|
+
* @type HTMLOlAttributes
|
|
23
|
+
*/
|
|
24
|
+
listProps?: HTMLOlAttributes;
|
|
25
|
+
/** The size of every step and divider of the trail.
|
|
26
|
+
* @default 'medium'
|
|
27
|
+
*/
|
|
28
|
+
size?: Sizes;
|
|
29
|
+
/** How the focus walks the trail: `tab` leaves every step its own tab stop, `arrow` gives the
|
|
30
|
+
* trail a single one and moves between steps with the arrow keys.
|
|
31
|
+
* @default 'tab'
|
|
32
|
+
*/
|
|
33
|
+
focusMode?: BreadcrumbFocusMode;
|
|
34
|
+
} & HTMLAttributes<HTMLElement>;
|
|
35
|
+
/** @propsmith BreadcrumbItemProps */
|
|
36
|
+
export type BreadcrumbItemProps = {
|
|
37
|
+
/** The DOM reference of the item.
|
|
38
|
+
* @bindable
|
|
39
|
+
*/
|
|
40
|
+
ref?: HTMLLIElement;
|
|
41
|
+
} & HTMLAttributes<HTMLLIElement>;
|
|
42
|
+
/** @propsmith BreadcrumbButtonProps */
|
|
43
|
+
export type BreadcrumbButtonProps<T extends BreadcrumbItemGenerics = 'button'> = {
|
|
44
|
+
/** The DOM reference of the step.
|
|
45
|
+
* @type BreadcrumbItemElementDOMType[T]
|
|
46
|
+
* @bindable
|
|
47
|
+
*/
|
|
48
|
+
ref?: BreadcrumbItemElementDOMType[T];
|
|
49
|
+
/** The DOM element to render. A step that goes somewhere is an anchor and takes `href`.
|
|
50
|
+
* @type 'button' | 'a'
|
|
51
|
+
* @default 'button'
|
|
52
|
+
*/
|
|
53
|
+
as?: T;
|
|
54
|
+
/** The icon to display beside the label.
|
|
55
|
+
* @type Snippet | Component
|
|
56
|
+
*/
|
|
57
|
+
icon?: Snippet | Component;
|
|
58
|
+
/** Which side of the label the icon sits on.
|
|
59
|
+
* @default 'before'
|
|
60
|
+
*/
|
|
61
|
+
iconPosition?: BeforeOrAfter;
|
|
62
|
+
/** Marks the step as the page the trail ends at, which is what `aria-current` announces.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
current?: boolean;
|
|
66
|
+
/** Disables the user interaction. */
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
/** Keeps a disabled step focusable, so the tab order stays the same for a keyboard or screen
|
|
69
|
+
* reader user.
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
disabledFocusable?: boolean;
|
|
73
|
+
} & PolymorphicProps<T>;
|
|
74
|
+
/** @propsmith BreadcrumbDividerProps */
|
|
75
|
+
export type BreadcrumbDividerProps = {
|
|
76
|
+
/** The DOM reference of the divider.
|
|
77
|
+
* @bindable
|
|
78
|
+
*/
|
|
79
|
+
ref?: HTMLLIElement;
|
|
80
|
+
} & HTMLAttributes<HTMLLIElement>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|