@max-ts/svelte 1.10.7 → 1.10.10

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.
@@ -3453,18 +3453,6 @@ img, picture, video, canvas {
3453
3453
  .styles_content__1ovcrev8[data-side="top"] {
3454
3454
  animation: styles_fadeIn__1ovcrev0 150ms ease-out, styles_slideInFromBottom__1ovcrev5 150ms ease-out;
3455
3455
  }
3456
- .styles_content__1ovcrev8[data-side="bottom"][data-state="closed"] {
3457
- animation: styles_fadeOut__1ovcrev1 150ms ease-out, styles_zoomOut__1ovcrev3 150ms ease-out, styles_slideInFromTop__1ovcrev4 150ms ease-out reverse;
3458
- }
3459
- .styles_content__1ovcrev8[data-side="left"][data-state="closed"] {
3460
- animation: styles_fadeOut__1ovcrev1 150ms ease-out, styles_zoomOut__1ovcrev3 150ms ease-out, styles_slideInFromEnd__1ovcrev6 150ms ease-out reverse;
3461
- }
3462
- .styles_content__1ovcrev8[data-side="right"][data-state="closed"] {
3463
- animation: styles_fadeOut__1ovcrev1 150ms ease-out, styles_zoomOut__1ovcrev3 150ms ease-out, styles_slideInFromStart__1ovcrev7 150ms ease-out reverse;
3464
- }
3465
- .styles_content__1ovcrev8[data-side="top"][data-state="closed"] {
3466
- animation: styles_fadeOut__1ovcrev1 150ms ease-out, styles_zoomOut__1ovcrev3 150ms ease-out, styles_slideInFromBottom__1ovcrev5 150ms ease-out reverse;
3467
- }
3468
3456
  .styles_arrow__1ovcrev9 {
3469
3457
  fill: var(--colors-background-tooltip);
3470
3458
  width: 14px;
@@ -8,5 +8,5 @@ declare const Alert: {
8
8
  Title: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLAttributes<HTMLDivElement>>, {}, "ref">;
9
9
  Description: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLAttributes<HTMLDivElement>>, {}, "ref">;
10
10
  };
11
- export { Alert, alertVariants };
12
11
  export type * from './types';
12
+ export { Alert, alertVariants };
@@ -7,5 +7,5 @@ declare const Card: {
7
7
  Footer: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLAttributes<HTMLDivElement>>, {}, "ref">;
8
8
  Action: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLAttributes<HTMLDivElement>>, {}, "ref">;
9
9
  };
10
- export { Card };
11
10
  export type * from './types';
11
+ export { Card };
@@ -1,3 +1,3 @@
1
1
  import Header from './Header.svelte';
2
- export { Header };
3
2
  export type { HeaderProps } from './types';
3
+ export { Header };
@@ -10,5 +10,5 @@ declare const Dialog: {
10
10
  Title: import("svelte").Component<import("bits-ui").AlertDialogTitleProps, {}, "ref">;
11
11
  Description: import("svelte").Component<import("bits-ui").AlertDialogDescriptionProps, {}, "ref">;
12
12
  };
13
- export { Dialog };
14
13
  export type * from './types';
14
+ export { Dialog };
@@ -15,5 +15,5 @@ import { Sub } from './Sub';
15
15
  import { SubContent } from './SubContent';
16
16
  import { SubTrigger } from './SubTrigger';
17
17
  import { Trigger } from './Trigger';
18
- export { CheckboxGroup, CheckboxItem, Content, Group, GroupHeading, Item, Label, Portal, RadioGroup, RadioItem, Root, Separator, Shortcut, Sub, SubContent, SubTrigger, Trigger, };
19
18
  export type { DropdownMenuProps } from './types';
19
+ export { CheckboxGroup, CheckboxItem, Content, Group, GroupHeading, Item, Label, Portal, RadioGroup, RadioItem, Root, Separator, Shortcut, Sub, SubContent, SubTrigger, Trigger, };
@@ -27,5 +27,5 @@ declare const Field: {
27
27
  Set: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLFieldsetAttributes>, {}, "ref">;
28
28
  Title: import("svelte").Component<import("../../types").WithElementRef<import("svelte/elements").HTMLAttributes<HTMLDivElement>>, {}, "ref">;
29
29
  };
30
- export { Field };
31
30
  export * from './types';
31
+ export { Field };
@@ -1,139 +1,41 @@
1
1
  import Portal from "../Portal/Portal.js";
2
+ import { TooltipStore } from "./store.svelte.js";
2
3
  import __default__ from "./styles.css.js";
3
4
  import "svelte/internal/disclose-version";
4
5
  import * as $ from "svelte/internal/client";
5
- import { tick, untrack } from "svelte";
6
6
  //#region src/components/Tooltip/Tooltip.svelte
7
- let activeDismiss = null;
8
7
  var root_5 = $.from_svg(`<svg viewBox="0 0 7.68 4.35" xmlns="http://www.w3.org/2000/svg"><path d="m 0.52372243,0.10910656 c -0.1676883,0 -0.3188698,0.10099765 -0.38304509,0.25594925 -0.0641698,0.1548964 -0.0287017,0.3332318 0.0898753,0.4518088 L 3.5473966,4.1337031 c 0.077725,0.07778 0.1832001,0.1214516 0.2931533,0.1214516 0.1099531,0 0.2154286,-0.043672 0.2932085,-0.1214516 L 7.4505968,0.81686461 c 0.118577,-0.118577 0.1540119,-0.2969124 0.089831,-0.4518088 C 7.476247,0.21010421 7.3251098,0.10910656 7.1573882,0.10910656 Z" fill="inherit"></path></svg>`);
9
8
  var root_2 = $.from_html(`<div role="tooltip" data-slot="tooltip-content"><!> <!></div>`);
10
9
  var root = $.from_html(`<span style="display: contents;" data-slot="tooltip-trigger"><!></span> <!>`, 1);
11
10
  function Tooltip($$anchor, $$props) {
12
11
  $.push($$props, true);
13
- const ANIMATION_DURATION = 150;
14
- let open = $.prop($$props, "open", 15, false), alignOffset = $.prop($$props, "alignOffset", 3, 0), sideOffset = $.prop($$props, "sideOffset", 3, 10), side = $.prop($$props, "side", 3, "top"), align = $.prop($$props, "align", 3, "center"), arrow = $.prop($$props, "arrow", 3, false), delayDuration = $.prop($$props, "delayDuration", 3, 200);
15
- let triggerEl;
16
- let contentEl = $.state(void 0);
17
- let visible = $.state(false);
18
- let delayTimer;
19
- let closeTimer;
20
- let position = $.state({
21
- top: 0,
22
- left: 0
23
- });
24
- const tooltipId = `tooltip-${Math.random().toString(36).slice(2, 11)}`;
25
- function updatePosition() {
26
- if (!triggerEl || !$.get(contentEl)) return;
27
- const triggerRect = triggerEl.getBoundingClientRect();
28
- const contentRect = $.get(contentEl).getBoundingClientRect();
29
- let top = 0;
30
- let left = 0;
31
- switch (side()) {
32
- case "top":
33
- top = triggerRect.top - contentRect.height - sideOffset();
34
- left = triggerRect.left + (triggerRect.width - contentRect.width) / 2;
35
- break;
36
- case "bottom":
37
- top = triggerRect.bottom + sideOffset();
38
- left = triggerRect.left + (triggerRect.width - contentRect.width) / 2;
39
- break;
40
- case "left":
41
- top = triggerRect.top + (triggerRect.height - contentRect.height) / 2;
42
- left = triggerRect.left - contentRect.width - sideOffset();
43
- break;
44
- case "right":
45
- top = triggerRect.top + (triggerRect.height - contentRect.height) / 2;
46
- left = triggerRect.right + sideOffset();
47
- break;
12
+ let offset = $.prop($$props, "offset", 3, 10), placement = $.prop($$props, "placement", 3, "top"), arrow = $.prop($$props, "arrow", 3, false), delayDuration = $.prop($$props, "delayDuration", 3, 200);
13
+ const store = new TooltipStore({
14
+ get placement() {
15
+ return placement();
16
+ },
17
+ get offset() {
18
+ return offset();
19
+ },
20
+ get delayDuration() {
21
+ return delayDuration();
48
22
  }
49
- if (side() === "top" || side() === "bottom") if (align() === "start") left = triggerRect.left + alignOffset();
50
- else if (align() === "end") left = triggerRect.right - contentRect.width - alignOffset();
51
- else left += alignOffset();
52
- else if (align() === "start") top = triggerRect.top + alignOffset();
53
- else if (align() === "end") top = triggerRect.bottom - contentRect.height - alignOffset();
54
- else top += alignOffset();
55
- $.set(position, {
56
- top,
57
- left
58
- });
59
- }
60
- function dismiss() {
61
- clearTimeout(delayTimer);
62
- clearTimeout(closeTimer);
63
- if (activeDismiss === dismiss) activeDismiss = null;
64
- open(false);
65
- $.set(visible, false);
66
- }
67
- function show() {
68
- if (activeDismiss && activeDismiss !== dismiss) activeDismiss();
69
- clearTimeout(closeTimer);
70
- clearTimeout(delayTimer);
71
- activeDismiss = dismiss;
72
- delayTimer = setTimeout(() => {
73
- open(true);
74
- }, delayDuration());
75
- }
76
- function hide() {
77
- clearTimeout(delayTimer);
78
- if (activeDismiss === dismiss) activeDismiss = null;
79
- open(false);
80
- }
81
- function handleKeydown(event) {
82
- if (event.key === "Escape" && open()) hide();
83
- }
84
- $.user_effect(() => {
85
- if (open()) {
86
- clearTimeout(closeTimer);
87
- $.set(visible, true);
88
- tick().then(updatePosition);
89
- } else if (untrack(() => $.get(visible))) closeTimer = setTimeout(() => {
90
- $.set(visible, false);
91
- }, ANIMATION_DURATION);
92
- });
93
- $.user_effect(() => {
94
- if (!open()) return;
95
- window.addEventListener("scroll", updatePosition, true);
96
- window.addEventListener("resize", updatePosition);
97
- return () => {
98
- window.removeEventListener("scroll", updatePosition, true);
99
- window.removeEventListener("resize", updatePosition);
100
- };
101
23
  });
102
- $.user_effect(() => {
103
- return () => dismiss();
104
- });
105
- function attachTrigger(node) {
106
- const el = node.firstElementChild;
107
- if (!el) return;
108
- triggerEl = el;
109
- el.addEventListener("mouseenter", show);
110
- el.addEventListener("mouseleave", hide);
111
- el.addEventListener("focusin", show);
112
- el.addEventListener("focusout", hide);
113
- el.setAttribute("aria-describedby", tooltipId);
114
- return () => {
115
- el.removeEventListener("mouseenter", show);
116
- el.removeEventListener("mouseleave", hide);
117
- el.removeEventListener("focusin", show);
118
- el.removeEventListener("focusout", hide);
119
- el.removeAttribute("aria-describedby");
120
- triggerEl = void 0;
121
- };
122
- }
24
+ $.user_effect(() => () => store.destroy());
123
25
  var fragment = root();
124
- $.event("keydown", $.window, handleKeydown);
26
+ $.event("keydown", $.window, (e) => e.key === "Escape" && store.open && store.hide());
125
27
  var span = $.first_child(fragment);
126
- var node_1 = $.child(span);
127
- $.snippet(node_1, () => $$props.children ?? $.noop);
28
+ var node = $.child(span);
29
+ $.snippet(node, () => $$props.children ?? $.noop);
128
30
  $.reset(span);
129
- $.attach(span, () => attachTrigger);
130
- var node_2 = $.sibling(span, 2);
31
+ $.attach(span, () => store.attachTrigger);
32
+ var node_1 = $.sibling(span, 2);
131
33
  var consequent_2 = ($$anchor) => {
132
34
  Portal($$anchor, {
133
35
  children: ($$anchor, $$slotProps) => {
134
36
  var div = root_2();
135
37
  let styles_1;
136
- var node_3 = $.child(div);
38
+ var node_2 = $.child(div);
137
39
  var consequent = ($$anchor) => {
138
40
  var text = $.text();
139
41
  $.template_effect(() => $.set_text(text, $$props.content));
@@ -141,53 +43,52 @@ function Tooltip($$anchor, $$props) {
141
43
  };
142
44
  var alternate = ($$anchor) => {
143
45
  var fragment_3 = $.comment();
144
- var node_4 = $.first_child(fragment_3);
145
- $.snippet(node_4, () => $$props.content ?? $.noop);
46
+ var node_3 = $.first_child(fragment_3);
47
+ $.snippet(node_3, () => $$props.content ?? $.noop);
146
48
  $.append($$anchor, fragment_3);
147
49
  };
148
- $.if(node_3, ($$render) => {
50
+ $.if(node_2, ($$render) => {
149
51
  if (typeof $$props.content === "string") $$render(consequent);
150
52
  else $$render(alternate, -1);
151
53
  });
152
- var node_5 = $.sibling(node_3, 2);
54
+ var node_4 = $.sibling(node_2, 2);
153
55
  var consequent_1 = ($$anchor) => {
154
56
  var svg = root_5();
155
57
  $.template_effect(() => {
156
58
  $.set_class(svg, 0, $.clsx([__default__.arrow, $$props.arrowClass]));
157
- $.set_attribute(svg, "data-side", side());
59
+ $.set_attribute(svg, "data-side", store.placement);
158
60
  });
159
61
  $.append($$anchor, svg);
160
62
  };
161
- $.if(node_5, ($$render) => {
63
+ $.if(node_4, ($$render) => {
162
64
  if (arrow()) $$render(consequent_1);
163
65
  });
164
66
  $.reset(div);
165
- $.bind_this(div, ($$value) => $.set(contentEl, $$value), () => $.get(contentEl));
67
+ $.attach(div, () => store.attachContent);
166
68
  $.template_effect(() => {
167
- $.set_attribute(div, "id", tooltipId);
168
- $.set_attribute(div, "data-state", open() ? "open" : "closed");
169
- $.set_attribute(div, "data-side", side());
69
+ $.set_attribute(div, "id", store.tooltipId);
70
+ $.set_attribute(div, "data-state", store.open ? "open" : "closed");
71
+ $.set_attribute(div, "data-side", store.placement);
170
72
  $.set_class(div, 1, $.clsx([__default__.content, $$props.class]));
171
73
  styles_1 = $.set_style(div, "", styles_1, {
172
74
  position: "fixed",
173
- top: `${$.get(position).top ?? ""}px`,
174
- left: `${$.get(position).left ?? ""}px`
75
+ top: `${store.y ?? ""}px`,
76
+ left: `${store.x ?? ""}px`
175
77
  });
176
78
  });
177
- $.event("mouseenter", div, () => {
178
- clearTimeout(closeTimer);
179
- clearTimeout(delayTimer);
180
- activeDismiss = dismiss;
181
- open(true);
79
+ $.event("mouseenter", div, function(...$$args) {
80
+ store.keepOpen?.apply(this, $$args);
81
+ });
82
+ $.event("mouseleave", div, function(...$$args) {
83
+ store.hide?.apply(this, $$args);
182
84
  });
183
- $.event("mouseleave", div, hide);
184
85
  $.append($$anchor, div);
185
86
  },
186
87
  $$slots: { default: true }
187
88
  });
188
89
  };
189
- $.if(node_2, ($$render) => {
190
- if ($.get(visible)) $$render(consequent_2);
90
+ $.if(node_1, ($$render) => {
91
+ if (store.visible) $$render(consequent_2);
191
92
  });
192
93
  $.append($$anchor, fragment);
193
94
  $.pop();
@@ -1,4 +1,4 @@
1
1
  import type { TooltipProps } from './types';
2
- declare const Tooltip: import("svelte").Component<TooltipProps, {}, "open">;
2
+ declare const Tooltip: import("svelte").Component<TooltipProps, {}, "">;
3
3
  type Tooltip = ReturnType<typeof Tooltip>;
4
4
  export default Tooltip;
@@ -1,2 +1,2 @@
1
1
  export { default as Tooltip } from './Tooltip.svelte';
2
- export type { TooltipAlign, TooltipProps, TooltipSide } from './types';
2
+ export type { TooltipProps } from './types';
@@ -0,0 +1,26 @@
1
+ import type { TooltipProps } from './types';
2
+ type Options = Pick<TooltipProps, 'delayDuration' | 'placement' | 'offset'>;
3
+ export declare class TooltipStore {
4
+ #private;
5
+ open: boolean;
6
+ visible: boolean;
7
+ x: number;
8
+ y: number;
9
+ readonly tooltipId: string;
10
+ private static active;
11
+ private static readonly CLOSE_DURATION;
12
+ private triggerEl;
13
+ private cleanupAutoUpdate;
14
+ private delayTimer;
15
+ private closeTimer;
16
+ constructor(options: Options);
17
+ get placement(): import("@floating-ui/dom").Placement | undefined;
18
+ show: () => void;
19
+ hide: () => void;
20
+ keepOpen: () => void;
21
+ attachTrigger: (node: HTMLElement) => (() => void) | undefined;
22
+ attachContent: (node: HTMLElement) => (() => void) | undefined;
23
+ destroy(): void;
24
+ private forceClose;
25
+ }
26
+ export {};
@@ -0,0 +1,107 @@
1
+ import { autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
2
+ //#region src/components/Tooltip/store.svelte.ts
3
+ var TooltipStore = class TooltipStore {
4
+ open = $state(false);
5
+ visible = $state(false);
6
+ x = $state(0);
7
+ y = $state(0);
8
+ #options = $state({
9
+ delayDuration: 300,
10
+ placement: "top",
11
+ offset: 8
12
+ });
13
+ tooltipId = `tooltip-${Math.random().toString(36).slice(2, 11)}`;
14
+ static active = null;
15
+ static CLOSE_DURATION = 150;
16
+ triggerEl;
17
+ cleanupAutoUpdate;
18
+ delayTimer;
19
+ closeTimer;
20
+ constructor(options) {
21
+ this.#options = {
22
+ ...this.#options,
23
+ ...options
24
+ };
25
+ }
26
+ get placement() {
27
+ return this.#options.placement;
28
+ }
29
+ show = () => {
30
+ if (TooltipStore.active && TooltipStore.active !== this) TooltipStore.active.forceClose();
31
+ clearTimeout(this.closeTimer);
32
+ clearTimeout(this.delayTimer);
33
+ TooltipStore.active = this;
34
+ this.delayTimer = setTimeout(() => {
35
+ this.visible = true;
36
+ this.open = true;
37
+ }, this.#options.delayDuration);
38
+ };
39
+ hide = () => {
40
+ clearTimeout(this.delayTimer);
41
+ if (TooltipStore.active === this) TooltipStore.active = null;
42
+ this.open = false;
43
+ this.closeTimer = setTimeout(() => {
44
+ this.visible = false;
45
+ }, TooltipStore.CLOSE_DURATION);
46
+ };
47
+ keepOpen = () => {
48
+ clearTimeout(this.closeTimer);
49
+ clearTimeout(this.delayTimer);
50
+ this.open = true;
51
+ TooltipStore.active = this;
52
+ };
53
+ attachTrigger = (node) => {
54
+ const el = node.firstElementChild;
55
+ if (!el) return;
56
+ this.triggerEl = el;
57
+ el.addEventListener("mouseenter", this.show);
58
+ el.addEventListener("mouseleave", this.hide);
59
+ el.addEventListener("focusin", this.show);
60
+ el.addEventListener("focusout", this.hide);
61
+ el.setAttribute("aria-describedby", this.tooltipId);
62
+ return () => {
63
+ el.removeEventListener("mouseenter", this.show);
64
+ el.removeEventListener("mouseleave", this.hide);
65
+ el.removeEventListener("focusin", this.show);
66
+ el.removeEventListener("focusout", this.hide);
67
+ el.removeAttribute("aria-describedby");
68
+ this.triggerEl = void 0;
69
+ };
70
+ };
71
+ attachContent = (node) => {
72
+ if (!this.triggerEl) return;
73
+ this.cleanupAutoUpdate = autoUpdate(this.triggerEl, node, () => {
74
+ if (!this.triggerEl) return;
75
+ computePosition(this.triggerEl, node, {
76
+ placement: this.#options.placement,
77
+ middleware: [
78
+ offset({ mainAxis: this.#options.offset }),
79
+ flip(),
80
+ shift({ padding: 8 })
81
+ ]
82
+ }).then(({ x, y, placement }) => {
83
+ this.x = x;
84
+ this.y = y;
85
+ this.#options.placement = placement;
86
+ });
87
+ });
88
+ return () => {
89
+ this.cleanupAutoUpdate?.();
90
+ this.cleanupAutoUpdate = void 0;
91
+ };
92
+ };
93
+ destroy() {
94
+ this.forceClose();
95
+ }
96
+ forceClose() {
97
+ clearTimeout(this.delayTimer);
98
+ clearTimeout(this.closeTimer);
99
+ if (TooltipStore.active === this) TooltipStore.active = null;
100
+ this.open = false;
101
+ this.visible = false;
102
+ this.cleanupAutoUpdate?.();
103
+ this.cleanupAutoUpdate = void 0;
104
+ }
105
+ };
106
+ //#endregion
107
+ export { TooltipStore };
@@ -1,16 +1,12 @@
1
+ import type { Placement } from '@floating-ui/dom';
1
2
  import type { Snippet } from 'svelte';
2
- export type TooltipSide = 'top' | 'bottom' | 'left' | 'right';
3
- export type TooltipAlign = 'start' | 'center' | 'end';
4
3
  export type TooltipProps = {
5
- open?: boolean;
6
4
  delayDuration?: number;
7
5
  content?: Snippet<[]> | string;
8
6
  children?: Snippet<[]>;
9
7
  arrow?: boolean;
10
- align?: TooltipAlign;
11
- sideOffset?: number;
12
- alignOffset?: number;
13
- side?: TooltipSide;
8
+ offset?: number;
14
9
  class?: string;
15
10
  arrowClass?: string;
11
+ placement?: Placement;
16
12
  };
@@ -32,5 +32,5 @@ export { Slider, type SliderProps } from './Slider';
32
32
  export { SliderInput, type SliderInputProps } from './SliderInput';
33
33
  export { Spinner, type SpinnerSize } from './Spinner';
34
34
  export { Tabs, type TabsProps } from './Tabs';
35
- export { Tooltip, type TooltipAlign, type TooltipProps, type TooltipSide, } from './Tooltip';
35
+ export { Tooltip, type TooltipProps, } from './Tooltip';
36
36
  export { Typography, type TypographyAlign, type TypographyColor, type TypographyProps, type TypographyVariant, } from './Typography';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-ts/svelte",
3
- "version": "1.10.7",
3
+ "version": "1.10.10",
4
4
  "type": "module",
5
5
  "description": "Svelte component library.",
6
6
  "author": "Tsepelev Maksim",
@@ -67,6 +67,7 @@
67
67
  "vitest-browser-svelte": "^2.1.0"
68
68
  },
69
69
  "dependencies": {
70
+ "@floating-ui/dom": "^1.7.6",
70
71
  "@lucide/svelte": "^0.577.0",
71
72
  "bits-ui": "^2.16.3"
72
73
  },