drab 2.8.3 → 2.8.5
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/README.md +67 -67
- package/dist/components/Breakpoint.svelte +9 -13
- package/dist/components/Chord.svelte +30 -32
- package/dist/components/Chord.svelte.d.ts +8 -9
- package/dist/components/ContextMenu.svelte +75 -75
- package/dist/components/CopyButton.svelte +5 -5
- package/dist/components/DataTable.svelte +133 -158
- package/dist/components/DataTable.svelte.d.ts +51 -44
- package/dist/components/Details.svelte +103 -0
- package/dist/components/Details.svelte.d.ts +69 -0
- package/dist/components/Editor.svelte +33 -44
- package/dist/components/Editor.svelte.d.ts +16 -24
- package/dist/components/FullscreenButton.svelte +14 -19
- package/dist/components/FullscreenButton.svelte.d.ts +0 -2
- package/dist/components/Popover.svelte +63 -63
- package/dist/components/ShareButton.svelte +41 -44
- package/dist/components/Sheet.svelte +100 -100
- package/dist/components/Tabs.svelte +84 -107
- package/dist/components/Tabs.svelte.d.ts +52 -55
- package/dist/components/YouTube.svelte +9 -9
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/package.json +82 -82
- package/dist/components/Accordion.svelte +0 -189
- package/dist/components/Accordion.svelte.d.ts +0 -135
- package/dist/util/messages.d.ts +0 -1
- package/dist/util/messages.js +0 -1
@@ -1,108 +1,117 @@
|
|
1
|
-
<!--
|
2
|
-
@component
|
3
|
-
|
4
|
-
### DataTable
|
5
|
-
|
6
|
-
Data table to display an array of JS objects. Provides sorting and
|
7
|
-
|
8
|
-
@props
|
1
|
+
<!--
|
2
|
+
@component
|
3
|
+
|
4
|
+
### DataTable
|
5
|
+
|
6
|
+
Data table to display an array of JS objects. Provides pagination and sorting for `number`, `string`, `boolean`, and `Date`. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
|
7
|
+
|
8
|
+
@props
|
9
9
|
|
10
10
|
- `ascending` - current sort order
|
11
|
-
- `classButton` - `button` class
|
12
|
-
- `classFooter` - footer class
|
13
|
-
- `classNoscript` - `noscript` class
|
14
|
-
- `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
|
15
|
-
- `classTable` - `table` class
|
16
11
|
- `classTbodyTr` - `tbody tr` class
|
17
12
|
- `classTbody` - `tbody` class
|
18
|
-
- `classTdSorted` - currently sorted `td`
|
19
13
|
- `classTd` - `td` class
|
20
|
-
- `classThSorted` - currently sorted `th`
|
21
14
|
- `classTh` - `th` class
|
22
15
|
- `classTheadTr` - `thead tr` class
|
23
16
|
- `classThead` - `thead` class
|
24
17
|
- `classTr` - `tr` class
|
25
18
|
- `class`
|
26
|
-
- `currentPage` - current page, defaults to `
|
27
|
-
- `data` -
|
28
|
-
- `idTable` - `table` id
|
19
|
+
- `currentPage` - current page index, defaults to `0`
|
20
|
+
- `data` - an array of items to render in the table
|
29
21
|
- `id`
|
30
|
-
- `keys` - table columns to include in the table, in order
|
22
|
+
- `keys` - table columns to include in the table, in order. Defaults to first item's keys
|
31
23
|
- `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
|
32
24
|
- `sortBy` - key (column) to sort by, defaults to first key
|
33
25
|
|
34
|
-
@slots
|
35
|
-
|
36
|
-
| name
|
37
|
-
|
|
38
|
-
| `
|
39
|
-
| `
|
40
|
-
| `
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
@example
|
26
|
+
@slots
|
27
|
+
|
28
|
+
| name | purpose | default value | slot props |
|
29
|
+
| ---------- | ----------------------------------------------------- | ------------- | ------------------------------- |
|
30
|
+
| `controls` | helper that passes back `maxRows` and `numberOfPages` | none | `maxRows`, `numberOfPages` |
|
31
|
+
| `td` | td contents | `value` | `item`, `key`, `sortBy` `value` |
|
32
|
+
| `th` | th contents | `key` | `key`, `sortBy` |
|
33
|
+
|
34
|
+
@example
|
45
35
|
|
46
36
|
```svelte
|
47
|
-
<script lang="ts">
|
48
|
-
import {
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
{ make: "
|
55
|
-
{ make: "
|
56
|
-
{ make: "
|
57
|
-
{ make: "
|
58
|
-
{ make: "
|
59
|
-
{ make: "
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
37
|
+
<script lang="ts">
|
38
|
+
import type { ComponentProps } from "svelte";
|
39
|
+
import { DataTable } from "drab";
|
40
|
+
|
41
|
+
let currentPage = 0;
|
42
|
+
|
43
|
+
const data: ComponentProps<DataTable>["data"] = [
|
44
|
+
{ make: "Honda", model: "CR-V", year: 2011, awd: true },
|
45
|
+
{ make: "Volvo", model: "XC-40", year: 2024, awd: true },
|
46
|
+
{ make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
|
47
|
+
{ make: "Chevrolet", model: "Silverado", year: 2022, awd: true },
|
48
|
+
{ make: "Ford", model: "Model A", year: 1931, awd: false },
|
49
|
+
{ make: "Subaru", model: "Outback", year: 2021, awd: true },
|
50
|
+
{ make: "Ford", model: "Bronco", year: 1970, awd: true },
|
51
|
+
{ make: "GMC", model: "Acadia", year: 2008, awd: true },
|
52
|
+
{ make: "BMW", model: "X3", year: 2023, awd: true },
|
53
|
+
];
|
54
|
+
</script>
|
55
|
+
|
56
|
+
<DataTable {data} class="mb-12" />
|
57
|
+
|
58
|
+
<DataTable
|
59
|
+
{data}
|
60
|
+
bind:currentPage
|
61
|
+
sortBy="year"
|
62
|
+
maxRows={4}
|
63
|
+
class="tabular-nums"
|
64
|
+
classTh="cursor-pointer capitalize"
|
65
|
+
classTbodyTr="transition hover:bg-neutral-50"
|
66
|
+
>
|
67
|
+
<svelte:fragment slot="th" let:key let:sortBy>
|
68
|
+
<span class:uppercase={key === "awd"} class:underline={key === sortBy}>
|
69
|
+
{key}
|
70
|
+
</span>
|
71
|
+
</svelte:fragment>
|
72
|
+
<svelte:fragment slot="td" let:value>
|
73
|
+
{#if typeof value === "boolean"}
|
74
|
+
{value ? "Yes" : "No"}
|
75
|
+
{:else}
|
76
|
+
{value}
|
77
|
+
{/if}
|
78
|
+
</svelte:fragment>
|
79
|
+
<svelte:fragment slot="controls" let:maxRows let:numberOfPages>
|
80
|
+
{#if maxRows}
|
81
|
+
<div class="flex items-center justify-between">
|
82
|
+
<div>{currentPage + 1} / {numberOfPages}</div>
|
83
|
+
<div>
|
84
|
+
<button
|
85
|
+
type="button"
|
86
|
+
class="btn"
|
87
|
+
disabled={currentPage < 1}
|
88
|
+
on:click={() => currentPage--}
|
89
|
+
>
|
90
|
+
Previous
|
91
|
+
</button>
|
92
|
+
<button
|
93
|
+
type="button"
|
94
|
+
class="btn"
|
95
|
+
disabled={currentPage >= numberOfPages - 1}
|
96
|
+
on:click={() => currentPage++}
|
97
|
+
>
|
98
|
+
Next
|
99
|
+
</button>
|
100
|
+
</div>
|
101
|
+
</div>
|
102
|
+
{/if}
|
103
|
+
</svelte:fragment>
|
104
|
+
</DataTable>
|
87
105
|
```
|
88
|
-
-->
|
89
|
-
|
90
|
-
<script
|
91
|
-
|
92
|
-
<script>import { onMount } from "svelte";
|
93
|
-
import { messageNoScript } from "../util/messages";
|
94
|
-
let className = "";
|
106
|
+
-->
|
107
|
+
|
108
|
+
<script>let className = "";
|
95
109
|
export { className as class };
|
96
110
|
export let id = "";
|
97
111
|
export let data;
|
98
|
-
export let keys = [];
|
99
|
-
if (!keys.length && data[0]) {
|
100
|
-
keys = Object.keys(data[0]);
|
101
|
-
}
|
112
|
+
export let keys = Object.keys(data[0]);
|
102
113
|
export let sortBy = keys[0];
|
103
114
|
export let ascending = true;
|
104
|
-
export let classTable = "";
|
105
|
-
export let idTable = "";
|
106
115
|
export let classThead = "";
|
107
116
|
export let classTbody = "";
|
108
117
|
export let classTr = "";
|
@@ -110,15 +119,8 @@ export let classTheadTr = "";
|
|
110
119
|
export let classTbodyTr = "";
|
111
120
|
export let classTh = "";
|
112
121
|
export let classTd = "";
|
113
|
-
export let classThSorted = "";
|
114
|
-
export let classTdSorted = "";
|
115
|
-
export let classButton = "";
|
116
|
-
export let classFooter = "";
|
117
|
-
export let classPageControls = "";
|
118
122
|
export let maxRows = 0;
|
119
|
-
export let currentPage =
|
120
|
-
export let classNoscript = "";
|
121
|
-
let clientJs = false;
|
123
|
+
export let currentPage = 0;
|
122
124
|
$:
|
123
125
|
numberOfPages = Math.floor(data.length / maxRows) + 1;
|
124
126
|
const sort = (key, toggleAscending = true) => {
|
@@ -143,14 +145,19 @@ const sort = (key, toggleAscending = true) => {
|
|
143
145
|
} else {
|
144
146
|
return collator.compare(bVal, aVal);
|
145
147
|
}
|
146
|
-
} else if (
|
148
|
+
} else if (aVal instanceof Date && bVal instanceof Date) {
|
149
|
+
if (ascending) {
|
150
|
+
return aVal.getTime() - bVal.getTime();
|
151
|
+
} else {
|
152
|
+
return bVal.getTime() - aVal.getTime();
|
153
|
+
}
|
154
|
+
} else {
|
147
155
|
if (ascending) {
|
148
156
|
return aVal === bVal ? 0 : aVal ? -1 : 1;
|
149
157
|
} else {
|
150
158
|
return aVal === bVal ? 0 : aVal ? 1 : -1;
|
151
159
|
}
|
152
|
-
}
|
153
|
-
return 0;
|
160
|
+
}
|
154
161
|
});
|
155
162
|
data = data;
|
156
163
|
sortBy = key;
|
@@ -158,70 +165,38 @@ const sort = (key, toggleAscending = true) => {
|
|
158
165
|
const showRow = (i, currentPage2) => {
|
159
166
|
if (!maxRows)
|
160
167
|
return true;
|
161
|
-
const overMin = i >= maxRows *
|
162
|
-
const underMax = i < maxRows * currentPage2;
|
168
|
+
const overMin = i >= maxRows * currentPage2;
|
169
|
+
const underMax = i < maxRows * (currentPage2 + 1);
|
163
170
|
return overMin && underMax;
|
164
171
|
};
|
165
172
|
sort(sortBy, false);
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
<
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
{/each}
|
197
|
-
</tbody>
|
198
|
-
</table>
|
199
|
-
|
200
|
-
{#if maxRows}
|
201
|
-
<div class={classFooter}>
|
202
|
-
<slot name="pageNumber" {currentPage} {numberOfPages}>
|
203
|
-
<div>{currentPage} / {numberOfPages}</div>
|
204
|
-
</slot>
|
205
|
-
<div class={classPageControls}>
|
206
|
-
<button
|
207
|
-
type="button"
|
208
|
-
class={classButton}
|
209
|
-
disabled={!clientJs || currentPage < 2}
|
210
|
-
on:click={() => currentPage--}
|
211
|
-
>
|
212
|
-
<slot name="previous">Previous</slot>
|
213
|
-
</button>
|
214
|
-
<button
|
215
|
-
type="button"
|
216
|
-
class={classButton}
|
217
|
-
disabled={!clientJs || currentPage >= numberOfPages}
|
218
|
-
on:click={() => currentPage++}
|
219
|
-
>
|
220
|
-
<slot name="next">Next</slot>
|
221
|
-
</button>
|
222
|
-
</div>
|
223
|
-
</div>
|
224
|
-
|
225
|
-
<noscript><div class={classNoscript}>{messageNoScript}</div></noscript>
|
226
|
-
{/if}
|
227
|
-
</div>
|
173
|
+
</script>
|
174
|
+
|
175
|
+
<table class={className} {id}>
|
176
|
+
<thead class={classThead}>
|
177
|
+
<tr class="{classTr} {classTheadTr}">
|
178
|
+
{#each keys as key}
|
179
|
+
<th class={classTh} on:click={() => sort(key)}>
|
180
|
+
<slot name="th" {key} {sortBy}>{key}</slot>
|
181
|
+
</th>
|
182
|
+
{/each}
|
183
|
+
</tr>
|
184
|
+
</thead>
|
185
|
+
<tbody class={classTbody}>
|
186
|
+
{#each data as item, i}
|
187
|
+
{#if showRow(i, currentPage)}
|
188
|
+
<tr class="{classTr} {classTbodyTr}">
|
189
|
+
{#each keys as key}
|
190
|
+
<td class={classTd}>
|
191
|
+
<slot name="td" {item} {key} {sortBy} value={item[key]}>
|
192
|
+
{item[key]}
|
193
|
+
</slot>
|
194
|
+
</td>
|
195
|
+
{/each}
|
196
|
+
</tr>
|
197
|
+
{/if}
|
198
|
+
{/each}
|
199
|
+
</tbody>
|
200
|
+
</table>
|
201
|
+
|
202
|
+
<slot name="controls" {maxRows} {numberOfPages} />
|
@@ -1,15 +1,12 @@
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
2
|
-
export type DataTableItem = Record<string | number, string | number | boolean>;
|
3
2
|
declare const __propDef: {
|
4
3
|
props: {
|
5
4
|
class?: string | undefined;
|
6
5
|
id?: string | undefined;
|
7
|
-
/**
|
8
|
-
/** table columns to include in the table, in order */ keys?: string[] | undefined;
|
6
|
+
/** an array of items to render in the table */ data: Record<string | number, string | number | boolean | Date | null | undefined>[];
|
7
|
+
/** table columns to include in the table, in order. Defaults to first item's keys */ keys?: string[] | undefined;
|
9
8
|
/** key (column) to sort by, defaults to first key */ sortBy?: string | undefined;
|
10
9
|
/** current sort order */ ascending?: boolean | undefined;
|
11
|
-
/** `table` class */ classTable?: string | undefined;
|
12
|
-
/** `table` id */ idTable?: string | undefined;
|
13
10
|
/** `thead` class */ classThead?: string | undefined;
|
14
11
|
/** `tbody` class */ classTbody?: string | undefined;
|
15
12
|
/** `tr` class */ classTr?: string | undefined;
|
@@ -17,14 +14,8 @@ declare const __propDef: {
|
|
17
14
|
/** `tbody tr` class */ classTbodyTr?: string | undefined;
|
18
15
|
/** `th` class */ classTh?: string | undefined;
|
19
16
|
/** `td` class */ classTd?: string | undefined;
|
20
|
-
/** currently sorted `th` */ classThSorted?: string | undefined;
|
21
|
-
/** currently sorted `td` */ classTdSorted?: string | undefined;
|
22
|
-
/** `button` class */ classButton?: string | undefined;
|
23
|
-
/** footer class */ classFooter?: string | undefined;
|
24
|
-
/** class of `div` that wraps the "Previous" and "Next" buttons */ classPageControls?: string | undefined;
|
25
17
|
/** maximum number of rows to show on each page, defaults to `0` - no pagination */ maxRows?: number | undefined;
|
26
|
-
/** current page, defaults to `
|
27
|
-
/** `noscript` class */ classNoscript?: string | undefined;
|
18
|
+
/** current page index, defaults to `0` */ currentPage?: number | undefined;
|
28
19
|
};
|
29
20
|
events: {
|
30
21
|
[evt: string]: CustomEvent<any>;
|
@@ -35,17 +26,15 @@ declare const __propDef: {
|
|
35
26
|
sortBy: string;
|
36
27
|
};
|
37
28
|
td: {
|
38
|
-
item:
|
29
|
+
item: Record<string | number, string | number | boolean | Date | null | undefined>;
|
39
30
|
key: string;
|
40
31
|
sortBy: string;
|
41
|
-
value: string | number | boolean;
|
32
|
+
value: string | number | boolean | Date | null | undefined;
|
42
33
|
};
|
43
|
-
|
44
|
-
|
34
|
+
controls: {
|
35
|
+
maxRows: number;
|
45
36
|
numberOfPages: number;
|
46
37
|
};
|
47
|
-
previous: {};
|
48
|
-
next: {};
|
49
38
|
};
|
50
39
|
};
|
51
40
|
export type DataTableProps = typeof __propDef.props;
|
@@ -54,51 +43,44 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
54
43
|
/**
|
55
44
|
* ### DataTable
|
56
45
|
*
|
57
|
-
* Data table to display an array of JS objects. Provides sorting and
|
46
|
+
* Data table to display an array of JS objects. Provides pagination and sorting for `number`, `string`, `boolean`, and `Date`. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
|
58
47
|
*
|
59
48
|
* @props
|
60
49
|
*
|
61
50
|
* - `ascending` - current sort order
|
62
|
-
* - `classButton` - `button` class
|
63
|
-
* - `classFooter` - footer class
|
64
|
-
* - `classNoscript` - `noscript` class
|
65
|
-
* - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
|
66
|
-
* - `classTable` - `table` class
|
67
51
|
* - `classTbodyTr` - `tbody tr` class
|
68
52
|
* - `classTbody` - `tbody` class
|
69
|
-
* - `classTdSorted` - currently sorted `td`
|
70
53
|
* - `classTd` - `td` class
|
71
|
-
* - `classThSorted` - currently sorted `th`
|
72
54
|
* - `classTh` - `th` class
|
73
55
|
* - `classTheadTr` - `thead tr` class
|
74
56
|
* - `classThead` - `thead` class
|
75
57
|
* - `classTr` - `tr` class
|
76
58
|
* - `class`
|
77
|
-
* - `currentPage` - current page, defaults to `
|
78
|
-
* - `data` -
|
79
|
-
* - `idTable` - `table` id
|
59
|
+
* - `currentPage` - current page index, defaults to `0`
|
60
|
+
* - `data` - an array of items to render in the table
|
80
61
|
* - `id`
|
81
|
-
* - `keys` - table columns to include in the table, in order
|
62
|
+
* - `keys` - table columns to include in the table, in order. Defaults to first item's keys
|
82
63
|
* - `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
|
83
64
|
* - `sortBy` - key (column) to sort by, defaults to first key
|
84
65
|
*
|
85
66
|
* @slots
|
86
67
|
*
|
87
|
-
* | name
|
88
|
-
* |
|
89
|
-
* | `
|
90
|
-
* | `
|
91
|
-
* | `
|
92
|
-
* | `td` | td contents | `item[key]` | `item`, `key`, `sortBy` `value` |
|
93
|
-
* | `th` | th contents | `key` | `key`, `sortBy` |
|
68
|
+
* | name | purpose | default value | slot props |
|
69
|
+
* | ---------- | ----------------------------------------------------- | ------------- | ------------------------------- |
|
70
|
+
* | `controls` | helper that passes back `maxRows` and `numberOfPages` | none | `maxRows`, `numberOfPages` |
|
71
|
+
* | `td` | td contents | `value` | `item`, `key`, `sortBy` `value` |
|
72
|
+
* | `th` | th contents | `key` | `key`, `sortBy` |
|
94
73
|
*
|
95
74
|
* @example
|
96
75
|
*
|
97
76
|
* ```svelte
|
98
77
|
* <script lang="ts">
|
99
|
-
* import {
|
78
|
+
* import type { ComponentProps } from "svelte";
|
79
|
+
* import { DataTable } from "drab";
|
100
80
|
*
|
101
|
-
*
|
81
|
+
* let currentPage = 0;
|
82
|
+
*
|
83
|
+
* const data: ComponentProps<DataTable>["data"] = [
|
102
84
|
* { make: "Honda", model: "CR-V", year: 2011, awd: true },
|
103
85
|
* { make: "Volvo", model: "XC-40", year: 2024, awd: true },
|
104
86
|
* { make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
|
@@ -115,17 +97,17 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
115
97
|
*
|
116
98
|
* <DataTable
|
117
99
|
* {data}
|
100
|
+
* bind:currentPage
|
118
101
|
* sortBy="year"
|
119
102
|
* maxRows={4}
|
120
103
|
* class="tabular-nums"
|
121
104
|
* classTh="cursor-pointer capitalize"
|
122
|
-
* classThSorted="underline"
|
123
105
|
* classTbodyTr="transition hover:bg-neutral-50"
|
124
|
-
* classFooter="flex justify-between items-center"
|
125
|
-
* classButton="btn"
|
126
106
|
* >
|
127
|
-
* <svelte:fragment slot="th" let:key>
|
128
|
-
* <span class:uppercase={key === "awd"}
|
107
|
+
* <svelte:fragment slot="th" let:key let:sortBy>
|
108
|
+
* <span class:uppercase={key === "awd"} class:underline={key === sortBy}>
|
109
|
+
* {key}
|
110
|
+
* </span>
|
129
111
|
* </svelte:fragment>
|
130
112
|
* <svelte:fragment slot="td" let:value>
|
131
113
|
* {#if typeof value === "boolean"}
|
@@ -134,6 +116,31 @@ export type DataTableSlots = typeof __propDef.slots;
|
|
134
116
|
* {value}
|
135
117
|
* {/if}
|
136
118
|
* </svelte:fragment>
|
119
|
+
* <svelte:fragment slot="controls" let:maxRows let:numberOfPages>
|
120
|
+
* {#if maxRows}
|
121
|
+
* <div class="flex items-center justify-between">
|
122
|
+
* <div>{currentPage + 1} / {numberOfPages}</div>
|
123
|
+
* <div>
|
124
|
+
* <button
|
125
|
+
* type="button"
|
126
|
+
* class="btn"
|
127
|
+
* disabled={currentPage < 1}
|
128
|
+
* on:click={() => currentPage--}
|
129
|
+
* >
|
130
|
+
* Previous
|
131
|
+
* </button>
|
132
|
+
* <button
|
133
|
+
* type="button"
|
134
|
+
* class="btn"
|
135
|
+
* disabled={currentPage >= numberOfPages - 1}
|
136
|
+
* on:click={() => currentPage++}
|
137
|
+
* >
|
138
|
+
* Next
|
139
|
+
* </button>
|
140
|
+
* </div>
|
141
|
+
* </div>
|
142
|
+
* {/if}
|
143
|
+
* </svelte:fragment>
|
137
144
|
* </DataTable>
|
138
145
|
* ```
|
139
146
|
*/
|
@@ -0,0 +1,103 @@
|
|
1
|
+
<!--
|
2
|
+
@component
|
3
|
+
|
4
|
+
### Details
|
5
|
+
|
6
|
+
Displays a `details` element with helpful defaults and transitions. Can be used to make an accordion, or a collapse.
|
7
|
+
|
8
|
+
@props
|
9
|
+
|
10
|
+
- `class`
|
11
|
+
- `id`
|
12
|
+
- `open`
|
13
|
+
- `transition` - slides the content, set to `false` to remove
|
14
|
+
|
15
|
+
@slots
|
16
|
+
|
17
|
+
| name | purpose | default value | slot props |
|
18
|
+
| --------- | ------------------------------- | -------------- | ---------- |
|
19
|
+
| `summary` | `summary` element contents | none | `open` |
|
20
|
+
| `content` | contents when details is `open` | none | none |
|
21
|
+
|
22
|
+
@example
|
23
|
+
|
24
|
+
```svelte
|
25
|
+
<script lang="ts">
|
26
|
+
import { Details } from "drab";
|
27
|
+
import Chevron from "../../site/svg/Chevron.svelte";
|
28
|
+
</script>
|
29
|
+
|
30
|
+
<Details class="border-b">
|
31
|
+
<svelte:fragment slot="summary" let:open>
|
32
|
+
<div
|
33
|
+
class="flex cursor-pointer items-center justify-between gap-8 p-4 font-bold underline hover:decoration-dotted"
|
34
|
+
>
|
35
|
+
<div>Does it work without JavaScript?</div>
|
36
|
+
<div class="transition" class:rotate-180={open}>
|
37
|
+
<Chevron />
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</svelte:fragment>
|
41
|
+
<svelte:fragment slot="content">
|
42
|
+
<div class="px-4 pb-4">Yes.</div>
|
43
|
+
</svelte:fragment>
|
44
|
+
</Details>
|
45
|
+
```
|
46
|
+
-->
|
47
|
+
|
48
|
+
<script>import { onMount } from "svelte";
|
49
|
+
import { slide } from "svelte/transition";
|
50
|
+
import { prefersReducedMotion } from "../util/accessibility";
|
51
|
+
import { duration } from "../util/transition";
|
52
|
+
let className = "";
|
53
|
+
export { className as class };
|
54
|
+
export let id = "";
|
55
|
+
export let transition = { duration };
|
56
|
+
export let open = false;
|
57
|
+
let clientJs = false;
|
58
|
+
const toggleOpen = () => {
|
59
|
+
open = !open;
|
60
|
+
};
|
61
|
+
onMount(() => {
|
62
|
+
clientJs = true;
|
63
|
+
if (prefersReducedMotion())
|
64
|
+
transition = false;
|
65
|
+
});
|
66
|
+
</script>
|
67
|
+
|
68
|
+
<div class={className} {id}>
|
69
|
+
<details bind:open>
|
70
|
+
<!-- svelte-ignore a11y-no-redundant-roles -->
|
71
|
+
<summary
|
72
|
+
role="button"
|
73
|
+
tabindex="0"
|
74
|
+
on:click|preventDefault={toggleOpen}
|
75
|
+
on:keydown={(e) => {
|
76
|
+
if (e.key === "Enter") {
|
77
|
+
e.preventDefault();
|
78
|
+
toggleOpen();
|
79
|
+
}
|
80
|
+
}}
|
81
|
+
>
|
82
|
+
<slot name="summary" {open} />
|
83
|
+
</summary>
|
84
|
+
{#if !clientJs || !transition}
|
85
|
+
<slot name="content" />
|
86
|
+
{/if}
|
87
|
+
</details>
|
88
|
+
{#if clientJs && open && transition}
|
89
|
+
<!-- outside the details for the transition -->
|
90
|
+
<div transition:slide={transition}>
|
91
|
+
<slot name="content" />
|
92
|
+
</div>
|
93
|
+
{/if}
|
94
|
+
</div>
|
95
|
+
|
96
|
+
<style>
|
97
|
+
summary {
|
98
|
+
list-style: none;
|
99
|
+
}
|
100
|
+
summary::-webkit-details-marker {
|
101
|
+
display: none;
|
102
|
+
}
|
103
|
+
</style>
|