@stubber/ui 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/README.md +17 -0
- package/dist/Typography.svelte +129 -0
- package/dist/Typography.svelte.d.ts +23 -0
- package/dist/assets/docs-icon.svg +11 -0
- package/dist/assets/stubber-icon.svg +3 -0
- package/dist/atoms/Button.svelte +70 -0
- package/dist/atoms/Button.svelte.d.ts +24 -0
- package/dist/atoms/IconButton.svelte +0 -0
- package/dist/atoms/IconButton.svelte.d.ts +23 -0
- package/dist/atoms/SpinnerMessage.svelte +7 -0
- package/dist/atoms/SpinnerMessage.svelte.d.ts +16 -0
- package/dist/atoms/TextOnlyButton.svelte +70 -0
- package/dist/atoms/TextOnlyButton.svelte.d.ts +24 -0
- package/dist/components/Accordion.svelte +47 -0
- package/dist/components/Accordion.svelte.d.ts +14 -0
- package/dist/components/AdvancedSwitch.svelte +20 -0
- package/dist/components/AdvancedSwitch.svelte.d.ts +14 -0
- package/dist/components/Alert.svelte +34 -0
- package/dist/components/Alert.svelte.d.ts +25 -0
- package/dist/components/Breadcrumbs.svelte +64 -0
- package/dist/components/Breadcrumbs.svelte.d.ts +33 -0
- package/dist/components/Chip.svelte +53 -0
- package/dist/components/Chip.svelte.d.ts +33 -0
- package/dist/components/HorizontalTabs.svelte +32 -0
- package/dist/components/HorizontalTabs.svelte.d.ts +25 -0
- package/dist/components/IconButton.svelte +165 -0
- package/dist/components/IconButton.svelte.d.ts +43 -0
- package/dist/components/Inputs/PasswordInput.svelte +76 -0
- package/dist/components/Inputs/PasswordInput.svelte.d.ts +21 -0
- package/dist/components/Inputs/SelectInput.css +143 -0
- package/dist/components/Inputs/SelectInput.svelte +18 -0
- package/dist/components/Inputs/SelectInput.svelte.d.ts +22 -0
- package/dist/components/Inputs/TextInput.svelte +76 -0
- package/dist/components/Inputs/TextInput.svelte.d.ts +21 -0
- package/dist/components/Modal.svelte +25 -0
- package/dist/components/Modal.svelte.d.ts +31 -0
- package/dist/components/ModalIcon.svelte +19 -0
- package/dist/components/ModalIcon.svelte.d.ts +17 -0
- package/dist/components/NavProfile.svelte +70 -0
- package/dist/components/NavProfile.svelte.d.ts +29 -0
- package/dist/components/OrgSwitcher.svelte +193 -0
- package/dist/components/OrgSwitcher.svelte.d.ts +33 -0
- package/dist/components/PasswordStrengthItem.svelte +10 -0
- package/dist/components/PasswordStrengthItem.svelte.d.ts +17 -0
- package/dist/components/PasswordStrengthValidator.svelte +57 -0
- package/dist/components/PasswordStrengthValidator.svelte.d.ts +17 -0
- package/dist/components/PrimaryButton.svelte +182 -0
- package/dist/components/PrimaryButton.svelte.d.ts +47 -0
- package/dist/components/ProfileMenu.svelte +58 -0
- package/dist/components/ProfileMenu.svelte.d.ts +35 -0
- package/dist/components/SideNav/SideNavExample.svelte +47 -0
- package/dist/components/SideNav/SideNavExample.svelte.d.ts +23 -0
- package/dist/components/SideNav/SideNavItem.svelte +54 -0
- package/dist/components/SideNav/SideNavItem.svelte.d.ts +35 -0
- package/dist/components/SideNav/SideNavTitle.svelte +7 -0
- package/dist/components/SideNav/SideNavTitle.svelte.d.ts +23 -0
- package/dist/components/Tabs.svelte +102 -0
- package/dist/components/Tabs.svelte.d.ts +14 -0
- package/dist/components/Toast.svelte +49 -0
- package/dist/components/Toast.svelte.d.ts +18 -0
- package/dist/components/Tooltip.svelte +80 -0
- package/dist/components/Tooltip.svelte.d.ts +29 -0
- package/dist/components/alert-dialog/alert-dialog-action.svelte +16 -0
- package/dist/components/alert-dialog/alert-dialog-action.svelte.d.ts +23 -0
- package/dist/components/alert-dialog/alert-dialog-cancel.svelte +16 -0
- package/dist/components/alert-dialog/alert-dialog-cancel.svelte.d.ts +23 -0
- package/dist/components/alert-dialog/alert-dialog-content.svelte +23 -0
- package/dist/components/alert-dialog/alert-dialog-content.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/alert-dialog-description.svelte +12 -0
- package/dist/components/alert-dialog/alert-dialog-description.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/alert-dialog-footer.svelte +11 -0
- package/dist/components/alert-dialog/alert-dialog-footer.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/alert-dialog-header.svelte +8 -0
- package/dist/components/alert-dialog/alert-dialog-header.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/alert-dialog-overlay.svelte +17 -0
- package/dist/components/alert-dialog/alert-dialog-overlay.svelte.d.ts +15 -0
- package/dist/components/alert-dialog/alert-dialog-portal.svelte +6 -0
- package/dist/components/alert-dialog/alert-dialog-portal.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/alert-dialog-title.svelte +10 -0
- package/dist/components/alert-dialog/alert-dialog-title.svelte.d.ts +17 -0
- package/dist/components/alert-dialog/index.d.ts +13 -0
- package/dist/components/alert-dialog/index.js +15 -0
- package/dist/components/badge/badge.svelte +16 -0
- package/dist/components/badge/badge.svelte.d.ts +22 -0
- package/dist/components/badge/index.d.ts +60 -0
- package/dist/components/badge/index.js +17 -0
- package/dist/components/breadcrumb/breadcrumb-ellipsis.svelte +16 -0
- package/dist/components/breadcrumb/breadcrumb-ellipsis.svelte.d.ts +17 -0
- package/dist/components/breadcrumb/breadcrumb-item.svelte +9 -0
- package/dist/components/breadcrumb/breadcrumb-item.svelte.d.ts +19 -0
- package/dist/components/breadcrumb/breadcrumb-link.svelte +22 -0
- package/dist/components/breadcrumb/breadcrumb-link.svelte.d.ts +22 -0
- package/dist/components/breadcrumb/breadcrumb-list.svelte +16 -0
- package/dist/components/breadcrumb/breadcrumb-list.svelte.d.ts +19 -0
- package/dist/components/breadcrumb/breadcrumb-page.svelte +16 -0
- package/dist/components/breadcrumb/breadcrumb-page.svelte.d.ts +21 -0
- package/dist/components/breadcrumb/breadcrumb-separator.svelte +17 -0
- package/dist/components/breadcrumb/breadcrumb-separator.svelte.d.ts +19 -0
- package/dist/components/breadcrumb/breadcrumb.svelte +8 -0
- package/dist/components/breadcrumb/breadcrumb.svelte.d.ts +19 -0
- package/dist/components/breadcrumb/index.d.ts +8 -0
- package/dist/components/breadcrumb/index.js +10 -0
- package/dist/components/button/button.svelte +20 -0
- package/dist/components/button/button.svelte.d.ts +16 -0
- package/dist/components/button/index.d.ts +110 -0
- package/dist/components/button/index.js +28 -0
- package/dist/components/card/card-content.svelte +8 -0
- package/dist/components/card/card-content.svelte.d.ts +17 -0
- package/dist/components/card/card-description.svelte +8 -0
- package/dist/components/card/card-description.svelte.d.ts +17 -0
- package/dist/components/card/card-footer.svelte +8 -0
- package/dist/components/card/card-footer.svelte.d.ts +17 -0
- package/dist/components/card/card-header.svelte +8 -0
- package/dist/components/card/card-header.svelte.d.ts +17 -0
- package/dist/components/card/card-title.svelte +13 -0
- package/dist/components/card/card-title.svelte.d.ts +20 -0
- package/dist/components/card/card.svelte +11 -0
- package/dist/components/card/card.svelte.d.ts +17 -0
- package/dist/components/card/index.d.ts +8 -0
- package/dist/components/card/index.js +9 -0
- package/dist/components/checkbox/checkbox.svelte +28 -0
- package/dist/components/checkbox/checkbox.svelte.d.ts +13 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.js +4 -0
- package/dist/components/dialog/dialog-content.svelte +31 -0
- package/dist/components/dialog/dialog-content.svelte.d.ts +17 -0
- package/dist/components/dialog/dialog-description.svelte +12 -0
- package/dist/components/dialog/dialog-description.svelte.d.ts +17 -0
- package/dist/components/dialog/dialog-footer.svelte +11 -0
- package/dist/components/dialog/dialog-footer.svelte.d.ts +17 -0
- package/dist/components/dialog/dialog-header.svelte +8 -0
- package/dist/components/dialog/dialog-header.svelte.d.ts +17 -0
- package/dist/components/dialog/dialog-overlay.svelte +17 -0
- package/dist/components/dialog/dialog-overlay.svelte.d.ts +15 -0
- package/dist/components/dialog/dialog-portal.svelte +6 -0
- package/dist/components/dialog/dialog-portal.svelte.d.ts +17 -0
- package/dist/components/dialog/dialog-title.svelte +12 -0
- package/dist/components/dialog/dialog-title.svelte.d.ts +17 -0
- package/dist/components/dialog/index.d.ts +12 -0
- package/dist/components/dialog/index.js +14 -0
- package/dist/components/fields/Checkbox.svelte +24 -0
- package/dist/components/fields/Checkbox.svelte.d.ts +27 -0
- package/dist/components/fields/Radio.svelte +30 -0
- package/dist/components/fields/Radio.svelte.d.ts +27 -0
- package/dist/components/fields/StandardInput.svelte +47 -0
- package/dist/components/fields/StandardInput.svelte.d.ts +31 -0
- package/dist/components/input/index.d.ts +23 -0
- package/dist/components/input/index.js +4 -0
- package/dist/components/input/input.svelte +33 -0
- package/dist/components/input/input.svelte.d.ts +14 -0
- package/dist/components/label/index.d.ts +2 -0
- package/dist/components/label/index.js +4 -0
- package/dist/components/label/label.svelte +16 -0
- package/dist/components/label/label.svelte.d.ts +15 -0
- package/dist/components/radio-group/index.d.ts +5 -0
- package/dist/components/radio-group/index.js +7 -0
- package/dist/components/radio-group/radio-group-item.svelte +22 -0
- package/dist/components/radio-group/radio-group-item.svelte.d.ts +13 -0
- package/dist/components/radio-group/radio-group.svelte +10 -0
- package/dist/components/radio-group/radio-group.svelte.d.ts +17 -0
- package/dist/components/scroll-area/index.d.ts +3 -0
- package/dist/components/scroll-area/index.js +5 -0
- package/dist/components/scroll-area/scroll-area-scrollbar.svelte +21 -0
- package/dist/components/scroll-area/scroll-area-scrollbar.svelte.d.ts +23 -0
- package/dist/components/scroll-area/scroll-area.svelte +24 -0
- package/dist/components/scroll-area/scroll-area.svelte.d.ts +27 -0
- package/dist/components/select/index.d.ts +11 -0
- package/dist/components/select/index.js +13 -0
- package/dist/components/select/select-content.svelte +33 -0
- package/dist/components/select/select-content.svelte.d.ts +15 -0
- package/dist/components/select/select-item.svelte +34 -0
- package/dist/components/select/select-item.svelte.d.ts +15 -0
- package/dist/components/select/select-label.svelte +12 -0
- package/dist/components/select/select-label.svelte.d.ts +17 -0
- package/dist/components/select/select-separator.svelte +7 -0
- package/dist/components/select/select-separator.svelte.d.ts +15 -0
- package/dist/components/select/select-trigger.svelte +21 -0
- package/dist/components/select/select-trigger.svelte.d.ts +31 -0
- package/dist/components/separator/index.d.ts +2 -0
- package/dist/components/separator/index.js +4 -0
- package/dist/components/separator/separator.svelte +18 -0
- package/dist/components/separator/separator.svelte.d.ts +15 -0
- package/dist/components/sheet/index.d.ts +114 -0
- package/dist/components/sheet/index.js +79 -0
- package/dist/components/sheet/sheet-content.svelte +38 -0
- package/dist/components/sheet/sheet-content.svelte.d.ts +29 -0
- package/dist/components/sheet/sheet-description.svelte +9 -0
- package/dist/components/sheet/sheet-description.svelte.d.ts +17 -0
- package/dist/components/sheet/sheet-footer.svelte +11 -0
- package/dist/components/sheet/sheet-footer.svelte.d.ts +17 -0
- package/dist/components/sheet/sheet-header.svelte +8 -0
- package/dist/components/sheet/sheet-header.svelte.d.ts +17 -0
- package/dist/components/sheet/sheet-overlay.svelte +23 -0
- package/dist/components/sheet/sheet-overlay.svelte.d.ts +15 -0
- package/dist/components/sheet/sheet-portal.svelte +9 -0
- package/dist/components/sheet/sheet-portal.svelte.d.ts +17 -0
- package/dist/components/sheet/sheet-title.svelte +12 -0
- package/dist/components/sheet/sheet-title.svelte.d.ts +17 -0
- package/dist/components/sonner/index.d.ts +1 -0
- package/dist/components/sonner/index.js +1 -0
- package/dist/components/sonner/sonner.svelte +16 -0
- package/dist/components/sonner/sonner.svelte.d.ts +15 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +4 -0
- package/dist/components/switch/switch.svelte +30 -0
- package/dist/components/switch/switch.svelte.d.ts +13 -0
- package/dist/components/tabs/index.d.ts +6 -0
- package/dist/components/tabs/index.js +8 -0
- package/dist/components/tabs/tabs-content.svelte +17 -0
- package/dist/components/tabs/tabs-content.svelte.d.ts +17 -0
- package/dist/components/tabs/tabs-list.svelte +15 -0
- package/dist/components/tabs/tabs-list.svelte.d.ts +17 -0
- package/dist/components/tabs/tabs-trigger.svelte +18 -0
- package/dist/components/tabs/tabs-trigger.svelte.d.ts +15 -0
- package/dist/components/textarea/index.d.ts +19 -0
- package/dist/components/textarea/index.js +4 -0
- package/dist/components/textarea/textarea.svelte +28 -0
- package/dist/components/textarea/textarea.svelte.d.ts +14 -0
- package/dist/components/tooltip/index.d.ts +5 -0
- package/dist/components/tooltip/index.js +7 -0
- package/dist/components/tooltip/tooltip-content.svelte +24 -0
- package/dist/components/tooltip/tooltip-content.svelte.d.ts +17 -0
- package/dist/decorators/DecoratorHorizontalTabs.svelte +3 -0
- package/dist/decorators/DecoratorHorizontalTabs.svelte.d.ts +27 -0
- package/dist/decorators/DecoratorTransparentButton.svelte +3 -0
- package/dist/decorators/DecoratorTransparentButton.svelte.d.ts +27 -0
- package/dist/decorators/FixedWidthDecorator.svelte +3 -0
- package/dist/decorators/FixedWidthDecorator.svelte.d.ts +27 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +29 -0
- package/dist/utils/actions.d.ts +4 -0
- package/dist/utils/actions.js +20 -0
- package/dist/utils/shadcn-utils.d.ts +13 -0
- package/dist/utils/shadcn-utils.js +119 -0
- package/package.json +68 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script>import { createEventDispatcher } from "svelte";
|
|
2
|
+
const dispatch = createEventDispatcher();
|
|
3
|
+
export let name;
|
|
4
|
+
export let label;
|
|
5
|
+
export let value = "";
|
|
6
|
+
export let isError = false;
|
|
7
|
+
let inputRef;
|
|
8
|
+
let containerRef;
|
|
9
|
+
let isActive = false;
|
|
10
|
+
let isFocused = false;
|
|
11
|
+
let hasValue = false;
|
|
12
|
+
$:
|
|
13
|
+
isActive = ((isFocused2, hasValue2) => {
|
|
14
|
+
if (isFocused2 || hasValue2) {
|
|
15
|
+
return true;
|
|
16
|
+
} else {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
})(isFocused, hasValue);
|
|
20
|
+
$:
|
|
21
|
+
hasValue = ((value2) => {
|
|
22
|
+
if (value2) {
|
|
23
|
+
return true;
|
|
24
|
+
} else {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
})(value);
|
|
28
|
+
function handleClick() {
|
|
29
|
+
inputRef.focus();
|
|
30
|
+
isFocused = true;
|
|
31
|
+
}
|
|
32
|
+
function handleClickOutside({ target }) {
|
|
33
|
+
assertIsNode(target);
|
|
34
|
+
if (isFocused && !hasValue && !containerRef.contains(target)) {
|
|
35
|
+
isFocused = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function assertIsNode(e) {
|
|
39
|
+
if (!e || !("nodeType" in e)) {
|
|
40
|
+
throw new Error("Expected node EventTarget");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<svelte:window on:click={handleClickOutside} />
|
|
46
|
+
|
|
47
|
+
<div
|
|
48
|
+
on:click={handleClick}
|
|
49
|
+
on:keydown={() => {}}
|
|
50
|
+
bind:this={containerRef}
|
|
51
|
+
class="relative group w-full bg-white py-3 px-4 rounded-md cursor-text border {isError
|
|
52
|
+
? 'border-danger-500'
|
|
53
|
+
: 'border-surface-400 hover:border-surface-600 [&:is(:focus-within)]:border-primary-400'}"
|
|
54
|
+
>
|
|
55
|
+
<input
|
|
56
|
+
{name}
|
|
57
|
+
type="text"
|
|
58
|
+
bind:this={inputRef}
|
|
59
|
+
bind:value
|
|
60
|
+
on:focus={() => dispatch("focus")}
|
|
61
|
+
class="w-full text-surface-900 outline-none"
|
|
62
|
+
placeholder={label}
|
|
63
|
+
/>
|
|
64
|
+
{#if isActive}
|
|
65
|
+
<!-- TODO: group hover text-surface-600 -->
|
|
66
|
+
<fieldset aria-hidden="true">
|
|
67
|
+
<legend
|
|
68
|
+
class="absolute -top-3 left-2 px-1.5 bg-white {isError
|
|
69
|
+
? 'text-danger-500'
|
|
70
|
+
: 'text-surface-500 group-focus-within:text-primary-400'}"
|
|
71
|
+
>
|
|
72
|
+
<span class="text-label-sm">{label}</span>
|
|
73
|
+
</legend>
|
|
74
|
+
</fieldset>
|
|
75
|
+
{/if}
|
|
76
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
name: string;
|
|
5
|
+
label: string;
|
|
6
|
+
value?: string | undefined;
|
|
7
|
+
isError?: boolean | undefined;
|
|
8
|
+
};
|
|
9
|
+
events: {
|
|
10
|
+
focus: CustomEvent<any>;
|
|
11
|
+
} & {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
};
|
|
16
|
+
export type TextInputProps = typeof __propDef.props;
|
|
17
|
+
export type TextInputEvents = typeof __propDef.events;
|
|
18
|
+
export type TextInputSlots = typeof __propDef.slots;
|
|
19
|
+
export default class TextInput extends SvelteComponent<TextInputProps, TextInputEvents, TextInputSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
export let heading;
|
|
4
|
+
|
|
5
|
+
const dispatch = createEventDispatcher();
|
|
6
|
+
|
|
7
|
+
function handle_close_modal() {
|
|
8
|
+
dispatch("close_modal");
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<div class="max-h-screen flex flex-col min-w-[320px] bg-white border border-surface-100 rounded-lg">
|
|
13
|
+
<div class="h-fit pl-5 pr-2.5 py-2.5 flex grow items-center border-b border-surface-100">
|
|
14
|
+
<h1 class="text-heading-6 text-surface-900">{heading}</h1>
|
|
15
|
+
<button
|
|
16
|
+
on:click={handle_close_modal}
|
|
17
|
+
class="group ml-auto h-10 aspect-square flex items-center justify-center rounded-lg"
|
|
18
|
+
>
|
|
19
|
+
<i class="far fa-lg fa-xmark text-surface-900 group-hover:text-danger-500" />
|
|
20
|
+
</button>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="p-[15px] overflow-y-auto">
|
|
23
|
+
<slot />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} ModalProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} ModalEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} ModalSlots */
|
|
4
|
+
export default class Modal extends SvelteComponent<{
|
|
5
|
+
heading: any;
|
|
6
|
+
}, {
|
|
7
|
+
close_modal: CustomEvent<any>;
|
|
8
|
+
} & {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
}, {
|
|
11
|
+
default: {};
|
|
12
|
+
}> {
|
|
13
|
+
}
|
|
14
|
+
export type ModalProps = typeof __propDef.props;
|
|
15
|
+
export type ModalEvents = typeof __propDef.events;
|
|
16
|
+
export type ModalSlots = typeof __propDef.slots;
|
|
17
|
+
import { SvelteComponent } from "svelte";
|
|
18
|
+
declare const __propDef: {
|
|
19
|
+
props: {
|
|
20
|
+
heading: any;
|
|
21
|
+
};
|
|
22
|
+
events: {
|
|
23
|
+
close_modal: CustomEvent<any>;
|
|
24
|
+
} & {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
|
+
};
|
|
27
|
+
slots: {
|
|
28
|
+
default: {};
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script>import { Avatar } from "bits-ui";
|
|
2
|
+
import { faCog } from "@fortawesome/free-solid-svg-icons";
|
|
3
|
+
import { FontAwesomeIcon } from "@fortawesome/svelte-fontawesome";
|
|
4
|
+
export let loadingStatus = void 0;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<Avatar.Root
|
|
8
|
+
bind:loadingStatus
|
|
9
|
+
class="h-12 w-12 rounded-md border-[0.4px] border-slate-300 {loadingStatus === 'loaded'
|
|
10
|
+
? 'border-foreground'
|
|
11
|
+
: 'border-transparent'} bg-gradient-to-b from-[#FCFCFF] to-[#DFEAF6] text-[17px] font-medium uppercase text-muted-foreground"
|
|
12
|
+
>
|
|
13
|
+
<div
|
|
14
|
+
class="flex h-full w-full items-center justify-center p-1.5"
|
|
15
|
+
>
|
|
16
|
+
<FontAwesomeIcon icon={faCog} class="text-blue-500 text-2xl" />
|
|
17
|
+
</div>
|
|
18
|
+
</Avatar.Root>
|
|
19
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { Avatar } from "bits-ui";
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
loadingStatus?: Avatar.Props["loadingStatus"];
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type ModalIconProps = typeof __propDef.props;
|
|
13
|
+
export type ModalIconEvents = typeof __propDef.events;
|
|
14
|
+
export type ModalIconSlots = typeof __propDef.slots;
|
|
15
|
+
export default class ModalIcon extends SvelteComponent<ModalIconProps, ModalIconEvents, ModalIconSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { clickOutside } from "../utils/actions.js";
|
|
4
|
+
|
|
5
|
+
export let avatarLink = "";
|
|
6
|
+
export let manageLink = "";
|
|
7
|
+
|
|
8
|
+
const dispatch = createEventDispatcher();
|
|
9
|
+
|
|
10
|
+
//states
|
|
11
|
+
let isMenu = false;
|
|
12
|
+
|
|
13
|
+
const toggleMenu = () => {
|
|
14
|
+
isMenu = !isMenu;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function closeMenu() {
|
|
18
|
+
if (isMenu) {
|
|
19
|
+
isMenu = false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<button
|
|
25
|
+
use:clickOutside={closeMenu}
|
|
26
|
+
on:click={toggleMenu}
|
|
27
|
+
id="user-profile-btn"
|
|
28
|
+
class="h-full aspect-square flex items-center justify-center hover:bg-surface-100 focus:bg-surface-50"
|
|
29
|
+
>
|
|
30
|
+
<div
|
|
31
|
+
class="rounded-full {isMenu ? 'outline outline-2 outline-offset-1 outline-primary-100' : ''}"
|
|
32
|
+
>
|
|
33
|
+
{#if avatarLink}
|
|
34
|
+
<img class="rounded-full" src={avatarLink} width="28px" alt="" />
|
|
35
|
+
{:else}
|
|
36
|
+
<div class="h-9 aspect-square bg-surface-100 rounded-full text-center" />
|
|
37
|
+
{/if}
|
|
38
|
+
</div>
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<!-- Menu -->
|
|
42
|
+
{#if isMenu}
|
|
43
|
+
<div
|
|
44
|
+
class="absolute z-20 divide-y top-[49px] right-0 w-60 border border-surface-200 bg-surface-0 shadow-md rounded-b-md"
|
|
45
|
+
on:click={(e) => {
|
|
46
|
+
e.stopImmediatePropagation();
|
|
47
|
+
}}
|
|
48
|
+
on:keypress={(e) => {
|
|
49
|
+
e.stopImmediatePropagation();
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<div>
|
|
53
|
+
<a
|
|
54
|
+
href={manageLink}
|
|
55
|
+
class="w-full px-4 py-3 space-x-2 flex flex-row items-center text-left text-surface-700 hover:text-surface-900 focus:text-surface-700 hover:bg-surface-100 focus:outline-none focus:bg-surface-100"
|
|
56
|
+
>
|
|
57
|
+
<i class="fa-regular fa-lg fa-fw fa-cog" />
|
|
58
|
+
<p class="text-button">Settings</p>
|
|
59
|
+
</a>
|
|
60
|
+
</div>
|
|
61
|
+
<button
|
|
62
|
+
on:click={dispatch("logout")}
|
|
63
|
+
id="logout-btn"
|
|
64
|
+
class="w-full px-4 py-3 space-x-2 flex flex-row items-center text-left text-surface-700 hover:text-surface-900 focus:text-surface-700 hover:bg-surface-100 focus:outline-none focus:bg-surface-100"
|
|
65
|
+
>
|
|
66
|
+
<i class="fa-regular fa-lg fa-fw fa-right-from-bracket" />
|
|
67
|
+
<p class="text-button">Logout</p>
|
|
68
|
+
</button>
|
|
69
|
+
</div>
|
|
70
|
+
{/if}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} NavProfileProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} NavProfileEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} NavProfileSlots */
|
|
4
|
+
export default class NavProfile extends SvelteComponent<{
|
|
5
|
+
manageLink?: string | undefined;
|
|
6
|
+
avatarLink?: string | undefined;
|
|
7
|
+
}, {
|
|
8
|
+
logout: CustomEvent<any>;
|
|
9
|
+
} & {
|
|
10
|
+
[evt: string]: CustomEvent<any>;
|
|
11
|
+
}, {}> {
|
|
12
|
+
}
|
|
13
|
+
export type NavProfileProps = typeof __propDef.props;
|
|
14
|
+
export type NavProfileEvents = typeof __propDef.events;
|
|
15
|
+
export type NavProfileSlots = typeof __propDef.slots;
|
|
16
|
+
import { SvelteComponent } from "svelte";
|
|
17
|
+
declare const __propDef: {
|
|
18
|
+
props: {
|
|
19
|
+
manageLink?: string | undefined;
|
|
20
|
+
avatarLink?: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
events: {
|
|
23
|
+
logout: CustomEvent<any>;
|
|
24
|
+
} & {
|
|
25
|
+
[evt: string]: CustomEvent<any>;
|
|
26
|
+
};
|
|
27
|
+
slots: {};
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { slide } from "svelte/transition";
|
|
4
|
+
import { quintOut } from "svelte/easing";
|
|
5
|
+
import { clickOutside } from "../utils/actions.js";
|
|
6
|
+
|
|
7
|
+
export let orgs = [];
|
|
8
|
+
export let selectedorguuid = undefined;
|
|
9
|
+
export let createOrgLink = "";
|
|
10
|
+
export let loading = false;
|
|
11
|
+
|
|
12
|
+
$: selectedOrg = orgs.find((org) => org.orguuid === selectedorguuid);
|
|
13
|
+
|
|
14
|
+
const dispatch = createEventDispatcher();
|
|
15
|
+
const alertColorMap = {
|
|
16
|
+
error: "danger-500",
|
|
17
|
+
warning: "warning-500",
|
|
18
|
+
success: "success-500",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let filterText = "";
|
|
22
|
+
|
|
23
|
+
//state
|
|
24
|
+
let state = {
|
|
25
|
+
isMenu: false,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function toggleMenu() {
|
|
29
|
+
if (orgs.length > 0) {
|
|
30
|
+
state.isMenu = !state.isMenu;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function selectOrg(orguuid) {
|
|
35
|
+
dispatch("selectOrg", orguuid);
|
|
36
|
+
selectedorguuid = orguuid;
|
|
37
|
+
state.isMenu = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function closeMenu() {
|
|
41
|
+
if (state.isMenu) {
|
|
42
|
+
filterText = "";
|
|
43
|
+
state.isMenu = false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div class="relative">
|
|
49
|
+
<div use:clickOutside={closeMenu} class="{state.isMenu ? 'absolute top-0' : ''} bg-white w-fit">
|
|
50
|
+
{#if (orgs.length >= 10 && !state.isMenu) || orgs.length <= 10}
|
|
51
|
+
<button
|
|
52
|
+
on:click|stopPropagation={toggleMenu}
|
|
53
|
+
class="flex items-center {state.isMenu
|
|
54
|
+
? 'w-[230px] sm:w-[280px] border-x border-t rounded-x-lg rounded-t-lg hover:bg-primary-50'
|
|
55
|
+
: 'sm:w-[280px] border rounded-lg'} border-surface-100"
|
|
56
|
+
>
|
|
57
|
+
<div class="h-10 flex items-center justify-center aspect-square">
|
|
58
|
+
{#if selectedOrg?.filesrc && !loading}
|
|
59
|
+
<img
|
|
60
|
+
class="h-[25px] aspect-square object-cover rounded-full"
|
|
61
|
+
src={selectedOrg.filesrc}
|
|
62
|
+
alt={selectedOrg.label}
|
|
63
|
+
/>
|
|
64
|
+
{:else}
|
|
65
|
+
<div class="h-[25px] aspect-square rounded-full bg-surface-100" />
|
|
66
|
+
{/if}
|
|
67
|
+
</div>
|
|
68
|
+
{#if loading}
|
|
69
|
+
<span class="hidden sm:block h-[25px] w-40 bg-surface-100 rounded-md" />
|
|
70
|
+
{:else}
|
|
71
|
+
<div class="{state.isMenu ? '' : 'hidden'} sm:block w-full text-left truncate">
|
|
72
|
+
<p class="text-label text-surface-900 truncate">
|
|
73
|
+
{selectedOrg?.label ?? "No orgs"}
|
|
74
|
+
</p>
|
|
75
|
+
{#if selectedOrg?.alert}
|
|
76
|
+
<div class="flex items-center space-x-1">
|
|
77
|
+
<span
|
|
78
|
+
class="h-[6px] aspect-square bg-{alertColorMap[
|
|
79
|
+
selectedOrg.alert?.type
|
|
80
|
+
]} rounded-full"
|
|
81
|
+
/>
|
|
82
|
+
<p class="text-small italic text-{alertColorMap[selectedOrg.alert?.type]}">
|
|
83
|
+
{selectedOrg.alert?.message}
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
{/if}
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
89
|
+
{#if !state.isMenu && selectedOrg?.alert}
|
|
90
|
+
<span
|
|
91
|
+
class="block sm:hidden h-[6px] aspect-square bg-{alertColorMap[
|
|
92
|
+
selectedOrg.alert?.type
|
|
93
|
+
]} rounded-full"
|
|
94
|
+
/>
|
|
95
|
+
{/if}
|
|
96
|
+
<div
|
|
97
|
+
class="{loading
|
|
98
|
+
? 'block sm:hidden'
|
|
99
|
+
: ''} ml-auto h-10 aspect-square flex items-center justify-center"
|
|
100
|
+
>
|
|
101
|
+
<i class="text-surface-900 fa far fa-chevron-down {state.isMenu ? 'rotate down' : ''}" />
|
|
102
|
+
</div>
|
|
103
|
+
</button>
|
|
104
|
+
{:else}
|
|
105
|
+
<div
|
|
106
|
+
class="h-10 w-[230px] sm:w-[280px] flex items-center border-x border-t rounded-x-lg rounded-t-lg"
|
|
107
|
+
>
|
|
108
|
+
<div class="h-full aspect-square flex items-center justify-center">
|
|
109
|
+
<i class="text-surface-900 fa far fa-magnifying-glass" />
|
|
110
|
+
</div>
|
|
111
|
+
<input
|
|
112
|
+
type="text"
|
|
113
|
+
autofocus
|
|
114
|
+
class="w-full pr-3 text-surface-900 text-label focus:outline-none"
|
|
115
|
+
placeholder="Search orgs"
|
|
116
|
+
bind:value={filterText}
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
119
|
+
{/if}
|
|
120
|
+
|
|
121
|
+
{#if state.isMenu}
|
|
122
|
+
<div
|
|
123
|
+
in:slide={{ duration: 300, easing: quintOut, axis: "y" }}
|
|
124
|
+
class="w-[230px] sm:w-[280px] border-x border-b rounded-x-lg rounded-b-lg"
|
|
125
|
+
>
|
|
126
|
+
<div class="max-h-80 overflow-y-auto">
|
|
127
|
+
{#each orgs.filter((o) => o.orguuid !== selectedOrg.orguuid || orgs.length >= 10) as org}
|
|
128
|
+
{#if org.label.toLowerCase().includes(filterText.toLowerCase())}
|
|
129
|
+
<button
|
|
130
|
+
on:click={() => selectOrg(org.orguuid)}
|
|
131
|
+
class="w-full flex items-center hover:bg-primary-50 focus:bg-primary-50 focus:outline-none"
|
|
132
|
+
>
|
|
133
|
+
<div class="h-10 flex items-center justify-center aspect-square">
|
|
134
|
+
{#if org.filesrc}
|
|
135
|
+
<img
|
|
136
|
+
class="h-[25px] aspect-square object-cover rounded-full"
|
|
137
|
+
src={org.filesrc}
|
|
138
|
+
alt={org.label}
|
|
139
|
+
/>
|
|
140
|
+
{:else}
|
|
141
|
+
<div class="h-[25px] aspect-square rounded-full bg-surface-100" />
|
|
142
|
+
{/if}
|
|
143
|
+
</div>
|
|
144
|
+
<div class="{state.isMenu ? '' : 'hidden'} sm:block w-full text-left truncate">
|
|
145
|
+
<p class="text-label text-surface-900 truncate">
|
|
146
|
+
{org.label}
|
|
147
|
+
</p>
|
|
148
|
+
{#if org.alert}
|
|
149
|
+
<div class="flex items-center space-x-1">
|
|
150
|
+
<span
|
|
151
|
+
class="h-[6px] aspect-square bg-{alertColorMap[
|
|
152
|
+
org.alert.type
|
|
153
|
+
]} rounded-full"
|
|
154
|
+
/>
|
|
155
|
+
<p class="text-small italic text-{alertColorMap[org.alert.type]}">
|
|
156
|
+
{org.alert?.message}
|
|
157
|
+
</p>
|
|
158
|
+
</div>
|
|
159
|
+
{/if}
|
|
160
|
+
</div>
|
|
161
|
+
{#if org.orguuid === selectedOrg.orguuid}
|
|
162
|
+
<div class="ml-auto h-10 aspect-square flex items-center justify-center">
|
|
163
|
+
<i class="text-success-500 fa far fa-check" />
|
|
164
|
+
</div>
|
|
165
|
+
{/if}
|
|
166
|
+
</button>
|
|
167
|
+
{/if}
|
|
168
|
+
{/each}
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
{#if createOrgLink}
|
|
172
|
+
<a
|
|
173
|
+
href={createOrgLink}
|
|
174
|
+
class="h-10 w-full pl-3.5 pr-3 flex items-center bg-white text-primary-500 rounded-b-lg hover:bg-primary-50 focus:bg-primary-50 focus:outline-none hover:text-primary-400"
|
|
175
|
+
>
|
|
176
|
+
<i class="far fa fa-plus mr-2" />
|
|
177
|
+
<span class="text-placeholder">Create org</span>
|
|
178
|
+
</a>
|
|
179
|
+
{/if}
|
|
180
|
+
</div>
|
|
181
|
+
{/if}
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<style>
|
|
186
|
+
.rotate {
|
|
187
|
+
transition: all 150ms linear;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.rotate.down {
|
|
191
|
+
transform: rotate(180deg);
|
|
192
|
+
}
|
|
193
|
+
</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** @typedef {typeof __propDef.props} OrgSwitcherProps */
|
|
2
|
+
/** @typedef {typeof __propDef.events} OrgSwitcherEvents */
|
|
3
|
+
/** @typedef {typeof __propDef.slots} OrgSwitcherSlots */
|
|
4
|
+
export default class OrgSwitcher extends SvelteComponent<{
|
|
5
|
+
orgs?: any[] | undefined;
|
|
6
|
+
selectedorguuid?: any;
|
|
7
|
+
createOrgLink?: string | undefined;
|
|
8
|
+
loading?: boolean | undefined;
|
|
9
|
+
}, {
|
|
10
|
+
selectOrg: CustomEvent<any>;
|
|
11
|
+
} & {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}> {
|
|
14
|
+
}
|
|
15
|
+
export type OrgSwitcherProps = typeof __propDef.props;
|
|
16
|
+
export type OrgSwitcherEvents = typeof __propDef.events;
|
|
17
|
+
export type OrgSwitcherSlots = typeof __propDef.slots;
|
|
18
|
+
import { SvelteComponent } from "svelte";
|
|
19
|
+
declare const __propDef: {
|
|
20
|
+
props: {
|
|
21
|
+
orgs?: any[] | undefined;
|
|
22
|
+
selectedorguuid?: any;
|
|
23
|
+
createOrgLink?: string | undefined;
|
|
24
|
+
loading?: boolean | undefined;
|
|
25
|
+
};
|
|
26
|
+
events: {
|
|
27
|
+
selectOrg: CustomEvent<any>;
|
|
28
|
+
} & {
|
|
29
|
+
[evt: string]: CustomEvent<any>;
|
|
30
|
+
};
|
|
31
|
+
slots: {};
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script>export let value = "";
|
|
2
|
+
export let isPassed = false;
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<span
|
|
6
|
+
class="flex flex-row items-center space-x-2 {isPassed ? 'text-success-500' : 'text-danger-500'}"
|
|
7
|
+
>
|
|
8
|
+
<i class="fa fa-md {isPassed ? 'fa-circle-check' : 'fa-circle-x'}" />
|
|
9
|
+
<p class="text-label-sm">{value}</p>
|
|
10
|
+
</span>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
value?: string | undefined;
|
|
5
|
+
isPassed?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type PasswordStrengthItemProps = typeof __propDef.props;
|
|
13
|
+
export type PasswordStrengthItemEvents = typeof __propDef.events;
|
|
14
|
+
export type PasswordStrengthItemSlots = typeof __propDef.slots;
|
|
15
|
+
export default class PasswordStrengthItem extends SvelteComponent<PasswordStrengthItemProps, PasswordStrengthItemEvents, PasswordStrengthItemSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script>import PasswordStrengthItem from "./PasswordStrengthItem.svelte";
|
|
2
|
+
export let value = "";
|
|
3
|
+
$:
|
|
4
|
+
validatePassword(value);
|
|
5
|
+
export let isStrong = true;
|
|
6
|
+
let isEightCharacters = false;
|
|
7
|
+
let hasNumber = false;
|
|
8
|
+
let hasSymbol = false;
|
|
9
|
+
let hasUpper = false;
|
|
10
|
+
let hasLower = false;
|
|
11
|
+
function validatePassword(password) {
|
|
12
|
+
if (password.length >= 8) {
|
|
13
|
+
isEightCharacters = true;
|
|
14
|
+
} else {
|
|
15
|
+
isEightCharacters = false;
|
|
16
|
+
}
|
|
17
|
+
if (/[a-z]/.test(password)) {
|
|
18
|
+
hasLower = true;
|
|
19
|
+
} else {
|
|
20
|
+
hasLower = false;
|
|
21
|
+
}
|
|
22
|
+
if (/[A-Z]/.test(password)) {
|
|
23
|
+
hasUpper = true;
|
|
24
|
+
} else {
|
|
25
|
+
hasUpper = false;
|
|
26
|
+
}
|
|
27
|
+
if (/\d/.test(password)) {
|
|
28
|
+
hasNumber = true;
|
|
29
|
+
} else {
|
|
30
|
+
hasNumber = false;
|
|
31
|
+
}
|
|
32
|
+
if (/[!@#$%^&*]/.test(password)) {
|
|
33
|
+
hasSymbol = true;
|
|
34
|
+
} else {
|
|
35
|
+
hasSymbol = false;
|
|
36
|
+
}
|
|
37
|
+
if (isEightCharacters && hasLower && hasUpper && hasNumber && hasSymbol) {
|
|
38
|
+
isStrong = true;
|
|
39
|
+
} else {
|
|
40
|
+
isStrong = false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<div class="space-y-0.5 text-fluid-sm">
|
|
46
|
+
<PasswordStrengthItem
|
|
47
|
+
isPassed={isStrong}
|
|
48
|
+
value="Password strength: {isStrong ? 'strong' : 'weak'}"
|
|
49
|
+
/>
|
|
50
|
+
{#if !isStrong}
|
|
51
|
+
<PasswordStrengthItem isPassed={hasLower} value="At least one lower case character" />
|
|
52
|
+
<PasswordStrengthItem isPassed={hasUpper} value="At least one upper case character" />
|
|
53
|
+
<PasswordStrengthItem isPassed={hasNumber} value="Contains a number" />
|
|
54
|
+
<PasswordStrengthItem isPassed={hasSymbol} value="Contains a symbol" />
|
|
55
|
+
<PasswordStrengthItem isPassed={isEightCharacters} value="At least 8 characters" />
|
|
56
|
+
{/if}
|
|
57
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
value?: string | undefined;
|
|
5
|
+
isStrong?: boolean | undefined;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type PasswordStrengthValidatorProps = typeof __propDef.props;
|
|
13
|
+
export type PasswordStrengthValidatorEvents = typeof __propDef.events;
|
|
14
|
+
export type PasswordStrengthValidatorSlots = typeof __propDef.slots;
|
|
15
|
+
export default class PasswordStrengthValidator extends SvelteComponent<PasswordStrengthValidatorProps, PasswordStrengthValidatorEvents, PasswordStrengthValidatorSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|