drab 2.6.0 → 2.6.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.
@@ -7,15 +7,12 @@ Displays a popover relatively positioned to the button.
7
7
 
8
8
  @props
9
9
 
10
- - `classButton` - `button` class
11
- - `classPopover` - popover class
12
10
  - `class`
13
11
  - `display` - if `eventType="click"`, controls the display
14
- - `eventType` - controls if hovering or clicking the button displays the popover
15
- - `idButton` - `button` id
16
- - `idPopover` - popover id
17
12
  - `id`
18
- - `position` - where the popover is displayed in relation to the button
13
+ - `position` - where the popover is displayed in relation to the target
14
+ - `target` - target element to position the popover in relation to
15
+ - `transition` - fades in and out, set to false to disable
19
16
 
20
17
  @slots
21
18
 
@@ -27,28 +24,27 @@ Displays a popover relatively positioned to the button.
27
24
  @example
28
25
 
29
26
  ```svelte
30
- <script>
27
+ <script lang="ts">
31
28
  import { Popover } from "drab";
29
+
30
+ let button: HTMLButtonElement;
31
+ let hoverButton: HTMLButtonElement;
32
+
33
+ let display = false;
32
34
  </script>
33
35
 
34
- <Popover classButton="btn" classPopover="p-2 transition">
35
- <span slot="button">Hover</span>
36
- <div class="card flex w-48 flex-col gap-2">
37
- <div class="font-bold">Bottom</div>
38
- <button class="btn">Button</button>
39
- <button class="btn">Button</button>
40
- <button class="btn">Button</button>
41
- </div>
42
- </Popover>
43
- <Popover
44
- classButton="btn"
45
- classPopover="p-2 transition"
46
- eventType="click"
47
- position="right"
36
+ <button
37
+ class="btn"
38
+ type="button"
39
+ bind:this={button}
40
+ on:click={() => (display = !display)}
48
41
  >
49
- <span slot="button">Click</span>
50
- <div class="card flex w-48 flex-col gap-2">
51
- <div class="font-bold">Right</div>
42
+ {display ? "Close" : "Open"}
43
+ </button>
44
+
45
+ <Popover target={button} bind:display class="p-2">
46
+ <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
47
+ <div class="font-bold">Bottom</div>
52
48
  <button class="btn">Button</button>
53
49
  <button class="btn">Button</button>
54
50
  <button class="btn">Button</button>
@@ -57,55 +53,49 @@ Displays a popover relatively positioned to the button.
57
53
  ```
58
54
  -->
59
55
 
60
- <script>import { onMount, tick } from "svelte";
56
+ <script>import { prefersReducedMotion } from "../util/accessibility";
57
+ import { duration } from "../util/transition";
58
+ import { onMount, tick } from "svelte";
59
+ import { fade } from "svelte/transition";
61
60
  let className = "";
62
61
  export { className as class };
63
62
  export let id = "";
64
- export let classButton = "";
65
- export let classPopover = "";
66
- export let idButton = "";
67
- export let idPopover = "";
68
- export let display = false;
63
+ export let display = true;
69
64
  export let position = "bottom";
70
- export let eventType = "hover";
71
- let clientEventType = "hover";
65
+ export let target;
66
+ export let transition = { duration };
72
67
  let popover;
73
- let button;
74
68
  let coordinates = { x: 0, y: 0 };
