@noxlovette/material 0.1.18 → 0.1.19

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.
@@ -14,7 +14,6 @@ Floating action buttons (FABs) help people take primary actions.
14
14
  import { fab } from './theme.js';
15
15
  import type { FABProps } from './types.js';
16
16
  import FABMenu from './FABMenu.svelte';
17
- import ButtonIcon from './ButtonIcon.svelte';
18
17
  import { Layer, Icon } from '../../utils/index.js';
19
18
  import { clickOutside } from '../../actions/index.js';
20
19
  import { Button, type ButtonRootProps } from 'bits-ui';
@@ -34,10 +33,19 @@ Floating action buttons (FABs) help people take primary actions.
34
33
  }: FABProps = $props();
35
34
 
36
35
  const { base, icon, label: labelClass } = $derived(fab({ size, config, expanded }));
37
- const btnCls = $derived(base({ class: clsx(className) }));
38
36
 
39
37
  let showMenu = $state(false);
40
38
 
39
+ const btnCls = $derived(
40
+ base({
41
+ class: clsx(
42
+ className,
43
+ 'transition-[border-radius] duration-300',
44
+ withMenu && showMenu && '!rounded-full'
45
+ )
46
+ })
47
+ );
48
+
41
49
  function handleClick(e: MouseEvent) {
42
50
  if (disabled) {
43
51
  e.preventDefault();
@@ -45,24 +53,12 @@ Floating action buttons (FABs) help people take primary actions.
45
53
  }
46
54
  if (withMenu) {
47
55
  e.preventDefault();
48
- showMenu = true;
56
+ showMenu = !showMenu;
49
57
  }
50
58
  }
51
59
  </script>
52
60
 
