drab 2.2.1 → 2.4.0
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/dist/components/Accordion.svelte +77 -69
- package/dist/components/Accordion.svelte.d.ts +67 -29
- package/dist/components/Tabs.svelte +52 -48
- package/dist/components/Tabs.svelte.d.ts +57 -27
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/package.json +2 -1
@@ -8,19 +8,24 @@ Displays a list of `details` elements.
|
|
8
8
|
@props
|
9
9
|
|
10
10
|
- `autoClose` - if `true`, other items close when a new one is opened
|
11
|
+
- `classContent` - class of all the `div`s that wrap the `content` slot
|
11
12
|
- `classDetails` - class of the `div` around each `details` element
|
12
|
-
- `
|
13
|
-
- `
|
14
|
-
- `classSummary` - class of all the `summary`
|
13
|
+
- `classHeader` - class of all the `summary` elements
|
14
|
+
- `classIcon` - class of the `div` that wrap the icon if displayed
|
15
|
+
- `classSummary` - class of all the `div`s that wrap the `summary` slot
|
15
16
|
- `class`
|
16
|
-
- `content` - array of `AccordionContent` elements
|
17
17
|
- `icon`
|
18
18
|
- `id`
|
19
|
+
- `items` - array of `AccordionItem` elements
|
19
20
|
- `transition` - rotates the icon, slides the content, defaults to empty object, set to false to remove
|
20
21
|
|
21
22
|
@slots
|
22
23
|
|
23
|
-
|
24
|
+
| name | purpose | default value | slot props |
|
25
|
+
| --------- | ----------------------------- | -------------- | --------------- |
|
26
|
+
| `summary` | summary element | `item.summary` | `item`, `index` |
|
27
|
+
| `icon` | icon element | `icon` prop | `item`, `index` |
|
28
|
+
| `content` | content of the accordion item | `item.content` | `item`, `index` |
|
24
29
|
|
25
30
|
@example
|
26
31
|
|
@@ -29,20 +34,43 @@ Pass components into the `content` prop if needed. `AccordionContent` has `summa
|
|
29
34
|
import { Accordion } from "drab";
|
30
35
|
</script>
|
31
36
|
|
32
|
-
<Accordion
|
33
|
-
|
34
|
-
{ summary: "Is it accessible?",
|
37
|
+
<Accordion
|
38
|
+
items={[
|
39
|
+
{ summary: "Is it accessible?", content: "Yes." },
|
35
40
|
{
|
36
41
|
summary: "Is it styled?",
|
37
|
-
|
42
|
+
content: "Nope, style with global styles.",
|
38
43
|
},
|
39
44
|
{
|
40
45
|
summary: "Is it animated?",
|
41
|
-
|
46
|
+
content: "Yes, with the transition prop.",
|
47
|
+
},
|
48
|
+
{ summary: "Does it work without Javascript?", content: "Yes." },
|
49
|
+
]}
|
50
|
+
>
|
51
|
+
<div slot="content" let:item let:index>
|
52
|
+
<span>{index + 1}.</span>
|
53
|
+
<span>{item.content}</span>
|
54
|
+
</div>
|
55
|
+
</Accordion>
|
56
|
+
|
57
|
+
<Accordion
|
58
|
+
items={[
|
59
|
+
{
|
60
|
+
summary: "A Component",
|
61
|
+
content: "Rendered only on this item.",
|
62
|
+
data: { component: FullscreenButton },
|
42
63
|
},
|
43
|
-
{ summary: "
|
64
|
+
{ summary: "Summary", content: "Some other content" },
|
44
65
|
]}
|
45
|
-
|
66
|
+
>
|
67
|
+
<svelte:fragment slot="content" let:item>
|
68
|
+
{item.content}
|
69
|
+
{#if item.data?.component}
|
70
|
+
<svelte:component this={item.data.component} />
|
71
|
+
{/if}
|
72
|
+
</svelte:fragment>
|
73
|
+
</Accordion>
|
46
74
|
```
|
47
75
|
-->
|
48
76
|
|
@@ -54,28 +82,21 @@ import { prefersReducedMotion } from "../util/accessibility";
|
|
54
82
|
let className = "";
|
55
83
|
export { className as class };
|
56
84
|
export let id = "";
|
57
|
-
export let
|
85
|
+
export let items;
|
58
86
|
export let icon = "";
|
59
87
|
export let classDetails = "";
|
88
|
+
export let classHeader = "";
|
60
89
|
export let classSummary = "";
|
61
|
-
export let
|
90
|
+
export let classContent = "";
|
62
91
|
export let classIcon = "";
|
63
92
|
export let transition = {};
|
64
93
|
export let autoClose = true;
|
65
94
|
let clientJs = false;
|
66
|
-
for (const item of content) {
|
67
|
-
if (!item.classContentDetails)
|
68
|
-
item.classContentDetails = "";
|
69
|
-
if (!item.classContentSlot)
|
70
|
-
item.classContentSlot = "";
|
71
|
-
if (!item.classContentSummary)
|
72
|
-
item.classContentSummary = "";
|
73
|
-
}
|
74
95
|
const toggleOpen = (i) => {
|
75
|
-
|
96
|
+
items[i].open = !items[i].open;
|
76
97
|
if (autoClose) {
|
77
|
-
for (let j = 0; j <
|
78
|
-
const item =
|
98
|
+
for (let j = 0; j < items.length; j++) {
|
99
|
+
const item = items[j];
|
79
100
|
if (j !== i)
|
80
101
|
item.open = false;
|
81
102
|
}
|
@@ -88,64 +109,51 @@ onMount(() => {
|
|
88
109
|
});
|
89
110
|
</script>
|
90
111
|
|
91
|
-
<div class="transition"></div>
|
92
|
-
|
93
112
|
<div class={className} {id}>
|
94
|
-
{#each
|
95
|
-
<div class=
|
96
|
-
<details bind:open>
|
113
|
+
{#each items as item, index}
|
114
|
+
<div class={classDetails}>
|
115
|
+
<details bind:open={item.open}>
|
97
116
|
<!-- svelte-ignore a11y-no-redundant-roles -->
|
98
117
|
<summary
|
99
118
|
role="button"
|
100
119
|
tabindex="0"
|
101
|
-
class={
|
102
|
-
on:click={(
|
103
|
-
e.preventDefault();
|
104
|
-
toggleOpen(i);
|
105
|
-
}}
|
120
|
+
class={classHeader}
|
121
|
+
on:click|preventDefault={() => toggleOpen(index)}
|
106
122
|
on:keydown={(e) => {
|
107
123
|
if (e.key === "Enter") {
|
108
124
|
e.preventDefault();
|
109
|
-
toggleOpen(
|
125
|
+
toggleOpen(index);
|
110
126
|
}
|
111
127
|
}}
|
112
128
|
>
|
113
|
-
{
|
114
|
-
<
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
129
|
+
<div class={classSummary}>
|
130
|
+
<slot name="summary" {item} {index}>{item.summary}</slot>
|
131
|
+
</div>
|
132
|
+
<slot name="icon" {item} {index}>
|
133
|
+
{#if icon}
|
134
|
+
<div
|
135
|
+
class={classIcon}
|
136
|
+
class:d-rotate-180={item.open}
|
137
|
+
class:d-transition={transition}
|
138
|
+
>
|
139
|
+
{#if typeof icon !== "string"}
|
140
|
+
<svelte:component this={icon} />
|
141
|
+
{:else}
|
142
|
+
<span>{icon}</span>
|
143
|
+
{/if}
|
144
|
+
</div>
|
145
|
+
{/if}
|
146
|
+
</slot>
|
131
147
|
</summary>
|
132
148
|
{#if !clientJs || !transition}
|
133
|
-
<div class={
|
134
|
-
|
135
|
-
<svelte:component this={slot} class={classContentSlot} />
|
136
|
-
{:else}
|
137
|
-
<div class={classContentSlot}>{slot}</div>
|
138
|
-
{/if}
|
149
|
+
<div class={classContent}>
|
150
|
+
<slot name="content" {item} {index}>{item.content}</slot>
|
139
151
|
</div>
|
140
152
|
{/if}
|
141
153
|
</details>
|
142
|
-
{#if clientJs && open && transition}
|
143
|
-
<div transition:slide={transition}
|
144
|
-
|
145
|
-
<svelte:component this={slot} class={classContentSlot} />
|
146
|
-
{:else}
|
147
|
-
<div class={classContentSlot}>{slot}</div>
|
148
|
-
{/if}
|
154
|
+
{#if clientJs && item.open && transition}
|
155
|
+
<div class={classContent} transition:slide={transition}>
|
156
|
+
<slot name="content" {item} {index}>{item.content}</slot>
|
149
157
|
</div>
|
150
158
|
{/if}
|
151
159
|
</div>
|
@@ -159,10 +167,10 @@ onMount(() => {
|
|
159
167
|
summary::-webkit-details-marker {
|
160
168
|
display: none;
|
161
169
|
}
|
162
|
-
.
|
170
|
+
.d-rotate-180 {
|
163
171
|
transform: rotate(180deg);
|
164
172
|
}
|
165
|
-
.
|
173
|
+
.d-transition {
|
166
174
|
transition-property: transform;
|
167
175
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
168
176
|
transition-duration: 150ms;
|
@@ -1,37 +1,47 @@
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
/** `summary` element class */
|
9
|
-
classContentSummary?: string;
|
10
|
-
/** content of the `slot` */
|
11
|
-
slot: string | ComponentType;
|
12
|
-
/** `slot` element class */
|
13
|
-
classContentSlot?: string;
|
14
|
-
/** controls whether the slotted content is displayed */
|
2
|
+
export interface AccordionItem<T = any> {
|
3
|
+
/** text summary of the item */
|
4
|
+
summary?: string;
|
5
|
+
/** text content of the item */
|
6
|
+
content?: string;
|
7
|
+
/** controls whether the content is displayed */
|
15
8
|
open?: boolean;
|
9
|
+
/** any data to pass back to the parent */
|
10
|
+
data?: T;
|
16
11
|
}
|
12
|
+
import { type ComponentType } from "svelte";
|
17
13
|
import { type SlideParams } from "svelte/transition";
|
18
14
|
declare const __propDef: {
|
19
15
|
props: {
|
20
16
|
class?: string | undefined;
|
21
17
|
id?: string | undefined;
|
22
|
-
/** array of `
|
18
|
+
/** array of `AccordionItem` elements */ items: AccordionItem[];
|
23
19
|
icon?: string | ComponentType | undefined;
|
24
20
|
/** class of the `div` around each `details` element */ classDetails?: string | undefined;
|
25
|
-
/** class of all the `summary` elements */
|
26
|
-
/** class of all the `
|
27
|
-
/** class of the `div`
|
21
|
+
/** class of all the `summary` elements */ classHeader?: string | undefined;
|
22
|
+
/** class of all the `div`s that wrap the `summary` slot */ classSummary?: string | undefined;
|
23
|
+
/** class of all the `div`s that wrap the `content` slot */ classContent?: string | undefined;
|
24
|
+
/** class of the `div` that wrap the icon if displayed */ classIcon?: string | undefined;
|
28
25
|
/** rotates the icon, slides the content, defaults to empty object, set to false to remove */ transition?: false | SlideParams | undefined;
|
29
26
|
/** if `true`, other items close when a new one is opened */ autoClose?: boolean | undefined;
|
30
27
|
};
|
31
28
|
events: {
|
32
29
|
[evt: string]: CustomEvent<any>;
|
33
30
|
};
|
34
|
-
slots: {
|
31
|
+
slots: {
|
32
|
+
summary: {
|
33
|
+
item: AccordionItem<any>;
|
34
|
+
index: any;
|
35
|
+
};
|
36
|
+
icon: {
|
37
|
+
item: AccordionItem<any>;
|
38
|
+
index: any;
|
39
|
+
};
|
40
|
+
content: {
|
41
|
+
item: AccordionItem<any>;
|
42
|
+
index: any;
|
43
|
+
};
|
44
|
+
};
|
35
45
|
};
|
36
46
|
export type AccordionProps = typeof __propDef.props;
|
37
47
|
export type AccordionEvents = typeof __propDef.events;
|
@@ -44,19 +54,24 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
44
54
|
* @props
|
45
55
|
*
|
46
56
|
* - `autoClose` - if `true`, other items close when a new one is opened
|
57
|
+
* - `classContent` - class of all the `div`s that wrap the `content` slot
|
47
58
|
* - `classDetails` - class of the `div` around each `details` element
|
48
|
-
* - `
|
49
|
-
* - `
|
50
|
-
* - `classSummary` - class of all the `summary`
|
59
|
+
* - `classHeader` - class of all the `summary` elements
|
60
|
+
* - `classIcon` - class of the `div` that wrap the icon if displayed
|
61
|
+
* - `classSummary` - class of all the `div`s that wrap the `summary` slot
|
51
62
|
* - `class`
|
52
|
-
* - `content` - array of `AccordionContent` elements
|
53
63
|
* - `icon`
|
54
64
|
* - `id`
|
65
|
+
* - `items` - array of `AccordionItem` elements
|
55
66
|
* - `transition` - rotates the icon, slides the content, defaults to empty object, set to false to remove
|
56
67
|
*
|
57
68
|
* @slots
|
58
69
|
*
|
59
|
-
*
|
70
|
+
* | name | purpose | default value | slot props |
|
71
|
+
* | --------- | ----------------------------- | -------------- | --------------- |
|
72
|
+
* | `summary` | summary element | `item.summary` | `item`, `index` |
|
73
|
+
* | `icon` | icon element | `icon` prop | `item`, `index` |
|
74
|
+
* | `content` | content of the accordion item | `item.content` | `item`, `index` |
|
60
75
|
*
|
61
76
|
* @example
|
62
77
|
*
|
@@ -66,19 +81,42 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
66
81
|
* </script>
|
67
82
|
*
|
68
83
|
* <Accordion
|
69
|
-
*
|
70
|
-
* { summary: "Is it accessible?",
|
84
|
+
* items={[
|
85
|
+
* { summary: "Is it accessible?", content: "Yes." },
|
71
86
|
* {
|
72
87
|
* summary: "Is it styled?",
|
73
|
-
*
|
88
|
+
* content: "Nope, style with global styles.",
|
74
89
|
* },
|
75
90
|
* {
|
76
91
|
* summary: "Is it animated?",
|
77
|
-
*
|
92
|
+
* content: "Yes, with the transition prop.",
|
93
|
+
* },
|
94
|
+
* { summary: "Does it work without Javascript?", content: "Yes." },
|
95
|
+
* ]}
|
96
|
+
* >
|
97
|
+
* <div slot="content" let:item let:index>
|
98
|
+
* <span>{index + 1}.</span>
|
99
|
+
* <span>{item.content}</span>
|
100
|
+
* </div>
|
101
|
+
* </Accordion>
|
102
|
+
*
|
103
|
+
* <Accordion
|
104
|
+
* items={[
|
105
|
+
* {
|
106
|
+
* summary: "A Component",
|
107
|
+
* content: "Rendered only on this item.",
|
108
|
+
* data: { component: FullscreenButton },
|
78
109
|
* },
|
79
|
-
* { summary: "
|
110
|
+
* { summary: "Summary", content: "Some other content" },
|
80
111
|
* ]}
|
81
|
-
*
|
112
|
+
* >
|
113
|
+
* <svelte:fragment slot="content" let:item>
|
114
|
+
* {item.content}
|
115
|
+
* {#if item.data?.component}
|
116
|
+
* <svelte:component this={item.data.component} />
|
117
|
+
* {/if}
|
118
|
+
* </svelte:fragment>
|
119
|
+
* </Accordion>
|
82
120
|
* ```
|
83
121
|
*/
|
84
122
|
export default class Accordion extends SvelteComponent<AccordionProps, AccordionEvents, AccordionSlots> {
|
@@ -3,100 +3,104 @@
|
|
3
3
|
|
4
4
|
### Tabs
|
5
5
|
|
6
|
-
Displays tabs and
|
6
|
+
Displays tabs and the active tab's content.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
10
|
-
- `
|
11
|
-
- `
|
12
|
-
- `classButton` - `button` class
|
10
|
+
- `activeIndex` - index of active tab, defaults to 0
|
11
|
+
- `classContent` - class of `div` that wraps the slotted content
|
13
12
|
- `classHeader` - class of the `div` that wraps the `button`s
|
14
13
|
- `classNoscript` - `noscript` class
|
15
|
-
- `
|
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
|
16
17
|
- `class`
|
17
|
-
- `content` - array of `TabContent` elements
|
18
18
|
- `id`
|
19
|
-
- `
|
19
|
+
- `tabs` - array of tabs
|
20
20
|
|
21
21
|
@slots
|
22
22
|
|
23
|
-
|
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` |
|
24
27
|
|
25
28
|
@example
|
26
29
|
|
27
30
|
```svelte
|
28
31
|
<script>
|
29
32
|
import { Tabs } from "drab";
|
30
|
-
import { FullscreenButton } from "drab";
|
31
33
|
</script>
|
32
34
|
|
33
|
-
<Tabs
|
34
|
-
|
35
|
-
{ name: "
|
35
|
+
<Tabs
|
36
|
+
items={[
|
37
|
+
{ name: "Tab 1", content: "Content 1" },
|
38
|
+
{ name: "Tab 2", content: "Content 2" },
|
36
39
|
]}
|
37
40
|
/>
|
41
|
+
|
42
|
+
<Tabs
|
43
|
+
tabs={[
|
44
|
+
{ title: "Tab", content: "Content 1" },
|
45
|
+
{
|
46
|
+
title: "Tab",
|
47
|
+
content: "A tab with a component",
|
48
|
+
data: { component: FullscreenButton },
|
49
|
+
},
|
50
|
+
]}
|
51
|
+
let:activeTab
|
52
|
+
>
|
53
|
+
<svelte:fragment slot="title" let:item let:index>
|
54
|
+
{item.title}
|
55
|
+
{index + 1}
|
56
|
+
</svelte:fragment>
|
57
|
+
<div>{activeTab.content}</div>
|
58
|
+
{#if activeTab.data?.component}
|
59
|
+
<svelte:component this={activeTab.data.component} />
|
60
|
+
{/if}
|
61
|
+
</Tabs>
|
38
62
|
```
|
39
63
|
-->
|
40
64
|
|
41
65
|
<script context="module"></script>
|
42
66
|
|
43
67
|
<script>import { onMount } from "svelte";
|
44
|
-
import { fade } from "svelte/transition";
|
45
68
|
import { messageNoScript } from "../util/messages";
|
46
69
|
let className = "";
|
47
70
|
export { className as class };
|
48
71
|
export let id = "";
|
49
72
|
export let classHeader = "";
|
50
|
-
export let
|
51
|
-
export let
|
52
|
-
export let
|
73
|
+
export let classTitle = "";
|
74
|
+
export let classTitleActive = "";
|
75
|
+
export let classTitleInactive = "";
|
53
76
|
export let classNoscript = "";
|
54
|
-
export let
|
55
|
-
export let
|
56
|
-
export let
|
57
|
-
const fadeTransition = transition ? transition : { duration: 0 };
|
77
|
+
export let classContent = "";
|
78
|
+
export let tabs;
|
79
|
+
export let activeIndex = 0;
|
58
80
|
let clientJs = false;
|
59
|
-
let activeIndex = 0;
|
60
|
-
for (const item of content) {
|
61
|
-
if (!item.classContentSlot)
|
62
|
-
item.classContentSlot = "";
|
63
|
-
}
|
64
81
|
$:
|
65
|
-
activeTab =
|
82
|
+
activeTab = tabs[activeIndex];
|
66
83
|
onMount(() => clientJs = true);
|
67
84
|
</script>
|
68
85
|
|
69
86
|
<div class={className} {id}>
|
70
87
|
<div class={classHeader}>
|
71
|
-
{#each
|
88
|
+
{#each tabs as item, index}
|
72
89
|
<button
|
73
90
|
disabled={!clientJs}
|
74
|
-
class="{
|
75
|
-
?
|
76
|
-
: ''} {activeIndex !==
|
77
|
-
on:click={() => (activeIndex =
|
91
|
+
class="{classTitle} {activeIndex === index
|
92
|
+
? classTitleActive
|
93
|
+
: ''} {activeIndex !== index ? classTitleInactive : ''}"
|
94
|
+
on:click={() => (activeIndex = index)}
|
78
95
|
>
|
79
|
-
{
|
96
|
+
<slot name="title" {item} {index}>{item.title}</slot>
|
80
97
|
</button>
|
81
98
|
{/each}
|
82
99
|
</div>
|
83
|
-
<div class={
|
84
|
-
{
|
85
|
-
<div in:fade={fadeTransition}>
|
86
|
-
<svelte:component
|
87
|
-
this={activeTab.slot}
|
88
|
-
class={activeTab.classContentSlot}
|
89
|
-
/>
|
90
|
-
</div>
|
91
|
-
{:else}
|
92
|
-
<div in:fade={fadeTransition} class={activeTab.classContentSlot}>
|
93
|
-
{activeTab.slot}
|
94
|
-
</div>
|
95
|
-
{/if}
|
100
|
+
<div class={classContent}>
|
101
|
+
<slot {activeTab}>{activeTab.content}</slot>
|
96
102
|
</div>
|
97
103
|
<noscript>
|
98
|
-
<div class={classNoscript}>
|
99
|
-
{messageNoScript}
|
100
|
-
</div>
|
104
|
+
<div class={classNoscript}>{messageNoScript}</div>
|
101
105
|
</noscript>
|
102
106
|
</div>
|
@@ -1,31 +1,37 @@
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
name: string;
|
2
|
+
export interface TabsTab<T = any> {
|
3
|
+
/** tab title, displayed in `button` element */
|
4
|
+
title?: string;
|
6
5
|
/** slotted content, displayed once tab is clicked */
|
7
|
-
|
8
|
-
/**
|
9
|
-
|
6
|
+
content?: string;
|
7
|
+
/** any data to pass back to the parent */
|
8
|
+
data?: T;
|
10
9
|
}
|
11
|
-
import { type FadeParams } from "svelte/transition";
|
12
10
|
declare const __propDef: {
|
13
11
|
props: {
|
14
12
|
class?: string | undefined;
|
15
13
|
id?: string | undefined;
|
16
14
|
/** class of the `div` that wraps the `button`s */ classHeader?: string | undefined;
|
17
|
-
/** `button`
|
18
|
-
/** class of the active tab's `button` */
|
19
|
-
/** class of all the inactive tabs' `button`s */
|
15
|
+
/** class of all title `button`s */ classTitle?: string | undefined;
|
16
|
+
/** class of the active tab's `button` */ classTitleActive?: string | undefined;
|
17
|
+
/** class of all the inactive tabs' `button`s */ classTitleInactive?: string | undefined;
|
20
18
|
/** `noscript` class */ classNoscript?: string | undefined;
|
21
|
-
/** class of `div` that wraps the slotted content */
|
22
|
-
/** array of
|
23
|
-
/**
|
19
|
+
/** class of `div` that wraps the slotted content */ classContent?: string | undefined;
|
20
|
+
/** array of tabs */ tabs: TabsTab[];
|
21
|
+
/** index of active tab, defaults to 0 */ activeIndex?: number | undefined;
|
24
22
|
};
|
25
23
|
events: {
|
26
24
|
[evt: string]: CustomEvent<any>;
|
27
25
|
};
|
28
|
-
slots: {
|
26
|
+
slots: {
|
27
|
+
title: {
|
28
|
+
item: TabsTab<any>;
|
29
|
+
index: any;
|
30
|
+
};
|
31
|
+
default: {
|
32
|
+
activeTab: TabsTab<any>;
|
33
|
+
};
|
34
|
+
};
|
29
35
|
};
|
30
36
|
export type TabsProps = typeof __propDef.props;
|
31
37
|
export type TabsEvents = typeof __propDef.events;
|
@@ -33,38 +39,62 @@ export type TabsSlots = typeof __propDef.slots;
|
|
33
39
|
/**
|
34
40
|
* ### Tabs
|
35
41
|
*
|
36
|
-
* Displays tabs and
|
42
|
+
* Displays tabs and the active tab's content.
|
37
43
|
*
|
38
44
|
* @props
|
39
45
|
*
|
40
|
-
* - `
|
41
|
-
* - `
|
42
|
-
* - `classButton` - `button` class
|
46
|
+
* - `activeIndex` - index of active tab, defaults to 0
|
47
|
+
* - `classContent` - class of `div` that wraps the slotted content
|
43
48
|
* - `classHeader` - class of the `div` that wraps the `button`s
|
44
49
|
* - `classNoscript` - `noscript` class
|
45
|
-
* - `
|
50
|
+
* - `classTitleActive` - class of the active tab's `button`
|
51
|
+
* - `classTitleInactive` - class of all the inactive tabs' `button`s
|
52
|
+
* - `classTitle` - class of all title `button`s
|
46
53
|
* - `class`
|
47
|
-
* - `content` - array of `TabContent` elements
|
48
54
|
* - `id`
|
49
|
-
* - `
|
55
|
+
* - `tabs` - array of tabs
|
50
56
|
*
|
51
57
|
* @slots
|
52
58
|
*
|
53
|
-
*
|
59
|
+
* | name | purpose | default value | slot props |
|
60
|
+
* | --------- | --------------------- | -------------------- | --------------- |
|
61
|
+
* | `default` | active item's content | `activeItem.content` | `activeItem` |
|
62
|
+
* | `title` | title of each tab | `item.title` | `item`, `index` |
|
54
63
|
*
|
55
64
|
* @example
|
56
65
|
*
|
57
66
|
* ```svelte
|
58
67
|
* <script>
|
59
68
|
* import { Tabs } from "drab";
|
60
|
-
* import { FullscreenButton } from "drab";
|
61
69
|
* </script>
|
62
70
|
*
|
63
|
-
* <Tabs
|
64
|
-
*
|
65
|
-
* { name: "
|
71
|
+
* <Tabs
|
72
|
+
* items={[
|
73
|
+
* { name: "Tab 1", content: "Content 1" },
|
74
|
+
* { name: "Tab 2", content: "Content 2" },
|
66
75
|
* ]}
|
67
76
|
* />
|
77
|
+
*
|
78
|
+
* <Tabs
|
79
|
+
* tabs={[
|
80
|
+
* { title: "Tab", content: "Content 1" },
|
81
|
+
* {
|
82
|
+
* title: "Tab",
|
83
|
+
* content: "A tab with a component",
|
84
|
+
* data: { component: FullscreenButton },
|
85
|
+
* },
|
86
|
+
* ]}
|
87
|
+
* let:activeTab
|
88
|
+
* >
|
89
|
+
* <svelte:fragment slot="title" let:item let:index>
|
90
|
+
* {item.title}
|
91
|
+
* {index + 1}
|
92
|
+
* </svelte:fragment>
|
93
|
+
* <div>{activeTab.content}</div>
|
94
|
+
* {#if activeTab.data?.component}
|
95
|
+
* <svelte:component this={activeTab.data.component} />
|
96
|
+
* {/if}
|
97
|
+
* </Tabs>
|
68
98
|
* ```
|
69
99
|
*/
|
70
100
|
export default class Tabs extends SvelteComponent<TabsProps, TabsEvents, TabsSlots> {
|
package/dist/index.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import Accordion from "./components/Accordion.svelte";
|
2
|
-
import type {
|
2
|
+
import type { AccordionItem } from "./components/Accordion.svelte";
|
3
3
|
import Chord from "./components/Chord.svelte";
|
4
4
|
import type { ChordNote } from "./components/Chord.svelte";
|
5
5
|
import ContextMenu from "./components/ContextMenu.svelte";
|
@@ -11,5 +11,7 @@ import type { EditorContentElement } from "./components/Editor.svelte";
|
|
11
11
|
import FullscreenButton from "./components/FullscreenButton.svelte";
|
12
12
|
import Popover from "./components/Popover.svelte";
|
13
13
|
import ShareButton from "./components/ShareButton.svelte";
|
14
|
+
import Tabs from "./components/Tabs.svelte";
|
15
|
+
import type { TabsTab } from "./components/Tabs.svelte";
|
14
16
|
import YouTube from "./components/YouTube.svelte";
|
15
|
-
export { Accordion, type
|
17
|
+
export { Accordion, type AccordionItem, Chord, type ChordNote, ContextMenu, CopyButton, DataTable, type DataTableRow, Editor, type EditorContentElement, FullscreenButton, Popover, ShareButton, Tabs, type TabsTab, YouTube, };
|
package/dist/index.js
CHANGED
@@ -7,5 +7,6 @@ import Editor from "./components/Editor.svelte";
|
|
7
7
|
import FullscreenButton from "./components/FullscreenButton.svelte";
|
8
8
|
import Popover from "./components/Popover.svelte";
|
9
9
|
import ShareButton from "./components/ShareButton.svelte";
|
10
|
+
import Tabs from "./components/Tabs.svelte";
|
10
11
|
import YouTube from "./components/YouTube.svelte";
|
11
|
-
export { Accordion, Chord, ContextMenu, CopyButton, DataTable, Editor, FullscreenButton, Popover, ShareButton, YouTube, };
|
12
|
+
export { Accordion, Chord, ContextMenu, CopyButton, DataTable, Editor, FullscreenButton, Popover, ShareButton, Tabs, YouTube, };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "drab",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.4.0",
|
4
4
|
"description": "An unstyled Svelte component library",
|
5
5
|
"keywords": [
|
6
6
|
"components",
|
@@ -15,6 +15,7 @@
|
|
15
15
|
"Fullscreen",
|
16
16
|
"Popover",
|
17
17
|
"Share",
|
18
|
+
"Tabs",
|
18
19
|
"YouTube"
|
19
20
|
],
|
20
21
|
"homepage": "https://drab.robino.dev",
|