75
- const correctPosition = async () => {
69
+ const setPosition = async () => {
76
70
  if (position === "top" || position === "bottom") {
77
- coordinates.x = button.offsetWidth / 2 - popover.offsetWidth / 2;
71
+ coordinates.x = target.offsetWidth / 2 - popover.offsetWidth / 2;
78
72
  if (position === "top") {
79
73
  coordinates.y = -popover.offsetHeight;
80
74
  } else {
81
- coordinates.y = button.offsetHeight;
75
+ coordinates.y = target.offsetHeight;
82
76
  }
83
77
  } else {
84
- coordinates.y = button.offsetHeight / 2 - popover.offsetHeight / 2;
78
+ coordinates.y = target.offsetHeight / 2 - popover.offsetHeight / 2;
85
79
  if (position === "left") {
86
80
  coordinates.x = -popover.offsetWidth;
87
81
  } else {
88
- coordinates.x = button.offsetWidth;
82
+ coordinates.x = target.offsetWidth;
89
83
  }
90
84
  }
85
+ const targetRect = target.getBoundingClientRect();
86
+ coordinates.x += targetRect.x;
87
+ coordinates.y += targetRect.y;
91
88
  await tick();
92
- const rect = popover.getBoundingClientRect();
93
- if (rect.x < 0) {
94
- coordinates.x += Math.abs(rect.x);
95
- } else if (rect.x + popover.offsetWidth > window.innerWidth) {
96
- coordinates.x -= rect.x + popover.offsetWidth - window.innerWidth + 16;
89
+ const popoverRect = popover.getBoundingClientRect();
90
+ if (popoverRect.x < 0) {
91
+ coordinates.x += Math.abs(popoverRect.x);
92
+ } else if (popoverRect.x + popover.offsetWidth > window.innerWidth) {
93
+ coordinates.x -= popoverRect.x + popover.offsetWidth - window.innerWidth + 16;
97
94
  }
98
- if (rect.y < 0) {
99
- coordinates.y += Math.abs(rect.y);
100
- } else if (rect.y + popover.offsetHeight > window.innerHeight) {
101
- coordinates.y -= rect.y + popover.offsetHeight - window.innerHeight;
102
- }
103
- };
104
- const clickOutside = (e) => {
105
- if (popover && e.target instanceof HTMLElement) {
106
- if (!popover.contains(e.target)) {
107
- display = false;
108
- }
95
+ if (popoverRect.y < 0) {
96
+ coordinates.y += Math.abs(popoverRect.y);
97
+ } else if (popoverRect.y + popover.offsetHeight > window.innerHeight) {
98
+ coordinates.y -= popoverRect.y + popover.offsetHeight - window.innerHeight;
109
99
  }
110
100
  };
111
101
  const onKeyDown = (e) => {
@@ -113,58 +103,35 @@ const onKeyDown = (e) => {
113
103
  display = false;
114
104
  }
115
105
  };
116
- const openPopover = async (e) => {
117
- e.stopPropagation();
118
- display = true;
119
- };
106
+ $:
107
+ if (target && popover)
108
+ setPosition();
120
109
  onMount(() => {
121
- clientEventType = eventType;
122
- correctPosition();
110
+ if (prefersReducedMotion()) {
111
+ if (transition)
112
+ transition.duration = 0;
113
+ }
123
114
  });
124
115
  </script>
125
116
 
126
- <svelte:body on:keydown={onKeyDown} on:click={clickOutside} />
117
+ <svelte:body on:keydown={onKeyDown} />
127
118
 
128
- <div class="db-relative {className}" {id}>
129
- <button
130
- bind:this={button}
131
- id={idButton}
132
- class={classButton}
133
- on:click={openPopover}
134
- on:mouseover={correctPosition}
135
- on:focus={correctPosition}
136
- >
137
- <slot name="button">Open</slot>
138
- </button>
119
+ {#if display}
139
120
  <div
121
+ role="dialog"
140
122
  bind:this={popover}
141
- id={idPopover}
142
- class="db-popover {classPopover}"
143
- class:db-type-click={clientEventType === "click" && display}
144
- class:db-type-hover={clientEventType === "hover"}
123
+ class={className}
124
+ {id}
145
125
  style:top="{coordinates.y}px"
146
126
  style:left="{coordinates.x}px"
147
- inert={clientEventType === "hover" || display ? false : true}
127
+ transition:fade={transition ? transition : { duration: 0 }}
148
128
  >
149
129
  <slot>Popover</slot>
150
130
  </div>
151
- </div>
131
+ {/if}
152
132
 
153
133
  <style>
154
- .db-relative {
155
- position: relative;
156
- }
157
- .db-popover {
134
+ div {
158
135
  position: absolute;
159
- opacity: 0;
160
- z-index: -10;
161
- }
162
- button:hover + .db-type-hover,
163
- button:focus + .db-type-hover,
164
- .db-type-hover:hover,
165
- .db-type-hover:focus-within,
166
- .db-type-click {
167
- opacity: 1;
168
- z-index: 10;
169
136
  }
170
137
  </style>
@@ -1,21 +1,18 @@
1
1
  import { SvelteComponent } from "svelte";
2
+ import { type FadeParams } from "svelte/transition";
2
3
  declare const __propDef: {
3
4
  props: {
4
5
  class?: string | undefined;
5
6
  id?: string | undefined;
6
- /** `button` class */ classButton?: string | undefined;
7
- /** popover class */ classPopover?: string | undefined;
8
- /** `button` id */ idButton?: string | undefined;
9
- /** popover id */ idPopover?: string | undefined;
10
7
  /** if `eventType="click"`, controls the display */ display?: boolean | undefined;
11
- /** where the popover is displayed in relation to the button */ position?: "top" | "bottom" | "left" | "right" | undefined;
12
- /** controls if hovering or clicking the button displays the popover */ eventType?: ("click" | "hover") | undefined;
8
+ /** where the popover is displayed in relation to the target */ position?: "top" | "bottom" | "left" | "right" | undefined;
9
+ /** target element to position the popover in relation to */ target: HTMLElement;
10
+ /** fades in and out, set to false to disable */ transition?: false | FadeParams | undefined;
13
11
  };
14
12
  events: {
15
13
  [evt: string]: CustomEvent<any>;
16
14
  };
17
15
  slots: {
18
- button: {};
19
16
  default: {};
20
17
  };
21
18
  };
@@ -29,15 +26,12 @@ export type PopoverSlots = typeof __propDef.slots;
29
26
  *
30
27
  * @props
31
28
  *
32
- * - `classButton` - `button` class
33
- * - `classPopover` - popover class
34
29
  * - `class`
35
30
  * - `display` - if `eventType="click"`, controls the display
36
- * - `eventType` - controls if hovering or clicking the button displays the popover
37
- * - `idButton` - `button` id
38
- * - `idPopover` - popover id
39
31
  * - `id`
40
- * - `position` - where the popover is displayed in relation to the button
32
+ * - `position` - where the popover is displayed in relation to the target
33
+ * - `target` - target element to position the popover in relation to
34
+ * - `transition` - fades in and out, set to false to disable
41
35
  *
42
36
  * @slots
43
37
  *
@@ -49,28 +43,27 @@ export type PopoverSlots = typeof __propDef.slots;
49
43
  * @example
50
44
  *
51
45
  * ```svelte
52
- * <script>
46
+ * <script lang="ts">
53
47
  * import { Popover } from "drab";
48
+ *
49
+ * let button: HTMLButtonElement;
50
+ * let hoverButton: HTMLButtonElement;
51
+ *
52
+ * let display = false;
54
53
  * </script>
55
54
  *
56
- * <Popover classButton="btn" classPopover="p-2 transition">
57
- * <span slot="button">Hover</span>
58
- * <div class="card flex w-48 flex-col gap-2">
59
- * <div class="font-bold">Bottom</div>
60
- * <button class="btn">Button</button>
61
- * <button class="btn">Button</button>
62
- * <button class="btn">Button</button>
63
- * </div>
64
- * </Popover>
65
- * <Popover
66
- * classButton="btn"
67
- * classPopover="p-2 transition"
68
- * eventType="click"
69
- * position="right"
55
+ * <button
56
+ * class="btn"
57
+ * type="button"
58
+ * bind:this={button}
59
+ * on:click={() => (display = !display)}
70
60
  * >
71
- * <span slot="button">Click</span>
72
- * <div class="card flex w-48 flex-col gap-2">
73
- * <div class="font-bold">Right</div>
61
+ * {display ? "Close" : "Open"}
62
+ * </button>
63
+ *
64
+ * <Popover target={button} bind:display class="p-2">
65
+ * <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
66
+ * <div class="font-bold">Bottom</div>
74
67
  * <button class="btn">Button</button>
75
68
  * <button class="btn">Button</button>
76
69
  * <button class="btn">Button</button>
@@ -40,6 +40,7 @@ Uses the navigator api to share or copy a url link depending on browser support.
40
40
  -->
41
41
 
42
42
  <script>import { onMount } from "svelte";
43
+ import { delay } from "../util/delay";
43
44
  let className = "";
44
45
  export { className as class };
45
46
  export let id = "";
@@ -56,7 +57,7 @@ const onClick = async () => {
56
57
  } else {
57
58
  await navigator.clipboard.writeText(url);
58
59
  complete = true;
59
- setTimeout(() => complete = false, 800);
60
+ setTimeout(() => complete = false, delay);
60
61
  }
61
62
  } catch (error) {
62
63
  console.log(error);
@@ -65,7 +66,14 @@ const onClick = async () => {
65
66
  onMount(() => clientJs = true);
66
67
  </script>
67
68
 
68
- <button disabled={!clientJs} on:click={onClick} class={className} {id} {title}>
69
+ <button
70
+ type="button"
71
+ disabled={!clientJs}
72
+ on:click={onClick}
73
+ class={className}
74
+ {id}
75
+ {title}
76
+ >
69
77
  {#if complete}
70
78
  <slot name="complete">Copied</slot>
71
79
  {:else}
@@ -13,7 +13,7 @@ Creates a sheet element based on the `position` provided.
13
13
  - `id`
14
14
  - `onClickClose` - close on click, defaults to `false` - only closes if clicked outside
15
15
  - `position` - determines the position of sheet
16
- - `size` - size of sheet based on position - can also use css instead
16
+ - `size` - width/height of sheet based on the `side` - can also use css instead
17
17
  - `transitionSheet` - slides the sheet, set to `false` to remove
18
18
  - `transition` - fades the entire component, set to `false` to remove
19
19
 
@@ -28,22 +28,32 @@ Creates a sheet element based on the `position` provided.
28
28
  ```svelte
29
29
  <script lang="ts">
30
30
  import { Sheet } from "drab";
31
+ import { X } from "../../site/svg/X.svelte";
31
32
 
32
33
  let display = false;
33
34
  </script>
34
35
 
35
36
  <div>
36
- <button class="btn" on:click={() => (display = true)}>Open</button>
37
+ <button type="button" class="btn" on:click={() => (display = true)}>
38
+ Open
39
+ </button>
37
40
  </div>
38
41
 
39
42
  <Sheet
40
43
  bind:display
41
- class="bg-gray-50/80 backdrop-blur"
44
+ class="bg-neutral-50/80 backdrop-blur"
42
45
  classSheet="p-4 shadow bg-white"
43
46
  >
44
47
  <div class="mb-4 flex items-center justify-between">
45
- <div class="text-lg font-bold">Sheet</div>
46
- <button class="btn" on:click={() => (display = false)}>Close</button>
48
+ <h2 class="my-0">Sheet</h2>
49
+ <button
50
+ type="button"
51
+ title="Close"
52
+ class="btn btn-s"
53
+ on:click={() => (display = false)}
54
+ >
55
+ <X />
56
+ </button>
47
57
  </div>
48
58
  <div>
49
59
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
@@ -118,6 +128,7 @@ onMount(() => {
118
128
  {id}
119
129
  >
120
130
  <div
131
+ role="dialog"
121
132
  bind:this={sheet}
122
133
  transition:fly={transitionSheet ? transitionSheet : { duration: 0 }}
123
134
  style={position === "top" || position === "bottom"
@@ -138,7 +149,7 @@ onMount(() => {
138
149
  .d-backdrop {
139
150
  position: fixed;
140
151
  display: grid;
141
- z-index: 10;
152
+ z-index: 40;
142
153
  top: 0;
143
154
  bottom: 0;
144
155
  left: 0;
@@ -8,7 +8,7 @@ declare const __propDef: {
8
8
  /** controls whether the sheet is displayed*/ display?: boolean | undefined;
9
9
  /** fades the entire component, set to `false` to remove */ transition?: false | FadeParams | undefined;
10
10
  /** determines the position of sheet */ position?: "top" | "bottom" | "left" | "right" | undefined;
11
- /** size of sheet based on position - can also use css instead */ size?: number | undefined;
11
+ /** width/height of sheet based on the `side` - can also use css instead */ size?: number | undefined;
12
12
  /** slides the sheet, set to `false` to remove */ transitionSheet?: false | FlyParams | undefined;
13
13
  /** close on click, defaults to `false` - only closes if clicked outside */ onClickClose?: boolean | undefined;
14
14
  };
@@ -35,7 +35,7 @@ export type SheetSlots = typeof __propDef.slots;
35
35
  * - `id`
36
36
  * - `onClickClose` - close on click, defaults to `false` - only closes if clicked outside
37
37
  * - `position` - determines the position of sheet
38
- * - `size` - size of sheet based on position - can also use css instead
38
+ * - `size` - width/height of sheet based on the `side` - can also use css instead
39
39
  * - `transitionSheet` - slides the sheet, set to `false` to remove
40
40
  * - `transition` - fades the entire component, set to `false` to remove
41
41
  *
@@ -50,22 +50,32 @@ export type SheetSlots = typeof __propDef.slots;
50
50
  * ```svelte
51
51
  * <script lang="ts">
52
52
  * import { Sheet } from "drab";
53
+ * import { X } from "../../site/svg/X.svelte";
53
54
  *
54
55
  * let display = false;
55
56
  * </script>
56
57
  *
57
58
  * <div>
58
- * <button class="btn" on:click={() => (display = true)}>Open</button>
59
+ * <button type="button" class="btn" on:click={() => (display = true)}>
60
+ * Open
61
+ * </button>
59
62
  * </div>
60
63
  *
61
64
  * <Sheet
62
65
  * bind:display
63
- * class="bg-gray-50/80 backdrop-blur"
66
+ * class="bg-neutral-50/80 backdrop-blur"
64
67
  * classSheet="p-4 shadow bg-white"
65
68
  * >
66
69
  * <div class="mb-4 flex items-center justify-between">
67
- * <div class="text-lg font-bold">Sheet</div>
68
- * <button class="btn" on:click={() => (display = false)}>Close</button>
70
+ * <h2 class="my-0">Sheet</h2>
71
+ * <button
72
+ * type="button"
73
+ * title="Close"
74
+ * class="btn btn-s"
75
+ * on:click={() => (display = false)}
76
+ * >
77
+ * <X />
78
+ * </button>
69
79
  * </div>
70
80
  * <div>
71
81
  * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
@@ -7,23 +7,23 @@ Displays tabs and the active tab's content.
7
7
 
8
8
  @props
9
9
 
10
- - `activeIndex` - index of active tab, defaults to 0
11
- - `classContent` - class of `div` that wraps the slotted content
12
- - `classHeader` - class of the `div` that wraps the `button`s
13
10
  - `classNoscript` - `noscript` class
14
- - `classTitleActive` - class of the active tab's `button`
15
- - `classTitleInactive` - class of all the inactive tabs' `button`s
16
- - `classTitle` - class of all title `button`s
11
+ - `classTabActive` - class of the active tab's `button`
12
+ - `classTabInactive` - class of all the inactive tabs' `button`s
13
+ - `classTabList` - class of the `div` that wraps the `button`s
14
+ - `classTabPanel` - class of `div` that wraps the slotted content
15
+ - `classTab` - class of all title `button`s
17
16
  - `class`
18
17
  - `id`
18
+ - `selectedIndex` - index of selected tab, defaults to 0
19
19
  - `tabs` - array of tabs
20
20
 
21
21
  @slots
22
22
 
23
- | name | purpose | default value | slot props |
24
- | --------- | --------------------- | -------------------- | --------------- |
25
- | `default` | active item's content | `activeItem.content` | `activeItem` |
26
- | `title` | title of each tab | `item.title` | `item`, `index` |
23
+ | name | purpose | default value | slot props |
24
+ | --------- | --------------------- | ------------------ | --------------- |
25
+ | `default` | active item's content | `activeItem.panel` | `activeItem` |
26
+ | `tab` | title of each tab | `item.tab` | `item`, `index` |
27
27
 
28
28
  @example
29
29
 
@@ -34,40 +34,41 @@ Displays tabs and the active tab's content.
34
34
  </script>
35
35
 
36
36
  <Tabs
37
- classHeader="grid grid-flow-col grid-rows-1 gap-1 rounded bg-gray-200 p-1"
38
- classTitle="btn rounded-sm p-0.5"
39
- classTitleActive="bg-white text-gray-950"
40
- classTitleInactive="bg-gray-200 text-gray-500"
41
- classContent="py-2"
37
+ class="mb-4"
38
+ classTabList="grid grid-flow-col grid-rows-1 gap-1 rounded bg-neutral-200 p-1"
39
+ classTab="btn btn-s rounded-sm p-1"
40
+ classTabActive="bg-white text-neutral-950"
41
+ classTabInactive="bg-neutral-200 text-neutral-500"
42
+ classTabPanel="py-2"
42
43
  tabs={[
43
- { title: "Tab 1", content: "Content 1" },
44
- { title: "Tab 2", content: "Content 2" },
44
+ { tab: "Tab", panel: "Content" },
45
+ { tab: "Another Tab", panel: "Some more content" },
45
46
  ]}
46
47
  />
47
48
 
48
49
  <Tabs
49
- classHeader="grid grid-flow-col grid-rows-1 gap-1 rounded bg-gray-200 p-1"
50
- classTitle="btn rounded-sm p-0.5"
51
- classTitleActive="bg-white text-gray-950"
52
- classTitleInactive="bg-gray-200 text-gray-500"
53
- classContent="py-2"
50
+ classTabList="grid grid-flow-col grid-rows-1 gap-1 rounded bg-neutral-200 p-1"
51
+ classTab="btn btn-s rounded-sm p-1"
52
+ classTabActive="bg-white text-neutral-950"
53
+ classTabInactive="bg-neutral-200 text-neutral-500"
54
+ classTabPanel="py-2"
54
55
  tabs={[
55
- { title: "Tab", content: "Generated indexes" },
56
+ { tab: "Tab", panel: "Generated indexes" },
56
57
  {
57
- title: "Tab",
58
- content: "A tab with a component",
58
+ tab: "Tab",
59
+ panel: "A tab with a component",
59
60
  data: { component: FullscreenButton },
60
61
  },
61
62
  ]}
62
- let:activeTab
63
+ let:selectedTab
63
64
  >
64
- <svelte:fragment slot="title" let:item let:index>
65
- {item.title}
65
+ <svelte:fragment slot="tab" let:item let:index>
66
+ {item.tab}
66
67
  {index + 1}
67
68
  </svelte:fragment>
68
- <div>{activeTab.content}</div>
69
- {#if activeTab.data?.component}
70
- <svelte:component this={activeTab.data.component} class="btn" />
69
+ <div class="mb-2">{selectedTab.panel}</div>
70
+ {#if selectedTab.data?.component}
71
+ <svelte:component this={selectedTab.data.component} class="btn" />
71
72
  {/if}
72
73
  </Tabs>
73
74
  ```
@@ -80,36 +81,40 @@ import { messageNoScript } from "../util/messages";
80
81
  let className = "";
81
82
  export { className as class };
82
83
  export let id = "";
83
- export let classHeader = "";
84
- export let classTitle = "";
85
- export let classTitleActive = "";
86
- export let classTitleInactive = "";
84
+ export let classTabList = "";
85
+ export let classTab = "";
86
+ export let classTabActive = "";
87
+ export let classTabInactive = "";
87
88
  export let classNoscript = "";
88
- export let classContent = "";
89
+ export let classTabPanel = "";
89
90
  export let tabs;
90
- export let activeIndex = 0;
91
+ export let selectedIndex = 0;
91
92
  let clientJs = false;
92
93
  $:
93
- activeTab = tabs[activeIndex];
94
+ selectedTab = tabs[selectedIndex];
94
95
  onMount(() => clientJs = true);
95
96
  </script>
96
97
 
97
98
  <div class={className} {id}>
98
- <div class={classHeader}>
99
+ <div class={classTabList} role="tablist">
99
100
  {#each tabs as item, index}
100
101
  <button
102
+ role="tab"
103
+ tabindex={index === selectedIndex ? 0 : -1}
104
+ aria-selected={index === selectedIndex}
105
+ aria-controls="tabpanel"
101
106
  disabled={!clientJs}
102
- class="{classTitle} {activeIndex === index
103
- ? classTitleActive
104
- : ''} {activeIndex !== index ? classTitleInactive : ''}"
105
- on:click={() => (activeIndex = index)}
107
+ class="{classTab} {selectedIndex === index
108
+ ? classTabActive
109
+ : ''} {selectedIndex !== index ? classTabInactive : ''}"
110
+ on:click={() => (selectedIndex = index)}
106
111
  >
107
- <slot name="title" {item} {index}>{item.title}</slot>
112
+ <slot name="tab" {item} {index}>{item.tab}</slot>
108
113
  </button>
109
114
  {/each}
110
115
  </div>
111
- <div class={classContent}>
112
- <slot {activeTab}>{activeTab.content}</slot>
116
+ <div class={classTabPanel} role="tabpanel" id="tabpanel">
117
+ <slot {selectedTab}>{selectedTab.panel}</slot>
113
118
  </div>
114
119
  <noscript>
115
120
  <div class={classNoscript}>{messageNoScript}</div>