flowbite-svelte 0.22.20 → 0.22.23

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,27 @@
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.22.23](https://github.com/themesberg/flowbite-svelte/compare/v0.22.22...v0.22.23) (2022-07-29)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * minor fixes / fine tuning ([57c1cf7](https://github.com/themesberg/flowbite-svelte/commit/57c1cf7f1bd461c417be1fd925766c045d72c015))
11
+
12
+ ### [0.22.22](https://github.com/themesberg/flowbite-svelte/compare/v0.22.21...v0.22.22) (2022-07-28)
13
+
14
+
15
+ ### Features
16
+
17
+ * focus trap for modals ([08604ac](https://github.com/themesberg/flowbite-svelte/commit/08604ac3475f28a5a35c037e47ecfc13ee13b877))
18
+
19
+ ### [0.22.21](https://github.com/themesberg/flowbite-svelte/compare/v0.22.20...v0.22.21) (2022-07-28)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * megamenu centered in small screen ([713aa9a](https://github.com/themesberg/flowbite-svelte/commit/713aa9ab5d1c390291bb61910f9eae4b68d5981e))
25
+
5
26
  ### [0.22.20](https://github.com/themesberg/flowbite-svelte/compare/v0.22.19...v0.22.20) (2022-07-28)
6
27
 
7
28
  ### [0.22.19](https://github.com/themesberg/flowbite-svelte/compare/v0.22.17...v0.22.19) (2022-07-27)
@@ -1,7 +1,9 @@
1
- <script>import classNames from 'classnames';
1
+ <script>import { setContext } from 'svelte';
2
+ import classNames from 'classnames';
2
3
  import { createEventDispatcher } from 'svelte';
3
4
  import CloseButton from '../utils/CloseButton.svelte';
4
5
  const dispatch = createEventDispatcher();
6
+ setContext('background', true);
5
7
  export let color = 'blue';
6
8
  export let icon = null;
7
9
  export let dismissable = false;
@@ -48,13 +50,11 @@ const textColors = {
48
50
  dark: 'text-gray-700 dark:text-gray-300'
49
51
  };
50
52
  let divClass;
51
- $: divClass = classNames('flex flex-col p-4 mb-4 gap-2 ', bgClasses[color] ?? bgClasses.blue, accent && (borderAccentClasses[color] ?? borderAccentClasses.blue), rounded && 'rounded-lg ', accent && 'border-t-4 ', $$props.class);
52
- let textColor;
53
- $: textColor = textColors[color] ?? textColors.blue;
53
+ $: divClass = classNames('flex flex-col p-4 mb-4 gap-2 ', bgClasses[color] ?? bgClasses.blue, accent && (borderAccentClasses[color] ?? borderAccentClasses.blue), rounded && 'rounded-lg ', accent && 'border-t-4 ', textColors[color], $$props.class);
54
54
  </script>
55
55
 
56
56
  <div id={$$props.id} class:hidden class={divClass} role="alert">
57
- <div class="flex items-center {textColor}">
57
+ <div class="flex items-center">
58
58
  {#if icon}
59
59
  <svelte:component this={icon} class="flex-shrink-0 w-5 h-5 mr-3" />
60
60
  {/if}
@@ -37,6 +37,7 @@ $: {
37
37
  type="checkbox"
38
38
  bind:checked
39
39
  on:click
40
+ on:change
40
41
  {value}
41
42
  {...$$restProps}
42
43
  class={inputClass(custom, color, true, background, $$slots.default || $$props.class)}
@@ -12,6 +12,7 @@ declare const __propDef: {
12
12
  };
13
13
  events: {
14
14
  click: MouseEvent;
15
+ change: Event;
15
16
  } & {
16
17
  [evt: string]: CustomEvent<any>;
17
18
  };
@@ -26,7 +26,7 @@ let divClass;
26
26
  $: divClass = classNames(common, background ? 'dark:bg-gray-600 dark:border-gray-500' : 'dark:bg-gray-700 dark:border-gray-600', colors[$$restProps.color ?? 'blue'], sizes[size], 'relative');
27
27
  </script>
28
28
 
29
- <Checkbox custom {...$$restProps} class={$$props.class} {value} bind:checked bind:group on:click>
29
+ <Checkbox custom {...$$restProps} class={$$props.class} {value} bind:checked bind:group on:click on:change>
30
30
  <div class={divClass} />
31
31
  <slot />
32
32
  </Checkbox>
@@ -9,6 +9,7 @@ declare const __propDef: {
9
9
  };
10
10
  events: {
11
11
  click: MouseEvent;
12
+ change: Event;
12
13
  } & {
13
14
  [evt: string]: CustomEvent<any>;
14
15
  };
@@ -6,7 +6,7 @@ setContext('background', true);
6
6
  let wrapperClass;
7
7
  $: wrapperClass = classNames('border-gray-100 shadow-md dark:border-gray-700', full ? 'border-y' : 'rounded-lg border', full ? 'bg-white dark:bg-gray-800' : 'bg-white dark:bg-gray-700', $$props.class);
8
8
  let ulClass;
9
- $: ulClass = classNames('grid grid-flow-row gap-y-4 md:gap-x-0 auto-col-max auto-row-max', full && $$slots.extra ? 'sm:grid-cols-2' : 'sm:grid-cols-2 md:grid-cols-3', 'text-sm font-medium', 'text-gray-500 dark:text-gray-400', full && $$slots.extra && 'md:w-2/3');
9
+ $: ulClass = classNames('grid grid-flow-row gap-y-4 md:gap-x-0 auto-col-max auto-row-max', full && $$slots.extra ? 'grid-cols-2' : 'grid-cols-2 md:grid-cols-3', 'text-sm font-medium', 'text-gray-500 dark:text-gray-400', full && $$slots.extra && 'md:w-2/3');
10
10
  function init(node) {
11
11
  if (full) {
12
12
  node.parentElement.classList.add('inset-x-0');
@@ -1,6 +1,7 @@
1
1
  <script>import { createEventDispatcher } from 'svelte';
2
2
  import { setContext } from 'svelte';
3
3
  import CloseButton from '../utils/CloseButton.svelte';
4
+ import focusTrap from '../utils/focusTrap';
4
5
  export let open = false;
5
6
  export let title = undefined;
6
7
  export let size = 'md';
@@ -18,15 +19,14 @@ const allPlacementClasses = [
18
19
  'items-end'
19
20
  ];
20
21
  let backdropEl;
21
- function init(node, _visible) {
22
+ function init(node, _open) {
22
23
  getPlacementClasses().map((c) => node.classList.add(c));
23
- if (_visible)
24
- createBackdrop(node);
24
+ _open && createBackdrop(node);
25
25
  return {
26
- update(_visible) {
26
+ update(_open) {
27
27
  allPlacementClasses.map((c) => node.classList.remove(c));
28
28
  getPlacementClasses().map((c) => node.classList.add(c));
29
- _visible ? createBackdrop(node) : destroyBackdrop(node);
29
+ _open ? createBackdrop(node) : destroyBackdrop(node);
30
30
  },
31
31
  destroy() {
32
32
  destroyBackdrop(node);
@@ -44,17 +44,17 @@ function createBackdrop(node) {
44
44
  const body = document.querySelector('body');
45
45
  body.append(backdropEl);
46
46
  body.style.overflow = 'hidden';
47
- body.addEventListener('keydown', handleEscape, true);
47
+ document.addEventListener('keydown', handleEscape, true);
48
48
  }
49
49
  dispatch('show', node);
50
50
  }
51
51
  function destroyBackdrop(node) {
52
52
  const body = document.querySelector('body');
53
53
  body.style.overflow = 'auto';
54
- body.removeEventListener('keydown', handleEscape, true);
55
54
  if (backdropEl)
56
55
  backdropEl.remove();
57
56
  backdropEl = undefined;
57
+ document.removeEventListener('keydown', handleEscape, true);
58
58
  dispatch('hide', node);
59
59
  }
60
60
  function getPlacementClasses() {
@@ -110,6 +110,7 @@ function hide() {
110
110
  aria-modal={open ? 'true' : undefined}
111
111
  role={open ? 'dialog' : undefined}
112
112
  use:init={open}
113
+ use:focusTrap={open}
113
114
  on:click={onButtonsClick}
114
115
  >
115
116
  <div class="relative p-4 w-full {sizes[size]} h-full md:h-auto">
@@ -1,5 +1,5 @@
1
1
  <script>import { clickOutside } from '../utils/clickOutside';
2
- export let liButtonClass = 'flex items-center';
2
+ export let liButtonClass = 'flex items-center justify-between w-full';
3
3
  export let name;
4
4
  export let child = [];
5
5
  let hidden = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowbite-svelte",
3
- "version": "0.22.20",
3
+ "version": "0.22.23",
4
4
  "description": "Flowbite components for Svelte",
5
5
  "main": "index.js",
6
6
  "author": {
@@ -236,6 +236,7 @@
236
236
  "./utils/CloseButton.svelte": "./utils/CloseButton.svelte",
237
237
  "./utils/OptsButton.svelte": "./utils/OptsButton.svelte",
238
238
  "./utils/clickOutside": "./utils/clickOutside.js",
239
+ "./utils/focusTrap": "./utils/focusTrap.js",
239
240
  "./utils/generateId": "./utils/generateId.js"
240
241
  },
241
242
  "svelte": "./index.js"
@@ -0,0 +1,61 @@
1
+ //
2
+ // Focus trap copied from https://uxdesign.cc/how-to-trap-focus-inside-modal-to-make-it-ada-compliant-6a50f9a70700
3
+ //
4
+
5
+ // add all the elements inside modal which you want to make focusable
6
+ const focusableElements =
7
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
8
+
9
+ function getFocusable(node) {
10
+ const focusableContent = node.querySelectorAll(focusableElements);
11
+ return [focusableContent[0], focusableContent[focusableContent.length - 1]];
12
+ }
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
+ };
61
+ }