fluent-svelte-extra 1.0.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/.prettierignore +1 -0
- package/.prettierrc +7 -0
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +33 -0
- package/package.json +83 -0
- package/src/app.html +12 -0
- package/src/global.d.ts +1 -0
- package/src/lib/AutoSuggestBox/AutoSuggestBox.scss +44 -0
- package/src/lib/AutoSuggestBox/AutoSuggestBox.svelte +173 -0
- package/src/lib/Button/Button.scss +94 -0
- package/src/lib/Button/Button.svelte +48 -0
- package/src/lib/CalendarDatePicker/CalendarDatePicker.scss +15 -0
- package/src/lib/CalendarDatePicker/CalendarDatePicker.svelte +86 -0
- package/src/lib/CalendarView/CalendarView.scss +156 -0
- package/src/lib/CalendarView/CalendarView.svelte +753 -0
- package/src/lib/CalendarView/CalendarViewItem.scss +130 -0
- package/src/lib/CalendarView/CalendarViewItem.svelte +33 -0
- package/src/lib/Checkbox/Checkbox.scss +117 -0
- package/src/lib/Checkbox/Checkbox.svelte +81 -0
- package/src/lib/ComboBox/ComboBox.scss +152 -0
- package/src/lib/ComboBox/ComboBox.svelte +360 -0
- package/src/lib/ComboBox/ComboBoxItem.scss +80 -0
- package/src/lib/ComboBox/ComboBoxItem.svelte +30 -0
- package/src/lib/ContentDialog/ContentDialog.scss +68 -0
- package/src/lib/ContentDialog/ContentDialog.svelte +123 -0
- package/src/lib/ContextMenu/ContextMenu.scss +11 -0
- package/src/lib/ContextMenu/ContextMenu.svelte +104 -0
- package/src/lib/Expander/Expander.scss +134 -0
- package/src/lib/Expander/Expander.svelte +123 -0
- package/src/lib/Flipper/Flipper.svelte +49 -0
- package/src/lib/Flyout/FlyoutSurface.scss +14 -0
- package/src/lib/Flyout/FlyoutSurface.svelte +21 -0
- package/src/lib/Flyout/FlyoutWrapper.scss +81 -0
- package/src/lib/Flyout/FlyoutWrapper.svelte +126 -0
- package/src/lib/IconButton/IconButton.scss +31 -0
- package/src/lib/IconButton/IconButton.svelte +49 -0
- package/src/lib/InfoBadge/InfoBadge.scss +39 -0
- package/src/lib/InfoBadge/InfoBadge.svelte +81 -0
- package/src/lib/InfoBar/InfoBar.scss +122 -0
- package/src/lib/InfoBar/InfoBar.svelte +133 -0
- package/src/lib/ListItem/ListItem.scss +74 -0
- package/src/lib/ListItem/ListItem.svelte +88 -0
- package/src/lib/MenuBar/MenuBar.scss +10 -0
- package/src/lib/MenuBar/MenuBar.svelte +49 -0
- package/src/lib/MenuBar/MenuBarItem.scss +38 -0
- package/src/lib/MenuBar/MenuBarItem.svelte +135 -0
- package/src/lib/MenuBar/flyoutState.ts +5 -0
- package/src/lib/MenuFlyout/MenuFlyoutDivider.scss +7 -0
- package/src/lib/MenuFlyout/MenuFlyoutDivider.svelte +14 -0
- package/src/lib/MenuFlyout/MenuFlyoutItem.scss +147 -0
- package/src/lib/MenuFlyout/MenuFlyoutItem.svelte +239 -0
- package/src/lib/MenuFlyout/MenuFlyoutSurface.scss +42 -0
- package/src/lib/MenuFlyout/MenuFlyoutSurface.svelte +28 -0
- package/src/lib/MenuFlyout/MenuFlyoutWrapper.scss +64 -0
- package/src/lib/MenuFlyout/MenuFlyoutWrapper.svelte +114 -0
- package/src/lib/NavigationView/NavigationView.scss +0 -0
- package/src/lib/NavigationView/NavigationView.svelte +82 -0
- package/src/lib/NumberBox/NumberBox.scss +31 -0
- package/src/lib/NumberBox/NumberBox.svelte +267 -0
- package/src/lib/PersonPicture/PersonPicture.scss +35 -0
- package/src/lib/PersonPicture/PersonPicture.svelte +62 -0
- package/src/lib/ProgressBar/ProgressBar.scss +83 -0
- package/src/lib/ProgressBar/ProgressBar.svelte +60 -0
- package/src/lib/ProgressRing/ProgressRing.scss +37 -0
- package/src/lib/ProgressRing/ProgressRing.svelte +73 -0
- package/src/lib/RadioButton/RadioButton.scss +114 -0
- package/src/lib/RadioButton/RadioButton.svelte +67 -0
- package/src/lib/RangeSlider/RangeSlider.svelte +91 -0
- package/src/lib/ScrollView/ScrollView.svelte +9 -0
- package/src/lib/Slider/Slider.scss +263 -0
- package/src/lib/Slider/Slider.svelte +261 -0
- package/src/lib/TextBlock/TextBlock.scss +62 -0
- package/src/lib/TextBlock/TextBlock.svelte +70 -0
- package/src/lib/TextBox/TextBox.scss +108 -0
- package/src/lib/TextBox/TextBox.svelte +225 -0
- package/src/lib/TextBox/TextBoxButton.scss +34 -0
- package/src/lib/TextBox/TextBoxButton.svelte +27 -0
- package/src/lib/ToggleSwitch/ToggleSwitch.scss +118 -0
- package/src/lib/ToggleSwitch/ToggleSwitch.svelte +55 -0
- package/src/lib/Tooltip/TooltipSurface.scss +16 -0
- package/src/lib/Tooltip/TooltipSurface.svelte +27 -0
- package/src/lib/Tooltip/TooltipWrapper.scss +66 -0
- package/src/lib/Tooltip/TooltipWrapper.svelte +117 -0
- package/src/lib/_mixins.scss +130 -0
- package/src/lib/index.ts +33 -0
- package/src/lib/internal.ts +213 -0
- package/src/lib/svelte-jsx.d.ts +14 -0
- package/src/lib/theme.css +414 -0
- package/src/routes/__layout.svelte +48 -0
- package/src/routes/docs/__layout.svelte +122 -0
- package/src/routes/docs/components/button.md +43 -0
- package/src/routes/docs/components/calendarview.md +188 -0
- package/src/routes/docs/components/checkbox.md +87 -0
- package/src/routes/docs/components/contentdialog.md +155 -0
- package/src/routes/docs/components/expander.md +115 -0
- package/src/routes/docs/components/flyout.md +107 -0
- package/src/routes/docs/components/iconbutton.md +39 -0
- package/src/routes/docs/components/infobadge.md +54 -0
- package/src/routes/docs/components/infobar.md +102 -0
- package/src/routes/docs/components/listitem.md +87 -0
- package/src/routes/docs/components/personpicture.md +125 -0
- package/src/routes/docs/components/progressring.md +83 -0
- package/src/routes/docs/components/radiobutton.md +88 -0
- package/src/routes/docs/components/slider.md +165 -0
- package/src/routes/docs/components/textblock.md +46 -0
- package/src/routes/docs/components/textbox.md +124 -0
- package/src/routes/docs/components/toggleswitch.md +73 -0
- package/src/routes/docs/getting-started.md +116 -0
- package/src/routes/docs/index.md +37 -0
- package/src/routes/docs/internals/index.md +0 -0
- package/src/routes/index.svelte +121 -0
- package/src/routes/test/__layout-test.svelte +1 -0
- package/src/routes/test/index.svelte +757 -0
- package/src/routes/test/nav.svelte +7 -0
- package/src/site/data/docs.ts +176 -0
- package/src/site/data/home.ts +12 -0
- package/src/site/lib/APIDocs/APIDocs.svelte +178 -0
- package/src/site/lib/APIDocs/ParsedComponent.d.ts +85 -0
- package/src/site/lib/CopyBox/CopyBox.svelte +23 -0
- package/src/site/lib/Example/Example.scss +33 -0
- package/src/site/lib/Example/Example.svelte +18 -0
- package/src/site/lib/HeroCard/HeroCard.scss +24 -0
- package/src/site/lib/HeroCard/HeroCard.svelte +36 -0
- package/src/site/lib/Metadata/Metadata.svelte +14 -0
- package/src/site/lib/Navbar/Navbar.scss +92 -0
- package/src/site/lib/Navbar/Navbar.svelte +47 -0
- package/src/site/lib/PageSection/PageSection.scss +57 -0
- package/src/site/lib/PageSection/PageSection.svelte +10 -0
- package/src/site/lib/Showcase/Showcase.scss +53 -0
- package/src/site/lib/Showcase/Showcase.svelte +67 -0
- package/src/site/lib/Toc/Toc.scss +18 -0
- package/src/site/lib/Toc/Toc.svelte +59 -0
- package/src/site/lib/TreeView/TreeView.svelte +89 -0
- package/src/site/lib/index.ts +9 -0
- package/src/site/styles/_markdown.scss +260 -0
- package/src/site/styles/_mixins.scss +319 -0
- package/src/site/styles/global.scss +40 -0
- package/src/site/styles/pages/docs.scss +74 -0
- package/src/site/styles/pages/home.scss +134 -0
- package/static/bloom-mica-dark.png +0 -0
- package/static/bloom-mica-light.png +0 -0
- package/static/logo.svg +11 -0
- package/svelte.config.js +57 -0
- package/tsconfig.json +38 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SvelteComponentTyped } from "svelte";
|
|
3
|
+
|
|
4
|
+
import { tabbable } from "tabbable";
|
|
5
|
+
|
|
6
|
+
import { createEventDispatcher, setContext } from "svelte";
|
|
7
|
+
import { arrowNavigation, uid } from "$lib/internal";
|
|
8
|
+
|
|
9
|
+
import MenuFlyoutSurface from "./MenuFlyoutSurface.svelte";
|
|
10
|
+
|
|
11
|
+
/** Determines the flyout's visibility. */
|
|
12
|
+
export let open = false;
|
|
13
|
+
|
|
14
|
+
/** Determines if the flyout can be closed using conventional user interaction. */
|
|
15
|
+
export let closable = true;
|
|
16
|
+
|
|
17
|
+
/** Controls if the flyout will be closed when clicking a standard variant item. Only applies if `closable` is set to `true`. */
|
|
18
|
+
export let closeOnSelect = true;
|
|
19
|
+
|
|
20
|
+
/** Direction that the flyout will be opened from. */
|
|
21
|
+
export let placement: "top" | "bottom" | "left" | "right" = "top";
|
|
22
|
+
|
|
23
|
+
/** Alignment of the menu along the clickable target's given axis. */
|
|
24
|
+
export let alignment: "start" | "center" | "end" = "center";
|
|
25
|
+
|
|
26
|
+
/** Distance of the flyout from the control button in pixels. */
|
|
27
|
+
export let offset = 4;
|
|
28
|
+
|
|
29
|
+
/** Specifies a custom class name for the flyout. */
|
|
30
|
+
let className = "";
|
|
31
|
+
export { className as class };
|
|
32
|
+
|
|
33
|
+
/** Obtains a bound DOM reference to the content wrapper element. */
|
|
34
|
+
export let wrapperElement: HTMLDivElement = null;
|
|
35
|
+
|
|
36
|
+
/** Obtains a bound DOM reference to the menu's positioning anchor element. */
|
|
37
|
+
export let anchorElement: HTMLDivElement = null;
|
|
38
|
+
|
|
39
|
+
/** Obtains a bound DOM reference to the inner menu element. */
|
|
40
|
+
export let menuElement: HTMLUListElement = null;
|
|
41
|
+
|
|
42
|
+
/** Obtains a bound DOM reference to the menu backdrop, which is present while the menu is `open`. */
|
|
43
|
+
export let backdropElement: HTMLDivElement = null;
|
|
44
|
+
|
|
45
|
+
const dispatch = createEventDispatcher();
|
|
46
|
+
const menuId = uid("fds-menu-flyout-anchor-");
|
|
47
|
+
|
|
48
|
+
let menu: SvelteComponentTyped = null;
|
|
49
|
+
let previousFocus: Element = null;
|
|
50
|
+
|
|
51
|
+
$: dispatch(open ? "open" : "close");
|
|
52
|
+
|
|
53
|
+
$: if (menu && tabbable(menuElement).length > 0) tabbable(menuElement)[0].focus();
|
|
54
|
+
|
|
55
|
+
function handleEscapeKey({ key }: KeyboardEvent) {
|
|
56
|
+
if (key === "Escape" && closable) open = false;
|
|
57
|
+
(<HTMLElement>previousFocus)?.focus();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function toggleFlyout() {
|
|
61
|
+
previousFocus = document.activeElement;
|
|
62
|
+
open = !open;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function closeFlyout() {
|
|
66
|
+
if (closable) open = false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setContext("closeFlyout", event => {
|
|
70
|
+
dispatch("select");
|
|
71
|
+
if (closeOnSelect && closable) {
|
|
72
|
+
event.stopPropagation();
|
|
73
|
+
open = false;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<svelte:window on:keydown={handleEscapeKey} />
|
|
79
|
+
|
|
80
|
+
<div
|
|
81
|
+
class="menu-flyout-wrapper {className}"
|
|
82
|
+
aria-expanded={open}
|
|
83
|
+
aria-haspopup={open}
|
|
84
|
+
aria-controls={menuId}
|
|
85
|
+
on:click={toggleFlyout}
|
|
86
|
+
bind:this={wrapperElement}
|
|
87
|
+
>
|
|
88
|
+
<slot />
|
|
89
|
+
{#if open}
|
|
90
|
+
<div
|
|
91
|
+
id={menuId}
|
|
92
|
+
class="menu-flyout-anchor placement-{placement} alignment-{alignment}"
|
|
93
|
+
style="--fds-menu-flyout-offset: {offset}px;"
|
|
94
|
+
tabindex="-1"
|
|
95
|
+
bind:this={anchorElement}
|
|
96
|
+
use:arrowNavigation={{ preventTab: true }}
|
|
97
|
+
on:click={e => e.stopPropagation()}
|
|
98
|
+
>
|
|
99
|
+
<MenuFlyoutSurface bind:element={menuElement} bind:this={menu} {...$$restProps}>
|
|
100
|
+
<slot name="flyout" />
|
|
101
|
+
</MenuFlyoutSurface>
|
|
102
|
+
</div>
|
|
103
|
+
<div
|
|
104
|
+
class="menu-flyout-backdrop"
|
|
105
|
+
bind:this={backdropElement}
|
|
106
|
+
on:click={e => e.stopPropagation()}
|
|
107
|
+
on:mousedown={closeFlyout}
|
|
108
|
+
/>
|
|
109
|
+
{/if}
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<style lang="scss">
|
|
113
|
+
@use "./MenuFlyoutWrapper";
|
|
114
|
+
</style>
|
|
File without changes
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
|
|
4
|
+
export let variant: "default" | "compact" | "minimal" = "default";
|
|
5
|
+
export let expanded = true;
|
|
6
|
+
export let menuButton = true;
|
|
7
|
+
export let backButton = true;
|
|
8
|
+
|
|
9
|
+
const dispatch = createEventDispatcher();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<main class="navigation-view variant-{variant}">
|
|
13
|
+
<aside class="navigation-view-pane" class:expanded>
|
|
14
|
+
<header class="navigation-view-pane-header">
|
|
15
|
+
{#if backButton}
|
|
16
|
+
<button type="button" on:click={() => dispatch("back")}>
|
|
17
|
+
{"<-"}
|
|
18
|
+
</button>
|
|
19
|
+
{/if}
|
|
20
|
+
{#if menuButton}
|
|
21
|
+
<button type="button" on:click={() => (expanded = !expanded)}>
|
|
22
|
+
{"-"}
|
|
23
|
+
</button>
|
|
24
|
+
{/if}
|
|
25
|
+
|
|
26
|
+
<slot name="header" />
|
|
27
|
+
</header>
|
|
28
|
+
<slot name="items" />
|
|
29
|
+
<footer class="navigation-view-pane-footer">
|
|
30
|
+
<slot name="footer" />
|
|
31
|
+
</footer>
|
|
32
|
+
</aside>
|
|
33
|
+
<article class="navigation-view-page">
|
|
34
|
+
<slot />
|
|
35
|
+
</article>
|
|
36
|
+
</main>
|
|
37
|
+
|
|
38
|
+
<style lang="scss">
|
|
39
|
+
@use "./NavigationView";
|
|
40
|
+
|
|
41
|
+
@use "../mixins" as *;
|
|
42
|
+
|
|
43
|
+
.navigation-view {
|
|
44
|
+
@include typography-body;
|
|
45
|
+
display: flex;
|
|
46
|
+
inline-size: 100%;
|
|
47
|
+
block-size: 100%;
|
|
48
|
+
&.variant- {
|
|
49
|
+
&-default {
|
|
50
|
+
.navigation-view-pane {
|
|
51
|
+
inline-size: 48px;
|
|
52
|
+
&.expanded {
|
|
53
|
+
inline-size: 320px;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
&-pane {
|
|
59
|
+
@include flex($direction: column);
|
|
60
|
+
user-select: none;
|
|
61
|
+
flex: 0 0 auto;
|
|
62
|
+
block-size: 100%;
|
|
63
|
+
&-header {
|
|
64
|
+
display: block;
|
|
65
|
+
flex: 0 0 auto;
|
|
66
|
+
padding-block-start: 4px;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
&-page {
|
|
70
|
+
@include flex($direction: column);
|
|
71
|
+
flex: 1 1 auto;
|
|
72
|
+
border-start-start-radius: var(--overlay-corner-radius);
|
|
73
|
+
background-clip: padding-box;
|
|
74
|
+
background-color: var(--layer-background-default);
|
|
75
|
+
border: 1px solid var(--card-stroke-default);
|
|
76
|
+
border-block-end: none;
|
|
77
|
+
border-inline-end: none;
|
|
78
|
+
padding-inline: 56px;
|
|
79
|
+
padding-block: 44px;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
:global {
|
|
4
|
+
.number-box input {
|
|
5
|
+
appearance: textfield;
|
|
6
|
+
&::-webkit-outer-spin-button,
|
|
7
|
+
&::-webkit-inner-spin-button {
|
|
8
|
+
appearance: none;
|
|
9
|
+
margin: 0;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.number-box-spinner-flyout {
|
|
15
|
+
@include flex($direction: column);
|
|
16
|
+
border-radius: var(--overlay-corner-radius);
|
|
17
|
+
border: 1px solid var(--surface-stroke-flyout);
|
|
18
|
+
background-clip: padding-box;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
background-color: var(--fds-solid-background-quarternary);
|
|
21
|
+
box-shadow: var(--flyout-shadow);
|
|
22
|
+
position: absolute;
|
|
23
|
+
padding: 2px 4px;
|
|
24
|
+
inset-inline-end: -16px;
|
|
25
|
+
z-index: 100;
|
|
26
|
+
:global(.number-box-spinner) {
|
|
27
|
+
margin: 2px 1px;
|
|
28
|
+
inline-size: 36px;
|
|
29
|
+
block-size: 36px;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import TextBox from "../TextBox/TextBox.svelte";
|
|
3
|
+
import TextBoxButton from "../TextBox/TextBoxButton.svelte";
|
|
4
|
+
|
|
5
|
+
/** @extends {"../TextBox/TextBox.svelte"} */
|
|
6
|
+
/** Determines whether the spinner buttons will be placed in an inline layout. */
|
|
7
|
+
export let inline = false;
|
|
8
|
+
|
|
9
|
+
/** The input's current value. */
|
|
10
|
+
export let value: any = "";
|
|
11
|
+
|
|
12
|
+
/** Minimum value for the input. */
|
|
13
|
+
export let min: number = undefined;
|
|
14
|
+
|
|
15
|
+
/** Maximum value for the input. */
|
|
16
|
+
export let max: number = undefined;
|
|
17
|
+
|
|
18
|
+
/** Controls the interval between two value changes when triggering a spin button. */
|
|
19
|
+
export let step: number = undefined;
|
|
20
|
+
|
|
21
|
+
/** Controls whether the NumberBox is intended for user interaction, and styles it accordingly. */
|
|
22
|
+
export let disabled = false;
|
|
23
|
+
|
|
24
|
+
/** Specifies a custom class name for the NumberBox. */
|
|
25
|
+
let className = "";
|
|
26
|
+
export { className as class };
|
|
27
|
+
|
|
28
|
+
/** Obtains a bound DOM reference to the input element. */
|
|
29
|
+
export let inputElement: HTMLInputElement = null;
|
|
30
|
+
|
|
31
|
+
/** Obtains a bound DOM reference to the NumberBox's container element. */
|
|
32
|
+
export let containerElement: HTMLDivElement = null;
|
|
33
|
+
|
|
34
|
+
/** Obtains a bound DOM reference to the NumberBox's buttons container element. */
|
|
35
|
+
export let buttonsContainerElement: HTMLDivElement = null;
|
|
36
|
+
|
|
37
|
+
/** Obtains a bound DOM reference to the spin button element that increases the input's value. */
|
|
38
|
+
export let spinUpButtonElement: HTMLButtonElement = null;
|
|
39
|
+
|
|
40
|
+
/** Obtains a bound DOM reference to the NumberBox's clear button element. Only available if `clearButton` is set to true, `readonly` is set to false, and a `value` is present. */
|
|
41
|
+
export let clearButtonElement: HTMLButtonElement = null;
|
|
42
|
+
|
|
43
|
+
/** Obtains a bound DOM reference to the spin button element that decreases the input's value. */
|
|
44
|
+
export let spinDownButtonElement: HTMLButtonElement = null;
|
|
45
|
+
|
|
46
|
+
/** Obtains a bound DOM reference to the spin button flyout. Only available when `inline` is set to `false`. */
|
|
47
|
+
export let spinnerFlyoutElement: HTMLDivElement = null;
|
|
48
|
+
|
|
49
|
+
let spinUpTimeout;
|
|
50
|
+
let spinDownTimeout;
|
|
51
|
+
let spinUpInterval;
|
|
52
|
+
let spinDownInterval;
|
|
53
|
+
let spinnerFlyoutOpen = false;
|
|
54
|
+
|
|
55
|
+
function spinUp() {
|
|
56
|
+
stepUp();
|
|
57
|
+
|
|
58
|
+
spinUpTimeout = setTimeout(() => {
|
|
59
|
+
spinUpInterval = setInterval(() => {
|
|
60
|
+
stepUp();
|
|
61
|
+
}, 50);
|
|
62
|
+
}, 500);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function spinDown() {
|
|
66
|
+
stepDown();
|
|
67
|
+
|
|
68
|
+
spinDownTimeout = setTimeout(() => {
|
|
69
|
+
spinDownInterval = setInterval(() => {
|
|
70
|
+
stepDown();
|
|
71
|
+
}, 50);
|
|
72
|
+
}, 500);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function stopSpinIntervals() {
|
|
76
|
+
clearTimeout(spinUpTimeout);
|
|
77
|
+
clearInterval(spinUpInterval);
|
|
78
|
+
clearTimeout(spinDownTimeout);
|
|
79
|
+
clearInterval(spinDownInterval);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function handleTabKey({ key }) {
|
|
83
|
+
if (key === "Tab") spinnerFlyoutOpen = false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function stepUp() {
|
|
87
|
+
inputElement.stepUp();
|
|
88
|
+
value = inputElement.value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function stepDown() {
|
|
92
|
+
inputElement.stepDown();
|
|
93
|
+
value = inputElement.value;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
$: if (value?.toString() === max?.toString() || value?.toString() === min?.toString())
|
|
97
|
+
stopSpinIntervals();
|
|
98
|
+
$: spinUpButtonDisabled = disabled || value?.toString() === max?.toString();
|
|
99
|
+
$: spinDownButtonDisabled = disabled || value?.toString() === min?.toString();
|
|
100
|
+
</script>
|
|
101
|
+
|
|
102
|
+
<svelte:window on:keydown={handleTabKey} />
|
|
103
|
+
|
|
104
|
+
<TextBox
|
|
105
|
+
class="number-box {className ?? ''}"
|
|
106
|
+
type="number"
|
|
107
|
+
bind:inputElement
|
|
108
|
+
bind:containerElement
|
|
109
|
+
bind:buttonsContainerElement
|
|
110
|
+
bind:clearButtonElement
|
|
111
|
+
bind:value
|
|
112
|
+
on:outermousedown={() => (spinnerFlyoutOpen = false)}
|
|
113
|
+
on:change
|
|
114
|
+
on:input
|
|
115
|
+
on:beforeinput
|
|
116
|
+
on:click
|
|
117
|
+
on:blur
|
|
118
|
+
on:focus={() => (spinnerFlyoutOpen = true)}
|
|
119
|
+
on:focus
|
|
120
|
+
on:dblclick
|
|
121
|
+
on:contextmenu
|
|
122
|
+
on:mousedown
|
|
123
|
+
on:mouseup
|
|
124
|
+
on:mouseover
|
|
125
|
+
on:mouseout
|
|
126
|
+
on:mouseenter
|
|
127
|
+
on:mouseleave
|
|
128
|
+
on:keypress
|
|
129
|
+
on:keydown
|
|
130
|
+
on:keyup
|
|
131
|
+
on:clear
|
|
132
|
+
{min}
|
|
133
|
+
{max}
|
|
134
|
+
{step}
|
|
135
|
+
{disabled}
|
|
136
|
+
{...$$restProps}
|
|
137
|
+
>
|
|
138
|
+
<slot />
|
|
139
|
+
<svelte:fragment slot="buttons">
|
|
140
|
+
{#if inline}
|
|
141
|
+
{#if !disabled}
|
|
142
|
+
<TextBoxButton
|
|
143
|
+
on:mousedown={spinUp}
|
|
144
|
+
on:mouseup={stopSpinIntervals}
|
|
145
|
+
on:mouseleave={stopSpinIntervals}
|
|
146
|
+
bind:element={spinUpButtonElement}
|
|
147
|
+
tabindex="-1"
|
|
148
|
+
aria-label="Increase number"
|
|
149
|
+
disabled={spinUpButtonDisabled}
|
|
150
|
+
class="number-box-spinner"
|
|
151
|
+
>
|
|
152
|
+
<svg
|
|
153
|
+
aria-hidden="true"
|
|
154
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
155
|
+
width="12"
|
|
156
|
+
height="12"
|
|
157
|
+
viewBox="0 0 12 12"
|
|
158
|
+
>
|
|
159
|
+
<path
|
|
160
|
+
fill="currentColor"
|
|
161
|
+
d="M2.14645 7.35355C2.34171 7.54882 2.65829 7.54882 2.85355 7.35355L6 4.20711L9.14645 7.35355C9.34171 7.54882 9.65829 7.54882 9.85355 7.35355C10.0488 7.15829 10.0488 6.84171 9.85355 6.64645L6.35355 3.14645C6.15829 2.95118 5.84171 2.95118 5.64645 3.14645L2.14645 6.64645C1.95118 6.84171 1.95118 7.15829 2.14645 7.35355Z"
|
|
162
|
+
/>
|
|
163
|
+
</svg>
|
|
164
|
+
</TextBoxButton>
|
|
165
|
+
<TextBoxButton
|
|
166
|
+
on:mousedown={spinDown}
|
|
167
|
+
on:mouseup={stopSpinIntervals}
|
|
168
|
+
on:mouseleave={stopSpinIntervals}
|
|
169
|
+
bind:element={spinDownButtonElement}
|
|
170
|
+
tabindex="-1"
|
|
171
|
+
aria-label="Decrease number"
|
|
172
|
+
class="number-box-spinner"
|
|
173
|
+
disabled={spinDownButtonDisabled}
|
|
174
|
+
>
|
|
175
|
+
<svg
|
|
176
|
+
aria-hidden="true"
|
|
177
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
178
|
+
width="12"
|
|
179
|
+
height="12"
|
|
180
|
+
viewBox="0 0 12 12"
|
|
181
|
+
>
|
|
182
|
+
<path
|
|
183
|
+
fill="currentColor"
|
|
184
|
+
d="M2.14645 4.64645C2.34171 4.45118 2.65829 4.45118 2.85355 4.64645L6 7.79289L9.14645 4.64645C9.34171 4.45118 9.65829 4.45118 9.85355 4.64645C10.0488 4.84171 10.0488 5.15829 9.85355 5.35355L6.35355 8.85355C6.15829 9.04882 5.84171 9.04882 5.64645 8.85355L2.14645 5.35355C1.95118 5.15829 1.95118 4.84171 2.14645 4.64645Z"
|
|
185
|
+
/>
|
|
186
|
+
</svg>
|
|
187
|
+
</TextBoxButton>
|
|
188
|
+
{/if}
|
|
189
|
+
{:else}
|
|
190
|
+
<TextBoxButton
|
|
191
|
+
{disabled}
|
|
192
|
+
class="number-box-spinner-compact"
|
|
193
|
+
tabindex="-1"
|
|
194
|
+
on:mousedown={() => inputElement.focus()}
|
|
195
|
+
>
|
|
196
|
+
<svg
|
|
197
|
+
aria-hidden="true"
|
|
198
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
199
|
+
height="12"
|
|
200
|
+
width="100%"
|
|
201
|
+
viewBox="128 0 768 1024"
|
|
202
|
+
>
|
|
203
|
+
<path
|
|
204
|
+
fill="currentColor"
|
|
205
|
+
d="M128,384C128,375.333 131.167,367.833 137.5,361.5L487,10.5C494,3.5 502.333,0 512,0C521.667,0 530,3.5 537,10.5L886.5,361.5C892.833,367.833 896,375.333 896,384C896,392.667 892.833,400.167 886.5,406.5C880.167,412.833 872.667,416 864,416C855.333,416 847.833,412.833 841.5,406.5L512,76L182.5,406.5C176.167,412.833 168.667,416 160,416C151.333,416 143.833,412.833 137.5,406.5C131.167,400.167 128,392.667 128,384ZM128,640C128,631.333 131.167,623.833 137.5,617.5C143.833,611.167 151.333,608 160,608C168.667,608 176.167,611.167 182.5,617.5L512,948L841.5,617.5C847.833,611.167 855.333,608 864,608C872.667,608 880.167,611.167 886.5,617.5C892.833,623.833 896,631.333 896,640C896,648.667 892.833,656.167 886.5,662.5L537,1013.5C530,1020.5 521.667,1024 512,1024C502.333,1024 494,1020.5 487,1013.5L137.5,662.5C131.167,656.167 128,648.667 128,640Z"
|
|
206
|
+
/>
|
|
207
|
+
</svg>
|
|
208
|
+
</TextBoxButton>
|
|
209
|
+
{#if spinnerFlyoutOpen}
|
|
210
|
+
<div class="number-box-spinner-flyout" bind:this={spinnerFlyoutElement}>
|
|
211
|
+
<TextBoxButton
|
|
212
|
+
on:mousedown={spinUp}
|
|
213
|
+
on:mouseup={stopSpinIntervals}
|
|
214
|
+
on:mouseleave={stopSpinIntervals}
|
|
215
|
+
bind:element={spinUpButtonElement}
|
|
216
|
+
class="number-box-spinner"
|
|
217
|
+
disabled={spinUpButtonDisabled}
|
|
218
|
+
aria-label="Increase number"
|
|
219
|
+
tabindex="-1"
|
|
220
|
+
>
|
|
221
|
+
<svg
|
|
222
|
+
aria-hidden="true"
|
|
223
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
224
|
+
width="16"
|
|
225
|
+
height="16"
|
|
226
|
+
viewBox="0 0 16 16"
|
|
227
|
+
>
|
|
228
|
+
<path
|
|
229
|
+
fill="currentColor"
|
|
230
|
+
d="M3.14645 10.3536C3.34171 10.5488 3.65829 10.5488 3.85355 10.3536L8 6.20711L12.1464 10.3536C12.3417 10.5488 12.6583 10.5488 12.8536 10.3536C13.0488 10.1583 13.0488 9.84171 12.8536 9.64645L8.35355 5.14645C8.15829 4.95118 7.84171 4.95118 7.64645 5.14645L3.14645 9.64645C2.95118 9.84171 2.95118 10.1583 3.14645 10.3536Z"
|
|
231
|
+
/>
|
|
232
|
+
</svg>
|
|
233
|
+
</TextBoxButton>
|
|
234
|
+
<TextBoxButton
|
|
235
|
+
on:mousedown={spinDown}
|
|
236
|
+
on:mouseup={stopSpinIntervals}
|
|
237
|
+
on:mouseleave={stopSpinIntervals}
|
|
238
|
+
bind:element={spinDownButtonElement}
|
|
239
|
+
tabindex="-1"
|
|
240
|
+
aria-label="Decrease number"
|
|
241
|
+
class="number-box-spinner"
|
|
242
|
+
disabled={spinDownButtonDisabled}
|
|
243
|
+
>
|
|
244
|
+
<svg
|
|
245
|
+
aria-hidden="true"
|
|
246
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
247
|
+
width="16"
|
|
248
|
+
height="16"
|
|
249
|
+
viewBox="0 0 16 16"
|
|
250
|
+
>
|
|
251
|
+
<path
|
|
252
|
+
fill="currentColor"
|
|
253
|
+
d="M3.14645 5.64645C3.34171 5.45118 3.65829 5.45118 3.85355 5.64645L8 9.79289L12.1464 5.64645C12.3417 5.45118 12.6583 5.45118 12.8536 5.64645C13.0488 5.84171 13.0488 6.15829 12.8536 6.35355L8.35355 10.8536C8.15829 11.0488 7.84171 11.0488 7.64645 10.8536L3.14645 6.35355C2.95118 6.15829 2.95118 5.84171 3.14645 5.64645Z"
|
|
254
|
+
/>
|
|
255
|
+
</svg>
|
|
256
|
+
</TextBoxButton>
|
|
257
|
+
</div>
|
|
258
|
+
{/if}
|
|
259
|
+
{/if}
|
|
260
|
+
|
|
261
|
+
<slot name="buttons" />
|
|
262
|
+
</svelte:fragment>
|
|
263
|
+
</TextBox>
|
|
264
|
+
|
|
265
|
+
<style lang="scss">
|
|
266
|
+
@use "./NumberBox";
|
|
267
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
.person-picture {
|
|
4
|
+
@include flex($justify: center, $align: center);
|
|
5
|
+
user-select: none;
|
|
6
|
+
text-align: center;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
inline-size: 100%;
|
|
9
|
+
block-size: 100%;
|
|
10
|
+
flex: 0 0 auto;
|
|
11
|
+
background-color: var(--control-alt-fill-quarternary);
|
|
12
|
+
border: 1px solid var(--card-stroke-default);
|
|
13
|
+
background-clip: padding-box;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
border-radius: 50%;
|
|
16
|
+
font: {
|
|
17
|
+
family: var(--font-family-display);
|
|
18
|
+
weight: 600;
|
|
19
|
+
size: calc(var(--person-picture-size) * (5 / 12));
|
|
20
|
+
}
|
|
21
|
+
&-container {
|
|
22
|
+
display: flex;
|
|
23
|
+
position: relative;
|
|
24
|
+
inline-size: var(--person-picture-size);
|
|
25
|
+
block-size: var(--person-picture-size);
|
|
26
|
+
}
|
|
27
|
+
&-badge {
|
|
28
|
+
@include flex($direction: column, $align: end);
|
|
29
|
+
position: absolute;
|
|
30
|
+
inset-inline-start: 0;
|
|
31
|
+
inset-block-start: 0;
|
|
32
|
+
inline-size: 100%;
|
|
33
|
+
block-size: 100%;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/** The size of the picture in pixels. */
|
|
3
|
+
export let size = 72;
|
|
4
|
+
|
|
5
|
+
/** Source URL used for the picture. */
|
|
6
|
+
export let src: string = undefined;
|
|
7
|
+
|
|
8
|
+
/** Defines the alt text used if an `src` attribute is specified. Also used as fallback text if no `src` or slot text is provided. */
|
|
9
|
+
export let alt: string = undefined;
|
|
10
|
+
|
|
11
|
+
/** Specifies a custom class name for the inner picture. */
|
|
12
|
+
let className = "";
|
|
13
|
+
export { className as class };
|
|
14
|
+
|
|
15
|
+
/** Obtains a bound DOM reference to the inner picture element. */
|
|
16
|
+
export let element: HTMLImageElement | HTMLDivElement = null;
|
|
17
|
+
|
|
18
|
+
/** Obtains a bound DOM reference to the outer picture container. */
|
|
19
|
+
export let containerElement: HTMLDivElement = null;
|
|
20
|
+
|
|
21
|
+
let error = false;
|
|
22
|
+
|
|
23
|
+
$: if (src) error = false;
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
class="person-picture-container"
|
|
28
|
+
style="--fds-person-picture-size: {size}px"
|
|
29
|
+
bind:this={containerElement}
|
|
30
|
+
>
|
|
31
|
+
{#if src && !error}
|
|
32
|
+
<img
|
|
33
|
+
bind:this={element}
|
|
34
|
+
on:error={() => (error = true)}
|
|
35
|
+
class="person-picture {className}"
|
|
36
|
+
width={size}
|
|
37
|
+
height={size}
|
|
38
|
+
{src}
|
|
39
|
+
{alt}
|
|
40
|
+
{...$$restProps}
|
|
41
|
+
/>
|
|
42
|
+
{:else}
|
|
43
|
+
<div bind:this={element} class="person-picture {className}" {...$$restProps}>
|
|
44
|
+
<slot>
|
|
45
|
+
{alt
|
|
46
|
+
?.split(" ")
|
|
47
|
+
.map(i => i.charAt(0))
|
|
48
|
+
.join("")
|
|
49
|
+
.toUpperCase() ?? ""}
|
|
50
|
+
</slot>
|
|
51
|
+
</div>
|
|
52
|
+
{/if}
|
|
53
|
+
{#if $$slots.badge}
|
|
54
|
+
<span class="person-picture-badge">
|
|
55
|
+
<slot name="badge" />
|
|
56
|
+
</span>
|
|
57
|
+
{/if}
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<style lang="scss">
|
|
61
|
+
@use "./PersonPicture";
|
|
62
|
+
</style>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
@keyframes indeterminate-1 {
|
|
4
|
+
0% {
|
|
5
|
+
opacity: 1;
|
|
6
|
+
transform: translateX(-100%);
|
|
7
|
+
}
|
|
8
|
+
75% {
|
|
9
|
+
opacity: 1;
|
|
10
|
+
transform: translateX(300%);
|
|
11
|
+
}
|
|
12
|
+
75.01% {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
}
|
|
15
|
+
100% {
|
|
16
|
+
opacity: 0;
|
|
17
|
+
transform: translateX(300%);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
@keyframes indeterminate-2 {
|
|
21
|
+
0% {
|
|
22
|
+
opacity: 0;
|
|
23
|
+
transform: translateX(-150%);
|
|
24
|
+
}
|
|
25
|
+
37.49% {
|
|
26
|
+
opacity: 0;
|
|
27
|
+
}
|
|
28
|
+
37.5% {
|
|
29
|
+
opacity: 1;
|
|
30
|
+
transform: translateX(-150%);
|
|
31
|
+
}
|
|
32
|
+
100% {
|
|
33
|
+
transform: translateX(166.66%);
|
|
34
|
+
opacity: 1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.progress-bar {
|
|
39
|
+
@include flex($align: center);
|
|
40
|
+
width: 100%;
|
|
41
|
+
min-block-size: 3px;
|
|
42
|
+
&-track {
|
|
43
|
+
height: 3px;
|
|
44
|
+
max-width: 50%;
|
|
45
|
+
transition: var(--control-fast-duration) linear fill;
|
|
46
|
+
fill: var(--accent-default);
|
|
47
|
+
}
|
|
48
|
+
&-rail {
|
|
49
|
+
fill: var(--control-strong-stroke-default);
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 1px;
|
|
52
|
+
}
|
|
53
|
+
&.indeterminate {
|
|
54
|
+
.progress-bar- {
|
|
55
|
+
&rail {
|
|
56
|
+
display: none;
|
|
57
|
+
}
|
|
58
|
+
&track {
|
|
59
|
+
animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1);
|
|
60
|
+
&:first-of-type {
|
|
61
|
+
width: 40%;
|
|
62
|
+
animation: 2s infinite indeterminate-1;
|
|
63
|
+
}
|
|
64
|
+
&:nth-of-type(2) {
|
|
65
|
+
width: 60%;
|
|
66
|
+
animation: 2s infinite indeterminate-2;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// &.status- {
|
|
72
|
+
// &paused {
|
|
73
|
+
// .progress-bar-fill {
|
|
74
|
+
// fill: var(--system-caution);
|
|
75
|
+
// }
|
|
76
|
+
// }
|
|
77
|
+
// &error {
|
|
78
|
+
// .progress-bar-fill {
|
|
79
|
+
// fill: var(--system-critical);
|
|
80
|
+
// }
|
|
81
|
+
// }
|
|
82
|
+
// }
|
|
83
|
+
}
|