flowbite-svelte 0.17.3 → 0.17.6

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/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.17.6](https://github.com/themesberg/flowbite-svelte/compare/v0.17.5...v0.17.6) (2022-06-17)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * removed $app/env browser from Tooltip component ([604a1e0](https://github.com/themesberg/flowbite-svelte/commit/604a1e075c6333c5532e04916a20500a31fb4716))
11
+
12
+ ### [0.17.5](https://github.com/themesberg/flowbite-svelte/compare/v0.17.4...v0.17.5) (2022-06-16)
13
+
14
+ ### [0.17.4](https://github.com/themesberg/flowbite-svelte/compare/v0.17.3...v0.17.4) (2022-06-14)
15
+
16
+ ### Breaking Change
17
+
18
+ * Tooltip component has different structures.
19
+
20
+ ### Bug Fixes
21
+
22
+ * update Tooltip component ([d0cc06e](https://github.com/themesberg/flowbite-svelte/commit/d0cc06e991e5677463a5625b4abaee2a6edef3fc))
23
+
5
24
  ### [0.17.3](https://github.com/themesberg/flowbite-svelte/compare/v0.17.2...v0.17.3) (2022-06-14)
6
25
 
7
26
 
package/index.d.ts CHANGED
@@ -97,4 +97,3 @@ export { default as TimelineItemHorizontal } from './timelines/TimelineItemHoriz
97
97
  export { default as TimelineItemVertical } from './timelines/TimelineItemVertical.svelte';
98
98
  export { default as Toast } from './toasts/Toast.svelte';
99
99
  export { default as Tooltip } from './tooltips/Tooltip.svelte';
100
- export { default as LightTooltip } from './tooltips/LightTooltip.svelte';
package/index.js CHANGED
@@ -123,4 +123,3 @@ export { default as TimelineItemVertical } from './timelines/TimelineItemVertica
123
123
  export { default as Toast } from './toasts/Toast.svelte';
124
124
  // Tooltips
125
125
  export { default as Tooltip } from './tooltips/Tooltip.svelte';
126
- export { default as LightTooltip } from './tooltips/LightTooltip.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowbite-svelte",
3
- "version": "0.17.3",
3
+ "version": "0.17.6",
4
4
  "description": "Flowbite components for Svelte",
5
5
  "main": "index.js",
6
6
  "author": {
@@ -75,6 +75,8 @@
75
75
  "url": "https://github.com/themesberg/flowbite-svelte"
76
76
  },
77
77
  "dependencies": {
78
+ "@floating-ui/dom": "^0.5.3",
79
+ "classnames": "^2.3.1",
78
80
  "flowbite": "^1.4.2",
79
81
  "svelte-heros": "^2.2.2"
80
82
  },
@@ -193,9 +195,9 @@
193
195
  "./timelines/TimelineItemHorizontal.svelte": "./timelines/TimelineItemHorizontal.svelte",
194
196
  "./timelines/TimelineItemVertical.svelte": "./timelines/TimelineItemVertical.svelte",
195
197
  "./toasts/Toast.svelte": "./toasts/Toast.svelte",
196
- "./tooltips/LightTooltip.svelte": "./tooltips/LightTooltip.svelte",
197
198
  "./tooltips/Tooltip.svelte": "./tooltips/Tooltip.svelte",
198
199
  "./types": "./types.js",
200
+ "./utils/clickOutside": "./utils/clickOutside.js",
199
201
  "./utils/generateId": "./utils/generateId.js"
200
202
  },
201
203
  "svelte": "./index.js"
@@ -2,21 +2,22 @@
2
2
  export let divClass = 'relative overflow-x-auto shadow-md sm:rounded-lg';
3
3
  export let tableClass = 'w-full text-sm text-left text-gray-500 dark:text-gray-400';
4
4
  export let theadClass = 'text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400';
5
+ export let thClass = 'px-6 py-3';
5
6
  </script>
6
7
 
7
8
  <div class={divClass}>
8
- <table class={tableClass}>
9
- <thead class={theadClass}>
10
- <tr>
11
- {#each header as column}
12
- <th scope="col" class="px-6 py-3">
13
- {column}
14
- </th>
15
- {/each}
16
- </tr>
17
- </thead>
18
- <tbody>
19
- <slot />
20
- </tbody>
21
- </table>
9
+ <table class={tableClass}>
10
+ <thead class={theadClass}>
11
+ <tr>
12
+ {#each header as column}
13
+ <th scope="col" class={thClass}>
14
+ {column}
15
+ </th>
16
+ {/each}
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <slot />
21
+ </tbody>
22
+ </table>
22
23
  </div>
@@ -5,6 +5,7 @@ declare const __propDef: {
5
5
  divClass?: string;
6
6
  tableClass?: string;
7
7
  theadClass?: string;
8
+ thClass?: string;
8
9
  };
9
10
  events: {
10
11
  [evt: string]: CustomEvent<any>;
@@ -1,113 +1,131 @@
1
- <script>export let tip;
2
- export let top = false;
3
- export let right = false;
4
- export let bottom = false;
5
- export let left = false;
6
- export let active = false;
1
+ <script>import classNames from 'classnames';
2
+ import { clickOutside } from '../utils/clickOutside';
3
+ import { computePosition, flip, shift, offset, autoPlacement, arrow as arrowFloat } from '@floating-ui/dom';
4
+ import { onDestroy } from 'svelte';
5
+ export let placement = 'top';
6
+ export let trigger = 'hover';
7
+ export let style = 'dark';
8
+ export let content = '';
9
+ export let animation = 'duration-300';
10
+ export let arrow = true;
11
+ let open = false;
12
+ const floatingPlacement = ({ placement }) => {
13
+ return placement === 'auto' ? undefined : placement;
14
+ };
15
+ const floatingArrowPlacement = ({ placement }) => {
16
+ if (!placement) {
17
+ return 'top';
18
+ }
19
+ return {
20
+ top: 'bottom',
21
+ right: 'left',
22
+ bottom: 'top',
23
+ left: 'right'
24
+ }[placement.split('-')[0]];
25
+ };
26
+ const floatingMiddleware = ({ arrowRef, placement }) => {
27
+ const middleware = [];
28
+ middleware.push(offset(8));
29
+ middleware.push(placement === 'auto' ? autoPlacement() : flip());
30
+ middleware.push(shift({ padding: 8 }));
31
+ if (arrowRef) {
32
+ middleware.push(arrowFloat({ element: arrowRef }));
33
+ }
34
+ return middleware;
35
+ };
36
+ let placementData;
37
+ let tooltipRef, triggerRef, arrowRef;
38
+ const updatePosition = () => computePosition(triggerRef, tooltipRef, {
39
+ middleware: floatingMiddleware({ arrowRef, placement }),
40
+ placement: floatingPlacement({ placement })
41
+ }).then((data) => (placementData = data));
42
+ let attachedScroll = false;
43
+ $: tooltipRef && open && updatePosition();
44
+ $: {
45
+ if (open && !attachedScroll) {
46
+ attachedScroll = true;
47
+ window.addEventListener('scroll', updatePosition, true);
48
+ }
49
+ else if (!open && attachedScroll) {
50
+ attachedScroll = false;
51
+ window.removeEventListener('scroll', updatePosition, true);
52
+ }
53
+ }
54
+ onDestroy(() => {
55
+ if (attachedScroll) {
56
+ attachedScroll = false;
57
+ window.removeEventListener('scroll', updatePosition, true);
58
+ }
59
+ });
7
60
  </script>
8
61
 
9
- <div class="tooltip-wrapper">
10
- <span class="tooltip-slot">
62
+ <svelte:window on:resize={() => open && updatePosition()} />
63
+
64
+ <div>
65
+ <div
66
+ class="w-fit"
67
+ bind:this={triggerRef}
68
+ on:mouseenter={() => {
69
+ if (trigger === 'hover') {
70
+ open = true;
71
+ }
72
+ }}
73
+ on:mouseleave={() => {
74
+ if (open && trigger === 'hover') {
75
+ open = false;
76
+ }
77
+ }}
78
+ on:click={() => {
79
+ if (trigger === 'click') {
80
+ open = !open;
81
+ }
82
+ }}
83
+ use:clickOutside={() => {
84
+ if (open) {
85
+ open = false;
86
+ }
87
+ }}
88
+ >
11
89
  <slot />
12
- </span>
13
- <div class="inline-block absolute invisible z-10 py-2 px-3 bg-gray-900 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip dark:bg-gray-700" class:active class:left class:right class:bottom class:top>
14
- {#if tip}
15
- <div class="text-sm font-medium text-white ">{tip}</div>
16
- {:else}
17
- <slot name="custom-tip" />
90
+ </div>
91
+
92
+ <div
93
+ bind:this={tooltipRef}
94
+ data-testid="tooltip"
95
+ class={classNames(
96
+ 'absolute inline-block rounded-lg py-2 px-3 text-sm font-medium shadow-sm',
97
+ animation !== false && `transition-opacity ${animation}`,
98
+ {
99
+ 'invisible opacity-0': !open,
100
+ 'bg-gray-900 text-white dark:bg-gray-700': style === 'dark',
101
+ 'border border-gray-200 bg-white text-gray-900': style === 'light',
102
+ 'border border-gray-200 bg-white text-gray-900 dark:border-none dark:bg-gray-700 dark:text-white':
103
+ style === 'auto'
104
+ },
105
+ $$props.class
106
+ )}
107
+ style={`left:${placementData?.x}px;top:${placementData?.y}px;position:${placementData?.strategy}`}
108
+ >
109
+ <div class="relative z-20">
110
+ <slot name="content">
111
+ {content}
112
+ </slot>
113
+ </div>
114
+ {#if arrow}
115
+ <div
116
+ class={classNames('absolute z-10 h-2 w-2 rotate-45', {
117
+ 'bg-gray-900 dark:bg-gray-700': style === 'dark',
118
+ 'bg-white': style === 'light',
119
+ 'bg-white dark:bg-gray-700': style === 'auto'
120
+ })}
121
+ data-testid="tooltip-arrow"
122
+ style={`left:${placementData?.middlewareData.arrow?.x}px;top:${
123
+ placementData?.middlewareData.arrow?.y
124
+ }px;${floatingArrowPlacement({ placement: placementData?.placement })}:-4px`}
125
+ bind:this={arrowRef}
126
+ >
127
+ &nbsp;
128
+ </div>
18
129
  {/if}
19
130
  </div>
20
131
  </div>
21
-
22
- <style>
23
- .tooltip-wrapper {
24
- position: relative;
25
- display: inline-block;
26
- }
27
- .tooltip {
28
- position: absolute;
29
- font-family: inherit;
30
- display: inline-block;
31
- white-space: nowrap;
32
- color: inherit;
33
- opacity: 0;
34
- visibility: hidden;
35
- transition: opacity 150ms, visibility 150ms;
36
- }
37
-
38
- .tooltip.top:after {
39
- content: '';
40
- position: absolute;
41
- top: 100%;
42
- left: 50%;
43
- margin-left: -10px;
44
- border-width: 5px;
45
- border-style: solid;
46
- border-color: rgb(55 65 81) transparent transparent transparent;
47
- }
48
- .tooltip.bottom::after {
49
- content: '';
50
- position: absolute;
51
- top: -30%;
52
- left: 50%;
53
- margin-left: -10px;
54
- border-width: 5px;
55
- border-style: solid;
56
- border-color: transparent transparent rgb(55 65 81) transparent;
57
- }
58
- .tooltip.right::after {
59
- content: '';
60
- position: absolute;
61
- /* vertically center */
62
- top: 50%;
63
- transform: translateY(-50%);
64
- /* position tooltip correctly */
65
- right: 100%;
66
- margin-left: -5px;
67
-
68
- border-width: 5px;
69
- border-style: solid;
70
- border-color: transparent rgb(55 65 81) transparent transparent;
71
- }
72
- .tooltip.left::after {
73
- content: '';
74
- position: absolute;
75
- /* vertically center */
76
- top: 50%;
77
- transform: translateY(-50%);
78
- /* position tooltip correctly */
79
- left: 100%;
80
- /* margin-left: -5px; */
81
- border-width: 5px;
82
- border-style: solid;
83
- border-color: transparent transparent transparent rgb(55 65 81);
84
- }
85
- .tooltip.top {
86
- left: 50%;
87
- transform: translate(-50%, -100%);
88
- margin-top: -8px;
89
- }
90
- .tooltip.bottom {
91
- left: 50%;
92
- bottom: 0px;
93
- transform: translate(-50%, 100%);
94
- /* margin-bottom: -px; */
95
- }
96
- .tooltip.left {
97
- left: 0;
98
- transform: translateX(-100%);
99
- margin-left: -8px;
100
- }
101
- .tooltip.right {
102
- right: 0;
103
- transform: translateX(100%);
104
- margin-right: 0px;
105
- }
106
- .tooltip.active {
107
- opacity: 1;
108
- visibility: initial;
109
- }
110
- .tooltip-slot:hover + .tooltip {
111
- opacity: 1;
112
- visibility: initial;
113
- }</style>
@@ -1,19 +1,21 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ import type { Placement } from '@floating-ui/dom';
2
3
  declare const __propDef: {
3
4
  props: {
4
- tip: string;
5
- top?: boolean;
6
- right?: boolean;
7
- bottom?: boolean;
8
- left?: boolean;
9
- active?: boolean;
5
+ [x: string]: any;
6
+ placement?: 'auto' | Placement;
7
+ trigger?: 'hover' | 'click';
8
+ style?: 'dark' | 'light' | 'auto';
9
+ content?: string;
10
+ animation?: false | `duration-${number}`;
11
+ arrow?: boolean;
10
12
  };
11
13
  events: {
12
14
  [evt: string]: CustomEvent<any>;
13
15
  };
14
16
  slots: {
15
17
  default: {};
16
- 'custom-tip': {};
18
+ content: {};
17
19
  };
18
20
  };
19
21
  export declare type TooltipProps = typeof __propDef.props;
@@ -0,0 +1,3 @@
1
+ export declare function clickOutside(node: HTMLElement, callback: () => void): {
2
+ destroy(): void;
3
+ };
@@ -0,0 +1,15 @@
1
+ export function clickOutside(node, callback) {
2
+ const handleClick = (event) => {
3
+ if (!event?.target)
4
+ return;
5
+ if (node && !node.contains(event.target) && !event.defaultPrevented) {
6
+ callback();
7
+ }
8
+ };
9
+ document.addEventListener('click', handleClick, true);
10
+ return {
11
+ destroy() {
12
+ document.removeEventListener('click', handleClick, true);
13
+ },
14
+ };
15
+ }
@@ -1,120 +0,0 @@
1
- <script>export let tip;
2
- export let top = false;
3
- export let right = false;
4
- export let bottom = false;
5
- export let left = false;
6
- export let active = false;
7
- </script>
8
-
9
- <div class="tooltip-wrapper">
10
- <span class="tooltip-slot">
11
- <slot />
12
- </span>
13
- <div
14
- class="inline-block absolute invisible z-10 py-2 px-3 bg-white rounded-lg border border-gray-200 shadow-sm opacity-0 tooltip"
15
- class:active
16
- class:left
17
- class:right
18
- class:bottom
19
- class:top
20
- >
21
- {#if tip}
22
- <div class="text-sm font-medium text-gray-900">{tip}</div>
23
- {:else}
24
- <slot name="custom-tip" />
25
- {/if}
26
- </div>
27
- </div>
28
-
29
- <style>
30
- .tooltip-wrapper {
31
- position: relative;
32
- display: inline-block;
33
- }
34
- .tooltip {
35
- position: absolute;
36
- font-family: inherit;
37
- display: inline-block;
38
- white-space: nowrap;
39
- color: inherit;
40
- opacity: 0;
41
- visibility: hidden;
42
- transition: opacity 150ms, visibility 150ms;
43
- }
44
-
45
- .tooltip.top:after {
46
- content: '';
47
- position: absolute;
48
- top: 100%;
49
- left: 50%;
50
- margin-left: -10px;
51
- border-width: 5px;
52
- border-style: solid;
53
- border-color: #ddd transparent transparent transparent;
54
- }
55
- .tooltip.bottom::after {
56
- content: '';
57
- position: absolute;
58
- top: -30%;
59
- left: 50%;
60
- margin-left: -10px;
61
- border-width: 5px;
62
- border-style: solid;
63
- border-color: transparent transparent #ddd transparent;
64
- }
65
- .tooltip.right::after {
66
- content: '';
67
- position: absolute;
68
- /* vertically center */
69
- top: 50%;
70
- transform: translateY(-50%);
71
- /* position tooltip correctly */
72
- right: 100%;
73
- margin-left: -5px;
74
-
75
- border-width: 5px;
76
- border-style: solid;
77
- border-color: transparent #ddd transparent transparent;
78
- }
79
- .tooltip.left::after {
80
- content: '';
81
- position: absolute;
82
- /* vertically center */
83
- top: 50%;
84
- transform: translateY(-50%);
85
- /* position tooltip correctly */
86
- left: 100%;
87
- /* margin-left: -5px; */
88
- border-width: 5px;
89
- border-style: solid;
90
- border-color: transparent transparent transparent #ddd;
91
- }
92
- .tooltip.top {
93
- left: 50%;
94
- transform: translate(-50%, -100%);
95
- margin-top: -8px;
96
- }
97
- .tooltip.bottom {
98
- left: 50%;
99
- bottom: 0px;
100
- transform: translate(-50%, 100%);
101
- /* margin-bottom: -px; */
102
- }
103
- .tooltip.left {
104
- left: 0;
105
- transform: translateX(-100%);
106
- margin-left: -8px;
107
- }
108
- .tooltip.right {
109
- right: 0;
110
- transform: translateX(100%);
111
- margin-right: 0px;
112
- }
113
- .tooltip.active {
114
- opacity: 1;
115
- visibility: initial;
116
- }
117
- .tooltip-slot:hover + .tooltip {
118
- opacity: 1;
119
- visibility: initial;
120
- }</style>
@@ -1,24 +0,0 @@
1
- import { SvelteComponentTyped } from "svelte";
2
- declare const __propDef: {
3
- props: {
4
- tip: string;
5
- top?: boolean;
6
- right?: boolean;
7
- bottom?: boolean;
8
- left?: boolean;
9
- active?: boolean;
10
- };
11
- events: {
12
- [evt: string]: CustomEvent<any>;
13
- };
14
- slots: {
15
- default: {};
16
- 'custom-tip': {};
17
- };
18
- };
19
- export declare type LightTooltipProps = typeof __propDef.props;
20
- export declare type LightTooltipEvents = typeof __propDef.events;
21
- export declare type LightTooltipSlots = typeof __propDef.slots;
22
- export default class LightTooltip extends SvelteComponentTyped<LightTooltipProps, LightTooltipEvents, LightTooltipSlots> {
23
- }
24
- export {};