@noxlovette/material 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/portal.d.ts +3 -0
- package/dist/actions/portal.js +8 -0
- package/dist/components/buttons/FAB.svelte +4 -3
- package/dist/components/buttons/FABMenu.svelte +14 -52
- package/dist/components/buttons/Toggle.svelte +0 -2
- package/dist/components/buttons/theme.js +3 -3
- package/dist/components/buttons/types.d.ts +2 -0
- package/dist/components/containers/menu-item/MenuItem.svelte +0 -1
- package/dist/components/containers/panes/SupportingPane.svelte +1 -0
- package/dist/components/containers/side-sheet/SideSheet.svelte +1 -1
- package/dist/components/date/DateField.svelte +2 -2
- package/dist/components/date/DateRangeField.svelte +2 -2
- package/dist/components/forms/textfield/Textfield.svelte +5 -1
- package/dist/components/time/TimepickerInput.svelte +1 -1
- package/package.json +1 -1
package/dist/actions/index.d.ts
CHANGED
package/dist/actions/index.js
CHANGED
|
@@ -35,6 +35,7 @@ Floating action buttons (FABs) help people take primary actions.
|
|
|
35
35
|
const { base, icon, label: labelClass } = $derived(fab({ size, config, expanded }));
|
|
36
36
|
|
|
37
37
|
let showMenu = $state(false);
|
|
38
|
+
let wrapperEl = $state<HTMLElement | null>(null);
|
|
38
39
|
|
|
39
40
|
const btnCls = $derived(
|
|
40
41
|
base({
|
|
@@ -58,7 +59,7 @@ Floating action buttons (FABs) help people take primary actions.
|
|
|
58
59
|
}
|
|
59
60
|
</script>
|
|
60
61
|
|
|
61
|
-
<div class="contents" use:clickOutside={() => (showMenu = false)}>
|
|
62
|
+
<div class="contents" bind:this={wrapperEl} use:clickOutside={() => (showMenu = false)}>
|
|
62
63
|
<Button.Root
|
|
63
64
|
{disabled}
|
|
64
65
|
{formaction}
|
|
@@ -76,8 +77,8 @@ Floating action buttons (FABs) help people take primary actions.
|
|
|
76
77
|
{/if}
|
|
77
78
|
</Button.Root>
|
|
78
79
|
|
|
79
|
-
{#if withMenu && showMenu}
|
|
80
|
-
<FABMenu>
|
|
80
|
+
{#if withMenu && showMenu && wrapperEl?.firstElementChild}
|
|
81
|
+
<FABMenu anchorEl={wrapperEl.firstElementChild as HTMLElement}>
|
|
81
82
|
{@render children?.()}
|
|
82
83
|
</FABMenu>
|
|
83
84
|
{/if}
|
|
@@ -5,69 +5,31 @@ Should be used with `FABMenuItem` as children.
|
|
|
5
5
|
-->
|
|
6
6
|
<script lang="ts">
|
|
7
7
|
import clsx from 'clsx';
|
|
8
|
+
import { flip } from '@floating-ui/dom';
|
|
8
9
|
import { fabMenu } from './theme.js';
|
|
9
10
|
import type { FABMenuProps } from './types.js';
|
|
10
11
|
import { enterExit } from '../../animation/enterExit.js';
|
|
11
|
-
import { easeEmphasizedDecel } from '../../animation/easing.js';
|
|
12
|
+
import { easeEmphasizedAccel, easeEmphasizedDecel } from '../../animation/easing.js';
|
|
13
|
+
import { floating, portal } from '../../actions/index.js';
|
|
12
14
|
|
|
13
|
-
let { children, class: className, ...restProps }: FABMenuProps = $props();
|
|
15
|
+
let { children, class: className, anchorEl, ...restProps }: FABMenuProps = $props();
|
|
14
16
|
|
|
15
17
|
const { base } = fabMenu();
|
|
16
|
-
|
|
17
|
-
const margin = 8;
|
|
18
|
-
const gap = 8;
|
|
19
|
-
let coords = $state({
|
|
20
|
-
x: 0,
|
|
21
|
-
y: 0,
|
|
22
|
-
originX: 'right',
|
|
23
|
-
originY: 'bottom',
|
|
24
|
-
maxHeight: 0
|
|
25
|
-
});
|
|
26
18
|
</script>
|
|
27
19
|
|
|
28
20
|
<ul
|
|
29
21
|
data-cy="m3-fab-menu"
|
|
30
22
|
{...restProps}
|
|
31
|
-
class={base({
|
|
32
|
-
class: clsx(className, 'fab-menu overflow-y-auto')
|
|
33
|
-
})}
|
|
23
|
+
class={base({ class: clsx(className, 'fab-menu overflow-y-auto') })}
|
|
34
24
|
in:enterExit={{ duration: 300, easing: easeEmphasizedDecel, mode: 'scale' }}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const rect = menu.getBoundingClientRect();
|
|
44
|
-
|
|
45
|
-
const spaceAbove = anchorRect.top - gap - margin;
|
|
46
|
-
const spaceBelow = window.innerHeight - margin - (anchorRect.bottom + gap);
|
|
47
|
-
const placeAbove = spaceAbove >= rect.height || spaceAbove >= Math.max(0, spaceBelow);
|
|
48
|
-
|
|
49
|
-
let maxHeight = placeAbove ? spaceAbove : spaceBelow;
|
|
50
|
-
maxHeight = Math.max(0, Math.min(rect.height, maxHeight));
|
|
51
|
-
|
|
52
|
-
const targetTop = placeAbove ? anchorRect.top - gap - maxHeight : anchorRect.bottom + gap;
|
|
53
|
-
|
|
54
|
-
let targetLeft = anchorRect.right - rect.width;
|
|
55
|
-
if (targetLeft + rect.width > window.innerWidth - margin) {
|
|
56
|
-
targetLeft = window.innerWidth - margin - rect.width;
|
|
57
|
-
}
|
|
58
|
-
if (targetLeft < margin) targetLeft = margin;
|
|
59
|
-
|
|
60
|
-
let clampedTop = targetTop;
|
|
61
|
-
if (clampedTop < margin) clampedTop = margin;
|
|
62
|
-
if (clampedTop + maxHeight > window.innerHeight - margin) {
|
|
63
|
-
clampedTop = window.innerHeight - margin - maxHeight;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const originY = placeAbove ? 'bottom' : 'top';
|
|
67
|
-
const originX =
|
|
68
|
-
anchorRect.left + anchorRect.width / 2 < targetLeft + rect.width / 2 ? 'left' : 'right';
|
|
69
|
-
|
|
70
|
-
coords = { x: targetLeft, y: clampedTop, originX, originY, maxHeight };
|
|
25
|
+
out:enterExit={{ duration: 200, easing: easeEmphasizedAccel, mode: 'scale' }}
|
|
26
|
+
use:portal
|
|
27
|
+
use:floating={{
|
|
28
|
+
reference: anchorEl,
|
|
29
|
+
strategy: 'fixed',
|
|
30
|
+
placement: 'top-end',
|
|
31
|
+
offsetPx: 8,
|
|
32
|
+
middleware: [flip()]
|
|
71
33
|
}}
|
|
72
34
|
>
|
|
73
35
|
{@render children()}
|
|
@@ -75,6 +37,6 @@ Should be used with `FABMenuItem` as children.
|
|
|
75
37
|
|
|
76
38
|
<style>
|
|
77
39
|
.fab-menu {
|
|
78
|
-
transform-origin:
|
|
40
|
+
transform-origin: bottom right;
|
|
79
41
|
}
|
|
80
42
|
</style>
|
|
@@ -66,7 +66,7 @@ export const button = tv({
|
|
|
66
66
|
{
|
|
67
67
|
usage: 'selection',
|
|
68
68
|
selected: false,
|
|
69
|
-
class: { base: 'bg-md-sys-color-surface-container' }
|
|
69
|
+
class: { base: 'bg-md-sys-color-surface-container-high text-md-sys-color-on-surface-variant' }
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
variant: 'text',
|
|
@@ -275,7 +275,7 @@ export const buttonIcon = tv({
|
|
|
275
275
|
{
|
|
276
276
|
variation: 'toggle',
|
|
277
277
|
selected: false,
|
|
278
|
-
class: { base: 'bg-md-sys-color-surface-container' }
|
|
278
|
+
class: { base: 'bg-md-sys-color-surface-container-high text-md-sys-color-on-surface-variant' }
|
|
279
279
|
},
|
|
280
280
|
{
|
|
281
281
|
variant: 'text',
|
|
@@ -474,7 +474,7 @@ export const fab = tv({
|
|
|
474
474
|
});
|
|
475
475
|
export const fabMenu = tv({
|
|
476
476
|
slots: {
|
|
477
|
-
base: 'gap-2 pb-2 flex flex-col
|
|
477
|
+
base: 'gap-2 pb-2 flex flex-col z-[9999] overflow-visible p-1'
|
|
478
478
|
}
|
|
479
479
|
});
|
|
480
480
|
export const fabMenuItem = tv({
|
|
@@ -158,6 +158,8 @@ export type FABProps = FABVariants & AnchorButtonAttributes & {
|
|
|
158
158
|
children?: Snippet;
|
|
159
159
|
};
|
|
160
160
|
export type FABMenuProps = HTMLAttributes<HTMLUListElement> & {
|
|
161
|
+
/** The FAB button element to position the menu relative to. */
|
|
162
|
+
anchorEl: HTMLElement;
|
|
161
163
|
/**
|
|
162
164
|
* The menu items. Use `FABMenuItem` components.
|
|
163
165
|
*/
|
|
@@ -19,7 +19,6 @@ and `ContextMenu`, which owns its own item list and is right-click triggered.
|
|
|
19
19
|
import Icon from '../../../utils/icon/Icon.svelte';
|
|
20
20
|
import Layer from '../../../utils/Layer.svelte';
|
|
21
21
|
import { DropdownMenu } from 'bits-ui';
|
|
22
|
-
import clsx from 'clsx';
|
|
23
22
|
import { tv } from 'tailwind-variants';
|
|
24
23
|
|
|
25
24
|
let {
|
|
@@ -49,6 +49,7 @@ SupportingPane provides a layout with a main content area and a supporting side
|
|
|
49
49
|
<div class="top-3 right-3 z-10 hidden h-12 w-12 md:absolute md:block">
|
|
50
50
|
<ButtonIcon
|
|
51
51
|
triggerClass=""
|
|
52
|
+
type="button"
|
|
52
53
|
variant="text"
|
|
53
54
|
tooltipContent={supportingVisible ? 'Скрыть панель' : 'Показать панель'}
|
|
54
55
|
size="sm"
|
|
@@ -15,7 +15,7 @@ Side sheets are supplementary surfaces which are anchored to the edge of the scr
|
|
|
15
15
|
<div class="flex items-center justify-between p-6">
|
|
16
16
|
<span class="md-sys-typescale-title-large text-md-sys-color-on-surface-variant">{headline}</span
|
|
17
17
|
>
|
|
18
|
-
<ButtonIcon variant="text" iconProps={{ name: 'close' }} onclick={close} />
|
|
18
|
+
<ButtonIcon type="button" variant="text" iconProps={{ name: 'close' }} onclick={close} />
|
|
19
19
|
</div>
|
|
20
20
|
{@render children()}
|
|
21
21
|
</div>
|
|
@@ -104,11 +104,11 @@ DateField is a text field that allows users to enter a date or pick it from a ca
|
|
|
104
104
|
class="text-md-sys-color-on-surface-variant z-10 flex w-full items-center justify-between pb-7.5"
|
|
105
105
|
>
|
|
106
106
|
<DatePicker.PrevButton>
|
|
107
|
-
<ButtonIcon iconProps={{ name: 'chevron_left' }} />
|
|
107
|
+
<ButtonIcon type="button" iconProps={{ name: 'chevron_left' }} />
|
|
108
108
|
</DatePicker.PrevButton>
|
|
109
109
|
<DatePicker.Heading class="md-sys-typescale-label-large" />
|
|
110
110
|
<DatePicker.NextButton>
|
|
111
|
-
<ButtonIcon iconProps={{ name: 'chevron_right' }} />
|
|
111
|
+
<ButtonIcon type="button" iconProps={{ name: 'chevron_right' }} />
|
|
112
112
|
</DatePicker.NextButton>
|
|
113
113
|
</DatePicker.Header>
|
|
114
114
|
|
|
@@ -153,11 +153,11 @@ segment inputs and a shared calendar popover.
|
|
|
153
153
|
class="text-md-sys-color-on-surface-variant z-10 flex w-full items-center justify-between pb-7.5"
|
|
154
154
|
>
|
|
155
155
|
<DateRangePicker.PrevButton>
|
|
156
|
-
<ButtonIcon iconProps={{ name: 'chevron_left' }} />
|
|
156
|
+
<ButtonIcon type="button" iconProps={{ name: 'chevron_left' }} />
|
|
157
157
|
</DateRangePicker.PrevButton>
|
|
158
158
|
<DateRangePicker.Heading class="md-sys-typescale-label-large" />
|
|
159
159
|
<DateRangePicker.NextButton>
|
|
160
|
-
<ButtonIcon iconProps={{ name: 'chevron_right' }} />
|
|
160
|
+
<ButtonIcon type="button" iconProps={{ name: 'chevron_right' }} />
|
|
161
161
|
</DateRangePicker.NextButton>
|
|
162
162
|
</DateRangePicker.Header>
|
|
163
163
|
|
|
@@ -68,7 +68,11 @@ Text fields allow users to enter and edit text.
|
|
|
68
68
|
{#if trailingIcon}
|
|
69
69
|
{@render trailingIcon()}
|
|
70
70
|
{:else if trailingIconProps}
|
|
71
|
-
<ButtonIcon
|
|
71
|
+
<ButtonIcon
|
|
72
|
+
type="button"
|
|
73
|
+
onclick={trailingOnClick}
|
|
74
|
+
class={cls.trailingIcon()}
|
|
75
|
+
iconProps={trailingIconProps}
|
|
72
76
|
></ButtonIcon>
|
|
73
77
|
{/if}
|
|
74
78
|
</div>
|
|
@@ -58,7 +58,7 @@ It follows the Material 3 design for time input pickers.
|
|
|
58
58
|
</TimeField.Root>
|
|
59
59
|
|
|
60
60
|
<div class={cls.buttonDiv()}>
|
|
61
|
-
<ButtonIcon iconProps={{ name: 'schedule' }} />
|
|
61
|
+
<ButtonIcon type="button" iconProps={{ name: 'schedule' }} />
|
|
62
62
|
<div>
|
|
63
63
|
<Button variant="text" type="button" onclick={() => close()}>Отмена</Button>
|
|
64
64
|
<Button
|