53
- {#if withMenu && showMenu}
54
- <div class="relative z-50" use:clickOutside={() => (showMenu = false)}>
55
- <FABMenu>
56
- {@render children?.()}
57
- </FABMenu>
58
- <ButtonIcon
59
- variant="filled"
60
- class="shadow-elevation-3"
61
- iconProps={{ name: 'close' }}
62
- onclick={() => (showMenu = !showMenu)}
63
- />
64
- </div>
65
- {:else}
61
+ <div class="contents" use:clickOutside={() => (showMenu = false)}>
66
62
  <Button.Root
67
63
  {disabled}
68
64
  {formaction}
@@ -71,12 +67,18 @@ Floating action buttons (FABs) help people take primary actions.
71
67
  data-cy="m3-fab"
72
68
  {...restProps as ButtonRootProps}
73
69
  >
74
- <Icon {...iconProps} class={icon()} />
70
+ <Icon {...withMenu && showMenu ? { name: 'close' } : iconProps} class={icon()} />
75
71
  <Layer />
76
- {#if expanded}
72
+ {#if expanded && !(withMenu && showMenu)}
77
73
  <p class={labelClass()}>
78
74
  {label}
79
75
  </p>
80
76
  {/if}
81
77
  </Button.Root>
82
- {/if}
78
+
79
+ {#if withMenu && showMenu}
80
+ <FABMenu>
81
+ {@render children?.()}
82
+ </FABMenu>
83
+ {/if}
84
+ </div>
@@ -10,21 +10,19 @@ Should be used with `FABMenuItem` as children.
10
10
  import { enterExit } from '../../animation/enterExit.js';
11
11
  import { easeEmphasizedDecel } from '../../animation/easing.js';
12
12
 
13
- let { children, class: className, position = 'top', ...restProps }: FABMenuProps = $props();
13
+ let { children, class: className, ...restProps }: FABMenuProps = $props();
14
14
 
15
- const { base } = $derived(fabMenu({ position }));
15
+ const { base } = fabMenu();
16
16
 
17
17
  const margin = 8;
18
18
  const gap = 8;
19
19
  let coords = $state({
20
20
  x: 0,
21
21
  y: 0,
22
- originX: 'left',
23
- originY: 'top',
22
+ originX: 'right',
23
+ originY: 'bottom',
24
24
  maxHeight: 0
25
25
  });
26
-
27
- // TODO: out:enterExit={{ duration: 200, easing: easeEmphasizedAccel, mode: 'scale' }} – if you can solve how to eliminate another button from appearing here, use this too
28
26
  </script>
29
27
 
30
28
  <ul
@@ -38,9 +36,11 @@ Should be used with `FABMenuItem` as children.
38
36
  style:max-height={coords.maxHeight ? `${coords.maxHeight}px` : undefined}
39
37
  style:--enter-exit-origin={`${coords.originY} ${coords.originX}`}
40
38
  {@attach (menu) => {
39
+ const anchorEl = menu.previousElementSibling as HTMLElement;
40
+ if (!anchorEl) return;
41
+
42
+ const anchorRect = anchorEl.getBoundingClientRect();
41
43
  const rect = menu.getBoundingClientRect();
42
- const anchorRect = menu.parentElement?.getBoundingClientRect();
43
- if (!anchorRect) return;
44
44
 
45
45
  const spaceAbove = anchorRect.top - gap - margin;
46
46
  const spaceBelow = window.innerHeight - margin - (anchorRect.bottom + gap);
@@ -52,29 +52,22 @@ Should be used with `FABMenuItem` as children.
52
52
  const targetTop = placeAbove ? anchorRect.top - gap - maxHeight : anchorRect.bottom + gap;
53
53
 
54
54
  let targetLeft = anchorRect.right - rect.width;
55
-
56
55
  if (targetLeft + rect.width > window.innerWidth - margin) {
57
56
  targetLeft = window.innerWidth - margin - rect.width;
58
57
  }
59
- if (targetLeft < margin) {
60
- targetLeft = margin;
61
- }
58
+ if (targetLeft < margin) targetLeft = margin;
62
59
 
63
60
  let clampedTop = targetTop;
64
- if (clampedTop < margin) {
65
- clampedTop = margin;
66
- }
61
+ if (clampedTop < margin) clampedTop = margin;
67
62
  if (clampedTop + maxHeight > window.innerHeight - margin) {
68
63
  clampedTop = window.innerHeight - margin - maxHeight;
69
64
  }
70
65
 
71
- const x = targetLeft - rect.left;
72
- const y = clampedTop - rect.top;
73
66
  const originY = placeAbove ? 'bottom' : 'top';
74
67
  const originX =
75
68
  anchorRect.left + anchorRect.width / 2 < targetLeft + rect.width / 2 ? 'left' : 'right';
76
69
 
77
- coords = { x, y, originX, originY, maxHeight };
70
+ coords = { x: targetLeft, y: clampedTop, originX, originY, maxHeight };
78
71
  }}
79
72
  >
80
73
  {@render children()}
@@ -491,22 +491,28 @@ export declare const fab: import("tailwind-variants").TVReturnType<{
491
491
  label: string;
492
492
  }, undefined, unknown, unknown, undefined>>;
493
493
  export declare const fabMenu: import("tailwind-variants").TVReturnType<{
494
- position: {
495
- top: string;
494
+ [key: string]: {
495
+ [key: string]: import("tailwind-merge").ClassNameValue | {
496
+ base?: import("tailwind-merge").ClassNameValue;
497
+ };
496
498
  };
497
- }, {
499
+ } | {
500
+ [x: string]: {
501
+ [x: string]: import("tailwind-merge").ClassNameValue | {
502
+ base?: import("tailwind-merge").ClassNameValue;
503
+ };
504
+ };
505
+ } | {}, {
498
506
  base: string;
499
507
  }, undefined, {
500
- position: {
501
- top: string;
508
+ [key: string]: {
509
+ [key: string]: import("tailwind-merge").ClassNameValue | {
510
+ base?: import("tailwind-merge").ClassNameValue;
511
+ };
502
512
  };
503
- }, {
513
+ } | {}, {
504
514
  base: string;
505
- }, import("tailwind-variants").TVReturnType<{
506
- position: {
507
- top: string;
508
- };
509
- }, {
515
+ }, import("tailwind-variants").TVReturnType<unknown, {
510
516
  base: string;
511
517
  }, undefined, unknown, unknown, undefined>>;
512
518
  export declare const fabMenuItem: import("tailwind-variants").TVReturnType<{
@@ -474,10 +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 absolute z-[100] overflow-visible p-1'
478
- },
479
- variants: {
480
- position: { top: 'top-16' }
477
+ base: 'gap-2 pb-2 flex flex-col fixed left-0 top-0 z-[9999] overflow-visible p-1'
481
478
  }
482
479
  });
483
480
  export const fabMenuItem = tv({
@@ -1,7 +1,7 @@
1
1
  import type { AnchorButtonAttributes, IconProps } from '../../utils/index.js';
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAnchorAttributes, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
4
- import type { ButtonGroupVariants, ButtonIconVariants, ButtonMDVariants, FABMenuItemVariants, FABMenuVariants, FABVariants } from './theme.js';
4
+ import type { ButtonGroupVariants, ButtonIconVariants, ButtonMDVariants, FABMenuItemVariants, FABVariants } from './theme.js';
5
5
  export interface ButtonGroupProps extends ButtonGroupVariants, HTMLAttributes<HTMLDivElement> {
6
6
  /**
7
7
  * The content of the button group.
@@ -157,11 +157,7 @@ export type FABProps = FABVariants & AnchorButtonAttributes & {
157
157
  */
158
158
  children?: Snippet;
159
159
  };
160
- export type FABMenuProps = FABMenuVariants & HTMLAttributes<HTMLUListElement> & {
161
- /**
162
- * The vertical position of the menu relative to the anchor.
163
- */
164
- position?: FABMenuVariants['position'];
160
+ export type FABMenuProps = HTMLAttributes<HTMLUListElement> & {
165
161
  /**
166
162
  * The menu items. Use `FABMenuItem` components.
167
163
  */
@@ -26,7 +26,6 @@ Context menus appear on right-click and provide actions related to the clicked e
26
26
  import Divider from '../divider/Divider.svelte';
27
27
  import { enterExit } from '../../../animation/enterExit.js';
28
28
  import { easeEmphasizedDecel } from '../../../animation/easing.js';
29
- import clsx from 'clsx';
30
29
 
31
30
  let {
32
31
  items = [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noxlovette/material",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {