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,225 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { get_current_component } from "svelte/internal";
|
|
4
|
+
import { externalMouseEvents, createEventForwarder } from "$lib/internal";
|
|
5
|
+
|
|
6
|
+
import TextBoxButton from "../TextBox/TextBoxButton.svelte";
|
|
7
|
+
|
|
8
|
+
type TextInputTypes =
|
|
9
|
+
| "text"
|
|
10
|
+
| "number"
|
|
11
|
+
| "search"
|
|
12
|
+
| "password"
|
|
13
|
+
| "email"
|
|
14
|
+
| "tel"
|
|
15
|
+
| "url"
|
|
16
|
+
| "date"
|
|
17
|
+
| "datetime-local"
|
|
18
|
+
| "month"
|
|
19
|
+
| "time"
|
|
20
|
+
| "week";
|
|
21
|
+
|
|
22
|
+
/** The input's current value. */
|
|
23
|
+
export let value: any = "";
|
|
24
|
+
|
|
25
|
+
/** Determiness the input type of the textbox. */
|
|
26
|
+
export let type: TextInputTypes = "text";
|
|
27
|
+
|
|
28
|
+
/** The initial placeholder text displayed if no value is present. */
|
|
29
|
+
export let placeholder: string = undefined;
|
|
30
|
+
|
|
31
|
+
/** Determines whether a text clear button is present. */
|
|
32
|
+
export let clearButton = true;
|
|
33
|
+
|
|
34
|
+
/** Determines whether a search button is present when `type` is set to "search". */
|
|
35
|
+
export let searchButton = true;
|
|
36
|
+
|
|
37
|
+
/** Determines whether a password reveal button is present when `type` is set to "password". */
|
|
38
|
+
export let revealButton = true;
|
|
39
|
+
|
|
40
|
+
/** Determines whether the textbox can be typed in or not. */
|
|
41
|
+
export let readonly = false;
|
|
42
|
+
|
|
43
|
+
/** Controls whether the TextBox is intended for user interaction, and styles it accordingly. */
|
|
44
|
+
export let disabled = false;
|
|
45
|
+
|
|
46
|
+
/** Specifies a custom class name for the TextBox container. */
|
|
47
|
+
let className = "";
|
|
48
|
+
export { className as class };
|
|
49
|
+
|
|
50
|
+
/** Obtains a bound DOM reference to the TextBox's input element. */
|
|
51
|
+
export let inputElement: HTMLInputElement = null;
|
|
52
|
+
|
|
53
|
+
/** Obtains a bound DOM reference to the TextBox's container element. */
|
|
54
|
+
export let containerElement: HTMLDivElement = null;
|
|
55
|
+
|
|
56
|
+
/** Obtains a bound DOM reference to the TextBox's buttons container element. */
|
|
57
|
+
export let buttonsContainerElement: HTMLDivElement = null;
|
|
58
|
+
|
|
59
|
+
/** Obtains a bound DOM reference to the TextBox's clear button element. Only available if `clearButton` is set to true, `readonly` is set to false, and a `value` is present. */
|
|
60
|
+
export let clearButtonElement: HTMLButtonElement = null;
|
|
61
|
+
|
|
62
|
+
/** Obtains a bound DOM reference to the TextBox's search button element. Only available if `type` is set to `search`. */
|
|
63
|
+
export let searchButtonElement: HTMLButtonElement = null;
|
|
64
|
+
|
|
65
|
+
/** Obtains a bound DOM reference to the TextBox's reveal button element. Only available if `type` is set to `password`. */
|
|
66
|
+
export let revealButtonElement: HTMLButtonElement = null;
|
|
67
|
+
|
|
68
|
+
const dispatch = createEventDispatcher();
|
|
69
|
+
const forwardEvents = createEventForwarder(get_current_component(), [
|
|
70
|
+
"clear",
|
|
71
|
+
"search",
|
|
72
|
+
"reveal",
|
|
73
|
+
"outermousedown"
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
function handleClear(event) {
|
|
77
|
+
dispatch("clear", event);
|
|
78
|
+
inputElement.focus();
|
|
79
|
+
value = "";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function handleSearch(event) {
|
|
83
|
+
dispatch("search", event);
|
|
84
|
+
inputElement.focus();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function handleReveal(event) {
|
|
88
|
+
inputElement.focus();
|
|
89
|
+
inputElement.setAttribute("type", "text");
|
|
90
|
+
dispatch("reveal", event);
|
|
91
|
+
let revealButtonMouseDown = true;
|
|
92
|
+
const hidePassword = () => {
|
|
93
|
+
if (!revealButtonMouseDown) return;
|
|
94
|
+
inputElement.focus();
|
|
95
|
+
revealButtonMouseDown = false;
|
|
96
|
+
inputElement.setAttribute("type", "password");
|
|
97
|
+
window.removeEventListener("mouseup", hidePassword);
|
|
98
|
+
};
|
|
99
|
+
window.addEventListener("mouseup", hidePassword);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const inputProps = {
|
|
103
|
+
class: "text-box",
|
|
104
|
+
disabled: disabled || undefined,
|
|
105
|
+
readonly: readonly || undefined,
|
|
106
|
+
placeholder: placeholder || undefined,
|
|
107
|
+
...$$restProps
|
|
108
|
+
};
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<!--
|
|
112
|
+
@component
|
|
113
|
+
The TextBox control lets a user type text into an app. The text displays on the screen in a simple, plaintext format on a single line. It additionally comes with a set of buttons which allow users to perform specialized actions on the text, such as showing a password or clearing the TextBox's contents. [Docs](https://fluent-svelte.vercel.app/docs/components/texbox)
|
|
114
|
+
- Usage:
|
|
115
|
+
```tsx
|
|
116
|
+
<TextBox placeholder="Enter your name." />
|
|
117
|
+
```
|
|
118
|
+
-->
|
|
119
|
+
<div
|
|
120
|
+
class="text-box-container {className}"
|
|
121
|
+
class:disabled
|
|
122
|
+
bind:this={containerElement}
|
|
123
|
+
use:externalMouseEvents={{ type: "mousedown" }}
|
|
124
|
+
on:outermousedown
|
|
125
|
+
>
|
|
126
|
+
<!-- Dirty workaround for the fact that svelte can't handle two-way binding when the input type is dynamic. -->
|
|
127
|
+
<!-- prettier-ignore -->
|
|
128
|
+
{#if type === "text"}
|
|
129
|
+
<input type="text" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
130
|
+
{:else if type === "number"}
|
|
131
|
+
<input type="number" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
132
|
+
{:else if type === "search"}
|
|
133
|
+
<input type="search" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
134
|
+
{:else if type === "password"}
|
|
135
|
+
<input type="password" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
136
|
+
{:else if type === "email"}
|
|
137
|
+
<input type="email" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
138
|
+
{:else if type === "tel"}
|
|
139
|
+
<input type="tel" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
140
|
+
{:else if type === "url"}
|
|
141
|
+
<input type="url" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
142
|
+
{:else if type === "date"}
|
|
143
|
+
<input type="date" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
144
|
+
{:else if type === "datetime-local"}
|
|
145
|
+
<input type="datetime-local" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
146
|
+
{:else if type === "month"}
|
|
147
|
+
<input type="month" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
148
|
+
{:else if type === "time"}
|
|
149
|
+
<input type="time" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
150
|
+
{:else if type === "week"}
|
|
151
|
+
<input type="week" bind:value bind:this={inputElement} use:forwardEvents {...inputProps} />
|
|
152
|
+
{/if}
|
|
153
|
+
<div class="text-box-underline" />
|
|
154
|
+
<div class="text-box-buttons" bind:this={buttonsContainerElement}>
|
|
155
|
+
{#if !disabled}
|
|
156
|
+
{#if clearButton && value && !readonly}
|
|
157
|
+
<TextBoxButton
|
|
158
|
+
class="text-box-clear-button"
|
|
159
|
+
aria-label="Clear value"
|
|
160
|
+
on:click={handleClear}
|
|
161
|
+
bind:element={clearButtonElement}
|
|
162
|
+
>
|
|
163
|
+
<svg
|
|
164
|
+
aria-hidden="true"
|
|
165
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
166
|
+
width="12"
|
|
167
|
+
height="12"
|
|
168
|
+
viewBox="0 0 12 12"
|
|
169
|
+
>
|
|
170
|
+
<path
|
|
171
|
+
fill="currentColor"
|
|
172
|
+
d="M2.08859 2.21569L2.14645 2.14645C2.32001 1.97288 2.58944 1.9536 2.78431 2.08859L2.85355 2.14645L6 5.293L9.14645 2.14645C9.34171 1.95118 9.65829 1.95118 9.85355 2.14645C10.0488 2.34171 10.0488 2.65829 9.85355 2.85355L6.707 6L9.85355 9.14645C10.0271 9.32001 10.0464 9.58944 9.91141 9.78431L9.85355 9.85355C9.67999 10.0271 9.41056 10.0464 9.21569 9.91141L9.14645 9.85355L6 6.707L2.85355 9.85355C2.65829 10.0488 2.34171 10.0488 2.14645 9.85355C1.95118 9.65829 1.95118 9.34171 2.14645 9.14645L5.293 6L2.14645 2.85355C1.97288 2.67999 1.9536 2.41056 2.08859 2.21569L2.14645 2.14645L2.08859 2.21569Z"
|
|
173
|
+
/>
|
|
174
|
+
</svg>
|
|
175
|
+
</TextBoxButton>
|
|
176
|
+
{/if}
|
|
177
|
+
{#if type === "search" && searchButton}
|
|
178
|
+
<TextBoxButton
|
|
179
|
+
aria-label="Search"
|
|
180
|
+
on:click={handleSearch}
|
|
181
|
+
bind:element={searchButtonElement}
|
|
182
|
+
>
|
|
183
|
+
<svg
|
|
184
|
+
aria-hidden="true"
|
|
185
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
186
|
+
width="12"
|
|
187
|
+
height="12"
|
|
188
|
+
viewBox="0 0 12 12"
|
|
189
|
+
>
|
|
190
|
+
<path
|
|
191
|
+
d="M5.00038 1C2.79103 1 1 2.7909 1 5.00008C1 7.20927 2.79103 9.00017 5.00038 9.00017C5.92463 9.00017 6.77568 8.68675 7.45302 8.1604L10.1464 10.8536C10.3416 11.0488 10.6583 11.0488 10.8535 10.8536C11.0488 10.6583 11.0488 10.3417 10.8535 10.1464L8.16028 7.45337C8.68705 6.77595 9.00075 5.92465 9.00075 5.00008C9.00075 2.7909 7.20972 1 5.00038 1ZM2.00009 5.00008C2.00009 3.34319 3.34337 2.00002 5.00038 2.00002C6.65739 2.00002 8.00066 3.34319 8.00066 5.00008C8.00066 6.65697 6.65739 8.00015 5.00038 8.00015C3.34337 8.00015 2.00009 6.65697 2.00009 5.00008Z"
|
|
192
|
+
fill="currentColor"
|
|
193
|
+
/>
|
|
194
|
+
</svg>
|
|
195
|
+
</TextBoxButton>
|
|
196
|
+
{/if}
|
|
197
|
+
{#if type === "password" && value && revealButton}
|
|
198
|
+
<TextBoxButton
|
|
199
|
+
aria-label="Reveal password"
|
|
200
|
+
on:mousedown={handleReveal}
|
|
201
|
+
bind:element={revealButtonElement}
|
|
202
|
+
>
|
|
203
|
+
<svg
|
|
204
|
+
aria-hidden="true"
|
|
205
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
206
|
+
width="10"
|
|
207
|
+
height="10"
|
|
208
|
+
viewBox="0 171 1024 683"
|
|
209
|
+
>
|
|
210
|
+
<path
|
|
211
|
+
d="M0,554.5C0,550.833 0.5,547.167 1.5,543.5C11.5,505.833 25.75,470.417 44.25,437.25C62.75,404.083 84.5833,373.667 109.75,346C134.917,318.333 162.75,293.667 193.25,272C223.75,250.333 256.25,231.917 290.75,216.75C325.25,201.583 361.167,190.083 398.5,182.25C435.833,174.417 473.667,170.5 512,170.5C550,170.5 587.583,174.417 624.75,182.25C661.917,190.083 697.75,201.5 732.25,216.5C766.75,231.5 799.417,249.917 830.25,271.75C861.083,293.583 889.083,318.25 914.25,345.75C939.417,373.25 961.25,403.5 979.75,436.5C998.25,469.5 1012.5,504.833 1022.5,542.5C1023.5,546.167 1024,550 1024,554C1024,566 1019.92,576.083 1011.75,584.25C1003.58,592.417 993.5,596.5 981.5,596.5C971.5,596.5 962.917,593.667 955.75,588C948.583,582.333 943.333,574.833 940,565.5C937,556.167 934.083,547.5 931.25,539.5C928.417,531.5 925.5,523.583 922.5,515.75C919.5,507.917 916.167,500.167 912.5,492.5C908.833,484.833 904.333,476.667 899,468C879.333,435 855.583,405.417 827.75,379.25C799.917,353.083 769.333,330.917 736,312.75C702.667,294.583 667.417,280.583 630.25,270.75C593.083,260.917 555.5,256 517.5,256L506.5,256C468.5,256 430.917,260.917 393.75,270.75C356.583,280.583 321.333,294.667 288,313C254.667,331.333 224,353.583 196,379.75C168,405.917 144.333,435.5 125,468.5C119.667,477.167 115.167,485.417 111.5,493.25C107.833,501.083 104.5,508.833 101.5,516.5C98.5,524.167 95.5833,532 92.75,540C89.9167,548 87,556.667 84,566C80.6667,575.333 75.5,582.917 68.5,588.75C61.5,594.583 52.8333,597.5 42.5,597.5C36.8333,597.5 31.4167,596.333 26.25,594C21.0833,591.667 16.5833,588.583 12.75,584.75C8.91667,580.917 5.83333,576.417 3.5,571.25C1.16667,566.083 0,560.5 0,554.5ZM256,597.5L256,592.5C256,557.833 262.917,525.25 276.75,494.75C290.583,464.25 309.25,437.667 332.75,415C356.25,392.333 383.417,374.417 414.25,361.25C445.083,348.083 477.667,341.5 512,341.5C547.333,341.5 580.583,348.167 611.75,361.5C642.917,374.833 670.083,393.083 693.25,416.25C716.417,439.417 734.667,466.583 748,497.75C761.333,528.917 768,562.167 768,597.5C768,632.833 761.333,666.083 748,697.25C734.667,728.417 716.417,755.583 693.25,778.75C670.083,801.917 642.917,820.167 611.75,833.5C580.583,846.833 547.333,853.5 512,853.5C476.667,853.5 443.417,846.833 412.25,833.5C381.083,820.167 353.917,801.917 330.75,778.75C307.583,755.583 289.333,728.417 276,697.25C262.667,666.083 256,632.833 256,597.5ZM682.5,597.5L682.5,594C682.5,571 677.917,549.333 668.75,529C659.583,508.667 647.167,490.917 631.5,475.75C615.833,460.583 597.667,448.583 577,439.75C556.333,430.917 534.667,426.5 512,426.5C488.333,426.5 466.167,431 445.5,440C424.833,449 406.833,461.25 391.5,476.75C376.167,492.25 364,510.417 355,531.25C346,552.083 341.5,574.167 341.5,597.5C341.5,621.167 346,643.333 355,664C364,684.667 376.167,702.667 391.5,718C406.833,733.333 424.833,745.5 445.5,754.5C466.167,763.5 488.333,768 512,768C535.333,768 557.417,763.5 578.25,754.5C599.083,745.5 617.167,733.333 632.5,718C647.833,702.667 660,684.667 669,664C678,643.333 682.5,621.167 682.5,597.5Z"
|
|
212
|
+
fill="currentColor"
|
|
213
|
+
/>
|
|
214
|
+
</svg>
|
|
215
|
+
</TextBoxButton>
|
|
216
|
+
{/if}
|
|
217
|
+
{/if}
|
|
218
|
+
<slot name="buttons" {value} />
|
|
219
|
+
</div>
|
|
220
|
+
<slot />
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<style lang="scss">
|
|
224
|
+
@use "./TextBox";
|
|
225
|
+
</style>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
.text-box-button {
|
|
4
|
+
@include flex($align: center, $justify: center);
|
|
5
|
+
outline: none;
|
|
6
|
+
border: none;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
min-inline-size: 26px;
|
|
9
|
+
min-block-size: 22px;
|
|
10
|
+
padding: 3px 5px;
|
|
11
|
+
color: var(--text-secondary);
|
|
12
|
+
border-radius: var(--control-corner-radius);
|
|
13
|
+
background-color: var(--subtle-fill-transparent);
|
|
14
|
+
&:focus-visible {
|
|
15
|
+
box-shadow: var(--focus-stroke);
|
|
16
|
+
}
|
|
17
|
+
&:hover {
|
|
18
|
+
background-color: var(--subtle-fill-secondary);
|
|
19
|
+
}
|
|
20
|
+
&:active {
|
|
21
|
+
color: var(--text-tertiary);
|
|
22
|
+
background-color: var(--subtle-fill-tertiary);
|
|
23
|
+
}
|
|
24
|
+
&:disabled {
|
|
25
|
+
background-color: var(--subtle-fill-tertiary);
|
|
26
|
+
color: var(--text-disabled);
|
|
27
|
+
}
|
|
28
|
+
:global(svg) {
|
|
29
|
+
pointer-events: none;
|
|
30
|
+
min-inline-size: 12px;
|
|
31
|
+
min-block-size: 12px;
|
|
32
|
+
fill: currentColor;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventForwarder } from "$lib/internal";
|
|
3
|
+
import { get_current_component } from "svelte/internal";
|
|
4
|
+
|
|
5
|
+
export let type = "button";
|
|
6
|
+
|
|
7
|
+
let className = "";
|
|
8
|
+
export { className as class };
|
|
9
|
+
|
|
10
|
+
export let element: HTMLButtonElement = null;
|
|
11
|
+
|
|
12
|
+
const forwardEvents = createEventForwarder(get_current_component());
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<button
|
|
16
|
+
use:forwardEvents
|
|
17
|
+
bind:this={element}
|
|
18
|
+
class="text-box-button {className}"
|
|
19
|
+
{type}
|
|
20
|
+
{...$$restProps}
|
|
21
|
+
>
|
|
22
|
+
<slot />
|
|
23
|
+
</button>
|
|
24
|
+
|
|
25
|
+
<style lang="scss">
|
|
26
|
+
@use "./TextBoxButton";
|
|
27
|
+
</style>
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
.toggle-switch {
|
|
4
|
+
@include flex($inline: true, $align: center);
|
|
5
|
+
@include typography-body;
|
|
6
|
+
|
|
7
|
+
position: relative;
|
|
8
|
+
margin: 0;
|
|
9
|
+
border: 1px solid var(--control-strong-stroke-default);
|
|
10
|
+
border-radius: 20px;
|
|
11
|
+
outline: none;
|
|
12
|
+
background-color: var(--control-alt-fill-secondary);
|
|
13
|
+
appearance: none;
|
|
14
|
+
inline-size: 40px;
|
|
15
|
+
block-size: 20px;
|
|
16
|
+
|
|
17
|
+
&::before {
|
|
18
|
+
content: "";
|
|
19
|
+
position: absolute;
|
|
20
|
+
border-radius: 7px;
|
|
21
|
+
background-color: var(--text-secondary);
|
|
22
|
+
transition: var(--control-fast-duration) ease-in-out transform,
|
|
23
|
+
var(--control-fast-duration) var(--control-fast-out-slow-in-easing) height,
|
|
24
|
+
var(--control-fast-duration) var(--control-fast-out-slow-in-easing) width,
|
|
25
|
+
var(--control-fast-duration) var(--control-fast-out-slow-in-easing) margin,
|
|
26
|
+
var(--control-faster-duration) linear background;
|
|
27
|
+
inset-inline-start: 3px;
|
|
28
|
+
inline-size: 12px;
|
|
29
|
+
block-size: 12px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:focus-visible {
|
|
33
|
+
box-shadow: var(--focus-stroke);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:hover {
|
|
37
|
+
background-color: var(--control-alt-fill-tertiary);
|
|
38
|
+
|
|
39
|
+
&::before {
|
|
40
|
+
inline-size: 14px;
|
|
41
|
+
block-size: 14px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&:active {
|
|
46
|
+
background-color: var(--control-alt-fill-quarternary);
|
|
47
|
+
|
|
48
|
+
&::before {
|
|
49
|
+
inline-size: 17px;
|
|
50
|
+
block-size: 14px;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:disabled {
|
|
55
|
+
border-color: var(--control-strong-stroke-disabled);
|
|
56
|
+
background-color: var(--control-alt-fill-disabled);
|
|
57
|
+
|
|
58
|
+
&::before {
|
|
59
|
+
margin: 0 !important;
|
|
60
|
+
background-color: var(--text-disabled);
|
|
61
|
+
box-shadow: none;
|
|
62
|
+
inline-size: 12px;
|
|
63
|
+
block-size: 12px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
+ span {
|
|
67
|
+
color: var(--text-disabled);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:checked {
|
|
72
|
+
border: none;
|
|
73
|
+
background-color: var(--accent-default);
|
|
74
|
+
|
|
75
|
+
&::before {
|
|
76
|
+
background-color: var(--text-on-accent-primary);
|
|
77
|
+
box-shadow: 0 0 0 1px solid var(--control-stroke-default);
|
|
78
|
+
transform: translateX(20px);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:hover {
|
|
82
|
+
background-color: var(--accent-secondary);
|
|
83
|
+
|
|
84
|
+
&::before {
|
|
85
|
+
margin-inline-start: -1px;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&:active {
|
|
90
|
+
background-color: var(--accent-tertiary);
|
|
91
|
+
|
|
92
|
+
&::before {
|
|
93
|
+
margin-inline-start: -4px;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&:disabled {
|
|
98
|
+
background-color: var(--accent-disabled);
|
|
99
|
+
&::before {
|
|
100
|
+
box-shadow: none;
|
|
101
|
+
background-color: var(--text-on-accent-disabled);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&-container {
|
|
107
|
+
@include flex($inline: true, $align: center);
|
|
108
|
+
@include typography-body;
|
|
109
|
+
|
|
110
|
+
color: var(--text-primary);
|
|
111
|
+
user-select: none;
|
|
112
|
+
min-block-size: 32px;
|
|
113
|
+
|
|
114
|
+
> span {
|
|
115
|
+
padding-inline-start: 8px;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { get_current_component } from "svelte/internal";
|
|
3
|
+
import { createEventForwarder } from "$lib/internal";
|
|
4
|
+
|
|
5
|
+
/** Controls whether the switch is toggled or not. */
|
|
6
|
+
export let checked = false;
|
|
7
|
+
|
|
8
|
+
/** Sets the input element's native `value` attribute for usage in forms. */
|
|
9
|
+
export let value: any = undefined;
|
|
10
|
+
|
|
11
|
+
/** Controls whether the switch is intended for user interaction, and styles it accordingly. */
|
|
12
|
+
export let disabled = false;
|
|
13
|
+
|
|
14
|
+
/** Specifies a custom class name for the switch. */
|
|
15
|
+
let className = "";
|
|
16
|
+
export { className as class };
|
|
17
|
+
|
|
18
|
+
/** Obtains a bound DOM reference to the switch's <input /> element. */
|
|
19
|
+
export let inputElement: HTMLInputElement = null;
|
|
20
|
+
|
|
21
|
+
/** Obtains a bound DOM reference to the switch's outer container element. */
|
|
22
|
+
export let containerElement: HTMLLabelElement = null;
|
|
23
|
+
|
|
24
|
+
const forwardEvents = createEventForwarder(get_current_component());
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<!--
|
|
28
|
+
@component
|
|
29
|
+
The toggle switch represents a physical switch that allows users to turn things on or off, like a light switch. Use toggle switch controls to present users with two mutually exclusive options (such as on/off), where choosing an option provides immediate results. [Docs](https://fluent-svelte.vercel.app/docs/components/radiobutton)
|
|
30
|
+
- Usage:
|
|
31
|
+
```tsx
|
|
32
|
+
<ToggleSwitch bind:checked />
|
|
33
|
+
```
|
|
34
|
+
-->
|
|
35
|
+
<label class="toggle-switch-container" bind:this={containerElement}>
|
|
36
|
+
<input
|
|
37
|
+
use:forwardEvents
|
|
38
|
+
class="toggle-switch {className}"
|
|
39
|
+
type="checkbox"
|
|
40
|
+
bind:checked
|
|
41
|
+
bind:this={inputElement}
|
|
42
|
+
{value}
|
|
43
|
+
{disabled}
|
|
44
|
+
{...$$restProps}
|
|
45
|
+
/>
|
|
46
|
+
{#if $$slots.default}
|
|
47
|
+
<span>
|
|
48
|
+
<slot />
|
|
49
|
+
</span>
|
|
50
|
+
{/if}
|
|
51
|
+
</label>
|
|
52
|
+
|
|
53
|
+
<style lang="scss">
|
|
54
|
+
@use "./ToggleSwitch";
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@use "../mixins" as *;
|
|
2
|
+
|
|
3
|
+
.tooltip {
|
|
4
|
+
@include flex($inline: true, $align: center, $justify: center);
|
|
5
|
+
@include typography-body;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
inline-size: max-content;
|
|
8
|
+
max-inline-size: 320px;
|
|
9
|
+
padding-inline: 8px;
|
|
10
|
+
padding-block: 5px 7px;
|
|
11
|
+
background-clip: padding-box;
|
|
12
|
+
background-color: var(--fds-solid-background-quarternary);
|
|
13
|
+
border: 1px solid var(--surface-stroke-flyout);
|
|
14
|
+
border-radius: var(--control-corner-radius);
|
|
15
|
+
box-shadow: var(--tooltip-shadow);
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { createEventForwarder } from "$lib/internal";
|
|
3
|
+
import { get_current_component } from "svelte/internal";
|
|
4
|
+
|
|
5
|
+
/** Specifies a custom class name for the surface. */
|
|
6
|
+
let className = "";
|
|
7
|
+
export { className as class };
|
|
8
|
+
|
|
9
|
+
/** Obtains a bound DOM reference to the surface element. */
|
|
10
|
+
export let element: HTMLDivElement = null;
|
|
11
|
+
|
|
12
|
+
const forwardEvents = createEventForwarder(get_current_component());
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
class="tooltip {className}"
|
|
17
|
+
role="tooltip"
|
|
18
|
+
use:forwardEvents
|
|
19
|
+
bind:this={element}
|
|
20
|
+
{...$$restProps}
|
|
21
|
+
>
|
|
22
|
+
<slot />
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<style lang="scss">
|
|
26
|
+
@use "./TooltipSurface";
|
|
27
|
+
</style>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
.tooltip- {
|
|
2
|
+
&wrapper {
|
|
3
|
+
position: relative;
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
&anchor {
|
|
7
|
+
pointer-events: none;
|
|
8
|
+
position: absolute;
|
|
9
|
+
z-index: 100;
|
|
10
|
+
&.placement- {
|
|
11
|
+
&top {
|
|
12
|
+
bottom: calc(100% + var(--tooltip-offset));
|
|
13
|
+
}
|
|
14
|
+
&bottom {
|
|
15
|
+
top: calc(100% + var(--tooltip-offset));
|
|
16
|
+
}
|
|
17
|
+
&left {
|
|
18
|
+
right: calc(100% + var(--tooltip-offset));
|
|
19
|
+
}
|
|
20
|
+
&right {
|
|
21
|
+
left: calc(100% + var(--tooltip-offset));
|
|
22
|
+
}
|
|
23
|
+
&top,
|
|
24
|
+
&bottom {
|
|
25
|
+
&.alignment- {
|
|
26
|
+
&start {
|
|
27
|
+
inset-inline-start: 0;
|
|
28
|
+
}
|
|
29
|
+
&end {
|
|
30
|
+
inset-inline-end: 0;
|
|
31
|
+
}
|
|
32
|
+
¢er {
|
|
33
|
+
inset-inline-start: 50%;
|
|
34
|
+
transform: translateX(-50%);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
&left,
|
|
39
|
+
&right {
|
|
40
|
+
&.alignment- {
|
|
41
|
+
&start {
|
|
42
|
+
inset-block-start: 0;
|
|
43
|
+
}
|
|
44
|
+
&end {
|
|
45
|
+
inset-block-end: 0;
|
|
46
|
+
}
|
|
47
|
+
¢er {
|
|
48
|
+
inset-block-start: 50%;
|
|
49
|
+
transform: translateY(-50%);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
&auto {
|
|
54
|
+
transform: translateY(-100%);
|
|
55
|
+
&.alignment- {
|
|
56
|
+
¢er {
|
|
57
|
+
transform: translate(-50%, -100%);
|
|
58
|
+
}
|
|
59
|
+
&end {
|
|
60
|
+
transform: translate(-100%, -100%);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { fade } from "svelte/transition";
|
|
4
|
+
import { getCSSDuration } from "$lib/internal";
|
|
5
|
+
|
|
6
|
+
import TooltipSurface from "./TooltipSurface.svelte";
|
|
7
|
+
|
|
8
|
+
/** Specifies the tooltip's text content. */
|
|
9
|
+
export let text = "";
|
|
10
|
+
|
|
11
|
+
/** Distance of the tooltip from the alignment axis in pixels. */
|
|
12
|
+
export let offset = 24;
|
|
13
|
+
|
|
14
|
+
/** Direction that the tooltip will appear from. */
|
|
15
|
+
export let placement: "top" | "bottom" | "left" | "right" | "auto" = "auto";
|
|
16
|
+
|
|
17
|
+
/** Alignment of the tooltip along the placement target's given axis. */
|
|
18
|
+
export let alignment: "start" | "center" | "end" = "center";
|
|
19
|
+
|
|
20
|
+
/** Allows the tooltip to follow the user's cursor if `placement` is set to `auto`. */
|
|
21
|
+
export let followCursor = false;
|
|
22
|
+
|
|
23
|
+
/** Prevents the tooltip from disappearing after cursor leaves bounds. */
|
|
24
|
+
export let persistent = false;
|
|
25
|
+
|
|
26
|
+
/** Determines if the tooltip is visible or not. */
|
|
27
|
+
export let visible = false;
|
|
28
|
+
|
|
29
|
+
/** Initial delay time for the tooltip to become visible in millseconds. */
|
|
30
|
+
export let delay = 1000;
|
|
31
|
+
|
|
32
|
+
/** Obtains a bound reference to the tooltip surface element. */
|
|
33
|
+
export let tooltipElement: HTMLDivElement = null;
|
|
34
|
+
|
|
35
|
+
/** Obtains a bound reference to the tooltip's positioning anchor element. */
|
|
36
|
+
export let anchorElement: HTMLDivElement = null;
|
|
37
|
+
|
|
38
|
+
/** Obtains a bound reference to the tooltip's content wrapper element. */
|
|
39
|
+
export let wrapperElement: HTMLDivElement = null;
|
|
40
|
+
|
|
41
|
+
let mounted = false;
|
|
42
|
+
let tooltipDurationTimeout: ReturnType<typeof setTimeout>;
|
|
43
|
+
let currentPosition = {
|
|
44
|
+
x: 0,
|
|
45
|
+
y: 0
|
|
46
|
+
};
|
|
47
|
+
let mousePosition = {
|
|
48
|
+
x: 0,
|
|
49
|
+
y: 0
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
onMount(() => (mounted = true));
|
|
53
|
+
|
|
54
|
+
function updateMousePosition({ clientX, clientY }) {
|
|
55
|
+
mousePosition.x = clientX;
|
|
56
|
+
mousePosition.y = clientY;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function updateTooltipPositionAuto(wrapperPosition) {
|
|
60
|
+
const { left, top } = wrapperPosition;
|
|
61
|
+
|
|
62
|
+
currentPosition.x = mousePosition.x - left;
|
|
63
|
+
currentPosition.y = mousePosition.y - top;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function mountTooltip() {
|
|
67
|
+
tooltipDurationTimeout = setTimeout(() => {
|
|
68
|
+
if (placement === "auto" && wrapperElement)
|
|
69
|
+
updateTooltipPositionAuto(wrapperElement.getBoundingClientRect());
|
|
70
|
+
|
|
71
|
+
visible = true;
|
|
72
|
+
}, delay);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function destroyTooltip() {
|
|
76
|
+
clearTimeout(tooltipDurationTimeout);
|
|
77
|
+
if (!persistent) visible = false;
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<svelte:window on:scroll={destroyTooltip} />
|
|
82
|
+
|
|
83
|
+
<div
|
|
84
|
+
class="tooltip-wrapper"
|
|
85
|
+
title={mounted ? undefined : text}
|
|
86
|
+
bind:this={wrapperElement}
|
|
87
|
+
on:mouseenter={mountTooltip}
|
|
88
|
+
on:mouseleave={destroyTooltip}
|
|
89
|
+
on:mousemove={updateMousePosition}
|
|
90
|
+
on:mousemove={() =>
|
|
91
|
+
placement === "auto" &&
|
|
92
|
+
followCursor &&
|
|
93
|
+
updateTooltipPositionAuto(wrapperElement.getBoundingClientRect())}
|
|
94
|
+
>
|
|
95
|
+
<slot />
|
|
96
|
+
|
|
97
|
+
{#if visible}
|
|
98
|
+
<div
|
|
99
|
+
bind:this={anchorElement}
|
|
100
|
+
in:fade|local={{ duration: getCSSDuration("--fds-control-fast-duration") }}
|
|
101
|
+
class="tooltip-anchor placement-{placement} alignment-{alignment}"
|
|
102
|
+
style="{placement === 'auto'
|
|
103
|
+
? `top: calc(${currentPosition.y}px - var(--fds-tooltip-offset));
|
|
104
|
+
left: ${currentPosition.x}px;`
|
|
105
|
+
: ''} --fds-tooltip-offset: {offset}px"
|
|
106
|
+
>
|
|
107
|
+
<TooltipSurface bind:element={tooltipElement} {...$$restProps}>
|
|
108
|
+
{text}
|
|
109
|
+
<slot name="tooltip" />
|
|
110
|
+
</TooltipSurface>
|
|
111
|
+
</div>
|
|
112
|
+
{/if}
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<style lang="scss">
|
|
116
|
+
@use "./TooltipWrapper";
|
|
117
|
+
</style>
|