flowbite-svelte 0.26.31 → 0.27.1

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,32 @@
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.27.1](https://github.com/themesberg/flowbite-svelte/compare/v0.27.0...v0.27.1) (2022-09-24)
6
+
7
+
8
+ ### Features
9
+
10
+ * modal block background scroll ([f3eb627](https://github.com/themesberg/flowbite-svelte/commit/f3eb62732dc899d6f1483d9f86a5c644c8d2edd2))
11
+ * modal internal scrolling ([7ca08ea](https://github.com/themesberg/flowbite-svelte/commit/7ca08ea939e0116241c564738ec237bd501ca32c))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * placement and padding ([169c749](https://github.com/themesberg/flowbite-svelte/commit/169c749004d16d9b7c1aef46448608beefd3caf7))
17
+
18
+ ## [0.27.0](https://github.com/themesberg/flowbite-svelte/compare/v0.26.31...v0.27.0) (2022-09-24)
19
+
20
+
21
+ ### Features
22
+
23
+ * add server hooks to redirect component pages and add redirect.spec test ([9e2cb72](https://github.com/themesberg/flowbite-svelte/commit/9e2cb72653cb2de16f77c30d73bd69a69bd73bd5))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * add other dir ([dc5e73f](https://github.com/themesberg/flowbite-svelte/commit/dc5e73feaa44c3fc7f020967f2e342b08bafccdf))
29
+ * add redirect to all other directories ([6ca9ce0](https://github.com/themesberg/flowbite-svelte/commit/6ca9ce0c38c2a417fc1bcd88520e609a0e1b2b0e))
30
+
5
31
  ### [0.26.31](https://github.com/themesberg/flowbite-svelte/compare/v0.26.30...v0.26.31) (2022-09-23)
6
32
 
7
33
 
@@ -1,61 +1,53 @@
1
- <script>import Frame from '../utils/Frame.svelte';
1
+ <script>import classNames from 'classnames';
2
+ import Frame from '../utils/Frame.svelte';
2
3
  import { createEventDispatcher } from 'svelte';
3
4
  import CloseButton from '../utils/CloseButton.svelte';
4
5
  import focusTrap from '../utils/focusTrap';
5
6
  export let open = false;
6
- export let title = undefined;
7
+ export let title = '';
7
8
  export let size = 'md';
8
9
  export let placement = 'center';
9
10
  export let autoclose = true;
10
- export let backdropClasses = 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40';
11
+ export let backdropClasses = 'bg-gray-900 bg-opacity-50 dark:bg-opacity-80';
11
12
  const dispatch = createEventDispatcher();
12
- const allPlacementClasses = [
13
- 'justify-start',
14
- 'justify-center',
15
- 'justify-end',
16
- 'items-start',
17
- 'items-center',
18
- 'items-end'
19
- ];
20
- let backdropEl;
21
- const init = (node, _open) => {
22
- getPlacementClasses().map((c) => node.classList.add(c));
23
- _open && createBackdrop(node);
13
+ function blockEvent(e) {
14
+ e.preventDefault();
15
+ e.stopPropagation();
16
+ return false;
17
+ }
18
+ function contentInit(node) {
19
+ function keydownHandler(e) {
20
+ if (open && e.key === 'Escape')
21
+ return hide();
22
+ const target = e.target;
23
+ if (node.contains(target))
24
+ return true;
25
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp')
26
+ return blockEvent(e);
27
+ return true;
28
+ }
29
+ document.addEventListener('keydown', keydownHandler, { passive: false });
30
+ node.focus();
24
31
  return {
25
- update(_open) {
26
- allPlacementClasses.map((c) => node.classList.remove(c));
27
- getPlacementClasses().map((c) => node.classList.add(c));
28
- _open ? createBackdrop(node) : destroyBackdrop(node);
29
- },
30
32
  destroy() {
31
- destroyBackdrop(node);
33
+ document.removeEventListener('keydown', keydownHandler);
32
34
  }
33
35
  };
34
- };
35
- const handleEscape = (e) => {
36
- if (open && e.key === 'Escape')
37
- open = false;
38
- };
39
- const createBackdrop = (node) => {
40
- if (!backdropEl) {
41
- backdropEl = document.createElement('div');
42
- backdropEl.classList.add(...backdropClasses.split(' '));
43
- const body = document.querySelector('body');
44
- body.append(backdropEl);
45
- body.style.overflow = 'hidden';
46
- document.addEventListener('keydown', handleEscape, true);
36
+ }
37
+ function init(node) {
38
+ function preventScroll(e) {
39
+ if (e.target === node)
40
+ return blockEvent(e);
47
41
  }
42
+ node.addEventListener('wheel', preventScroll, { passive: false });
48
43
  dispatch('show', node);
49
- };
50
- const destroyBackdrop = (node) => {
51
- const body = document.querySelector('body');
52
- body.style.overflow = 'auto';
53
- if (backdropEl)
54
- backdropEl.remove();
55
- backdropEl = undefined;
56
- document.removeEventListener('keydown', handleEscape, true);
57
- dispatch('hide', node);
58
- };
44
+ return {
45
+ destroy() {
46
+ node.removeEventListener('wheel', preventScroll);
47
+ dispatch('hide', node);
48
+ }
49
+ };
50
+ }
59
51
  const getPlacementClasses = () => {
60
52
  switch (placement) {
61
53
  // top
@@ -90,53 +82,60 @@ const sizes = {
90
82
  lg: 'max-w-4xl',
91
83
  xl: 'max-w-7xl'
92
84
  };
93
- const onButtonsClick = ({ target }) => {
94
- if (autoclose && target.tagName === 'BUTTON')
85
+ const onAutoClose = (e) => {
86
+ const target = e.target;
87
+ if (autoclose && target?.tagName === 'BUTTON')
95
88
  open = !open;
96
89
  };
97
90
  const hide = () => {
98
91
  open = false;
99
92
  };
93
+ let mainClass;
94
+ $: mainClass = classNames('flex overflow-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full', backdropClasses, getPlacementClasses().join(' '), $$props.class);
100
95
  </script>
101
96
 
102
97
  <!-- Main modal -->
103
- <div
104
- tabindex="-1"
105
- class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 w-full md:inset-0 h-modal md:h-full"
106
- class:flex={open}
107
- class:hidden={!open}
108
- aria-hidden={open ? undefined : 'true'}
109
- aria-modal={open ? 'true' : undefined}
110
- role={open ? 'dialog' : undefined}
111
- use:init={open}
112
- use:focusTrap={open}
113
- on:click={onButtonsClick}>
114
- <div class="relative p-4 w-full {sizes[size]} h-full md:h-auto">
115
- <!-- Modal content -->
116
- <Frame rounded shadow class="relative">
117
- <!-- Modal header -->
118
- {#if $$slots.header || title}
119
- <div class="flex justify-between items-center p-4 rounded-t border-b dark:border-gray-600">
120
- <slot name="header">
121
- <h3 class="text-xl font-semibold text-gray-900 dark:text-white p-0">
122
- {title}
123
- </h3>
124
- </slot>
125
- <CloseButton name="Close modal" on:click={hide} />
126
- </div>
127
- {:else}
128
- <CloseButton name="Close modal" class="absolute top-3 right-2.5" on:click={hide} />
129
- {/if}
130
- <!-- Modal body -->
131
- <div class="p-6 space-y-6">
132
- <slot />
133
- </div>
134
- <!-- Modal footer -->
135
- {#if $$slots.footer}
136
- <div class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
137
- <slot name="footer" />
138
- </div>
139
- {/if}
140
- </Frame>
141
- </div>
142
- </div>
98
+ {#if open}
99
+ <div
100
+ tabindex="-1"
101
+ class={mainClass}
102
+ aria-modal="true"
103
+ role="dialog"
104
+ use:init
105
+ use:focusTrap
106
+ on:click={autoclose ? onAutoClose : null}>
107
+ <div class="flex p-4 w-full {sizes[size]} h-full md:h-auto max-h-screen">
108
+ <!-- Modal content -->
109
+ <Frame rounded shadow class="relative flex flex-col w-full h-full md:h-auto">
110
+ <!-- Modal header -->
111
+ {#if $$slots.header || title}
112
+ <div
113
+ class="flex justify-between items-center p-4 rounded-t border-b dark:border-gray-600">
114
+ <slot name="header">
115
+ <h3 class="text-xl font-semibold text-gray-900 dark:text-white p-0">
116
+ {title}
117
+ </h3>
118
+ </slot>
119
+ <CloseButton name="Close modal" on:click={hide} />
120
+ </div>
121
+ {:else}
122
+ <CloseButton name="Close modal" class="absolute top-3 right-2.5" on:click={hide} />
123
+ {/if}
124
+ <!-- Modal body -->
125
+ <div
126
+ class="p-6 space-y-6 flex-1 overflow-y-auto overscroll-contain"
127
+ tabindex="0"
128
+ use:contentInit>
129
+ <slot />
130
+ </div>
131
+ <!-- Modal footer -->
132
+ {#if $$slots.footer}
133
+ <div
134
+ class="flex items-center p-6 space-x-2 rounded-b border-t border-gray-200 dark:border-gray-600">
135
+ <slot name="footer" />
136
+ </div>
137
+ {/if}
138
+ </Frame>
139
+ </div>
140
+ </div>
141
+ {/if}
@@ -1,6 +1,7 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
+ [x: string]: any;
4
5
  open?: boolean | undefined;
5
6
  title?: string | undefined;
6
7
  size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowbite-svelte",
3
- "version": "0.26.31",
3
+ "version": "0.27.1",
4
4
  "description": "Flowbite components for Svelte",
5
5
  "main": "index.js",
6
6
  "author": {
@@ -1,4 +1,3 @@
1
- export default function focusTrap(node: any, _open: any): {
2
- update(_open: any): void;
1
+ export default function focusTrap(node: any): {
3
2
  destroy(): void;
4
3
  };
@@ -4,58 +4,45 @@
4
4
 
5
5
  // add all the elements inside modal which you want to make focusable
6
6
  const focusableElements =
7
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
7
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
8
8
 
9
9
  function getFocusable(node) {
10
- const focusableContent = node.querySelectorAll(focusableElements);
11
- return [focusableContent[0], focusableContent[focusableContent.length - 1]];
10
+ const focusableContent = node.querySelectorAll(focusableElements);
11
+ return [focusableContent[0], focusableContent[focusableContent.length - 1]];
12
12
  }
13
13
 
14
- export default function focusTrap(node, _open) {
15
- let firstFocusableElement, lastFocusableElement; // first and last element to be focused inside modal
16
-
17
- function handleFocusTrap(e) {
18
- let isTabPressed = e.key === 'Tab' || e.keyCode === 9;
19
-
20
- if (!isTabPressed) {
21
- return;
22
- }
23
-
24
- if (e.shiftKey) {
25
- // if shift key pressed for shift + tab combination
26
- if (document.activeElement === firstFocusableElement) {
27
- lastFocusableElement.focus(); // add focus for the last focusable element
28
- e.preventDefault();
29
- }
30
- } else {
31
- // if tab key is pressed
32
- if (document.activeElement === lastFocusableElement) {
33
- // if focused has reached to last focusable element then focus first focusable element after pressing tab
34
- firstFocusableElement.focus(); // add focus for the first focusable element
35
- e.preventDefault();
36
- }
37
- }
38
- }
39
-
40
- if (_open) {
41
- [firstFocusableElement, lastFocusableElement] = getFocusable(node);
42
- document.addEventListener('keydown', handleFocusTrap, true);
43
- firstFocusableElement.focus();
44
- }
45
-
46
- return {
47
- update(_open) {
48
- if (_open) {
49
- [firstFocusableElement, lastFocusableElement] = getFocusable(node);
50
- document.addEventListener('keydown', handleFocusTrap, true);
51
- firstFocusableElement.focus();
52
- } else {
53
- document.removeEventListener('keydown', handleFocusTrap, true);
54
- }
55
- },
56
-
57
- destroy() {
58
- document.removeEventListener('keydown', handleFocusTrap, true);
59
- }
60
- };
14
+ export default function focusTrap(node) {
15
+ let firstFocusableElement, lastFocusableElement; // first and last element to be focused inside modal
16
+
17
+ function handleFocusTrap(e) {
18
+ let isTabPressed = e.key === 'Tab' || e.keyCode === 9;
19
+
20
+ if (!isTabPressed) {
21
+ return;
22
+ }
23
+
24
+ if (e.shiftKey) {
25
+ // if shift key pressed for shift + tab combination
26
+ if (document.activeElement === firstFocusableElement) {
27
+ lastFocusableElement.focus(); // add focus for the last focusable element
28
+ e.preventDefault();
29
+ }
30
+ } else {
31
+ // if tab key is pressed
32
+ if (document.activeElement === lastFocusableElement) {
33
+ // if focused has reached to last focusable element then focus first focusable element after pressing tab
34
+ firstFocusableElement.focus(); // add focus for the first focusable element
35
+ e.preventDefault();
36
+ }
37
+ }
38
+ }
39
+
40
+ [firstFocusableElement, lastFocusableElement] = getFocusable(node);
41
+ document.addEventListener('keydown', handleFocusTrap, true);
42
+
43
+ return {
44
+ destroy() {
45
+ document.removeEventListener('keydown', handleFocusTrap, true);
46
+ }
47
+ };
61
48
  }