drab 2.8.2 → 2.8.4

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.
@@ -1,18 +1,17 @@
1
- <!--
2
- @component
3
-
4
- ### DataTable
5
-
6
- Data table to display an array of JS objects. Provides sorting and pagination. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
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
11
  - `classButton` - `button` class
12
12
  - `classFooter` - footer class
13
13
  - `classNoscript` - `noscript` class
14
14
  - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
15
- - `classPageNumber` - class of `div` wrapping page numbers
16
15
  - `classTable` - `table` class
17
16
  - `classTbodyTr` - `tbody tr` class
18
17
  - `classTbody` - `tbody` class
@@ -22,36 +21,33 @@ Data table to display an array of JS objects. Provides sorting and pagination. S
22
21
  - `classTh` - `th` class
23
22
  - `classTheadTr` - `thead tr` class
24
23
  - `classThead` - `thead` class
24
+ - `classTr` - `tr` class
25
25
  - `class`
26
- - `columns` - table columns, in order
27
26
  - `currentPage` - current page, defaults to `1`
28
27
  - `data` - a list of objects to render in the table
29
28
  - `idTable` - `table` id
30
29
  - `id`
30
+ - `keys` - table columns to include in the table, in order. Defaults to first item's keys
31
31
  - `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
32
- - `sortBy` - column to sort by, defaults to first column
33
- - `transition` - fades the rows in, set to `false` to disable
32
+ - `sortBy` - key (column) to sort by, defaults to first key
33
+
34
+ @slots
34
35
 
35
- @slots
36
-
37
- | name | purpose | default value | slot props |
38
- | ------------ | ------------------------ | -------------------------------- | ------------------------------ |
39
- | `next` | next button contents | `Next` | `currentPage` |
40
- | `pageNumber` | page numbers | `currentPage` / `numberOfPages` | `currentPage`, `numberOfPages` |
41
- | `previous` | previous button contents | `Previous` | `currentPage` |
42
- | `td` | td contents | `Previous` | `column`, `row` |
43
- | `th` | th contents | `Previous` | `column` |
44
-
45
- @example
36
+ | name | purpose | default value | slot props |
37
+ | ------------ | ------------------------ | ------------------------------- | ------------------------------- |
38
+ | `next` | next button contents | `Next` | |
39
+ | `pageNumber` | page numbers | `currentPage` / `numberOfPages` | `currentPage`, `numberOfPages` |
40
+ | `previous` | previous button contents | `Previous` | |
41
+ | `td` | td contents | `item[key]` | `item`, `key`, `sortBy` `value` |
42
+ | `th` | th contents | `key` | `key`, `sortBy` |
43
+
44
+ @example
46
45
 
47
46
  ```svelte
48
47
  <script lang="ts">
49
- import { DataTable } from "drab";
50
- </script>
48
+ import { DataTable, type DataTableItem } from "drab";
51
49
 
52
- <DataTable
53
- class="mb-12"
54
- data={[
50
+ const data: DataTableItem[] = [
55
51
  { make: "Honda", model: "CR-V", year: 2011, awd: true },
56
52
  { make: "Volvo", model: "XC-40", year: 2024, awd: true },
57
53
  { make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
@@ -61,74 +57,52 @@ Data table to display an array of JS objects. Provides sorting and pagination. S
61
57
  { make: "Ford", model: "Bronco", year: 1970, awd: true },
62
58
  { make: "GMC", model: "Acadia", year: 2008, awd: true },
63
59
  { make: "BMW", model: "X3", year: 2023, awd: true },
64
- ]}
65
- />
60
+ ];
61
+ </script>
62
+
63
+ <DataTable {data} class="mb-12" />
66
64
 
67
65
  <DataTable
68
- data={[
69
- { make: "Honda", model: "CR-V", year: 2011, awd: true },
70
- { make: "Volvo", model: "XC-40", year: 2024, awd: true },
71
- { make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
72
- { make: "Chevrolet", model: "Silverado", year: 2022, awd: true },
73
- { make: "Ford", model: "Model A", year: 1931, awd: false },
74
- { make: "Subaru", model: "Outback", year: 2021, awd: true },
75
- { make: "Ford", model: "Bronco", year: 1970, awd: true },
76
- { make: "GMC", model: "Acadia", year: 2008, awd: true },
77
- { make: "BMW", model: "X3", year: 2023, awd: true },
78
- ]}
66
+ {data}
79
67
  sortBy="year"
80
68
  maxRows={4}
81
69
  class="tabular-nums"
82
- classTh="cursor-pointer"
70
+ classTh="cursor-pointer capitalize"
83
71
  classThSorted="underline"
84
72
  classTbodyTr="transition hover:bg-neutral-50"
85
73
  classFooter="flex justify-between items-center"
86
74
  classButton="btn"
87
75
  >
88
- <svelte:fragment slot="th" let:column>
89
- {#if column === "awd"}
90
- <span class="uppercase">{column}</span>
91
- {:else}
92
- {column}
93
- {/if}
76
+ <svelte:fragment slot="th" let:key>
77
+ <span class:uppercase={key === "awd"}>{key}</span>
94
78
  </svelte:fragment>
95
- <svelte:fragment slot="td" let:column let:row>
96
- {@const item = row[column]}
97
- {#if typeof item === "boolean"}
98
- {#if item}
99
- Yes
100
- {:else}
101
- No
102
- {/if}
79
+ <svelte:fragment slot="td" let:value>
80
+ {#if typeof value === "boolean"}
81
+ {value ? "Yes" : "No"}
103
82
  {:else}
104
- {item}
83
+ {value}
105
84
  {/if}
106
85
  </svelte:fragment>
107
86
  </DataTable>
108
87
  ```
109
- -->
110
-
111
- <script context="module"></script>
112
-
88
+ -->
89
+
90
+ <script context="module"></script>
91
+
113
92
  <script>import { onMount } from "svelte";
114
- import { fade } from "svelte/transition";
115
- import { duration } from "../util/transition";
116
- import { prefersReducedMotion } from "../util/accessibility";
117
93
  import { messageNoScript } from "../util/messages";
118
94
  let className = "";
119
95
  export { className as class };
120
96
  export let id = "";
121
97
  export let data;
122
- export let columns = [];
123
- if (!columns.length && data[0]) {
124
- columns = Object.keys(data[0]);
125
- }
126
- export let sortBy = columns[0];
98
+ export let keys = Object.keys(data[0]);
99
+ export let sortBy = keys[0];
127
100
  export let ascending = true;
128
101
  export let classTable = "";
129
102
  export let idTable = "";
130
103
  export let classThead = "";
131
104
  export let classTbody = "";
105
+ export let classTr = "";
132
106
  export let classTheadTr = "";
133
107
  export let classTbodyTr = "";
134
108
  export let classTh = "";
@@ -137,48 +111,51 @@ export let classThSorted = "";
137
111
  export let classTdSorted = "";
138
112
  export let classButton = "";
139
113
  export let classFooter = "";
140
- export let classPageNumber = "";
141
114
  export let classPageControls = "";
142
115
  export let maxRows = 0;
143
116
  export let currentPage = 1;
144
- export let transition = { duration };
145
117
  export let classNoscript = "";
146
118
  let clientJs = false;
147
119
  $:
148
120
  numberOfPages = Math.floor(data.length / maxRows) + 1;
149
- const sort = (column, toggleAscending = true) => {
150
- if (column === sortBy && toggleAscending) {
121
+ const sort = (key, toggleAscending = true) => {
122
+ if (key === sortBy && toggleAscending) {
151
123
  ascending = !ascending;
152
124
  } else {
153
125
  ascending = true;
154
126
  }
155
127
  data.sort((a, b) => {
156
- const aVal = a[column];
157
- const bVal = b[column];
158
- if (typeof aVal === "number") {
128
+ const aVal = a[key];
129
+ const bVal = b[key];
130
+ if (typeof aVal === "number" && typeof bVal === "number") {
159
131
  if (ascending) {
160
132
  return aVal - bVal;
161
133
  } else {
162
134
  return bVal - aVal;
163
135
  }
164
- } else if (typeof aVal === "string") {
136
+ } else if (typeof aVal === "string" && typeof bVal === "string") {
165
137
  const collator = new Intl.Collator();
166
138
  if (ascending) {
167
139
  return collator.compare(aVal, bVal);
168
140
  } else {
169
141
  return collator.compare(bVal, aVal);
170
142
  }
171
- } else if (typeof aVal === "boolean") {
143
+ } else if (aVal instanceof Date && bVal instanceof Date) {
144
+ if (ascending) {
145
+ return aVal.getTime() - bVal.getTime();
146
+ } else {
147
+ return bVal.getTime() - aVal.getTime();
148
+ }
149
+ } else {
172
150
  if (ascending) {
173
151
  return aVal === bVal ? 0 : aVal ? -1 : 1;
174
152
  } else {
175
153
  return aVal === bVal ? 0 : aVal ? 1 : -1;
176
154
  }
177
- } else
178
- return 0;
155
+ }
179
156
  });
180
157
  data = data;
181
- sortBy = column;
158
+ sortBy = key;
182
159
  };
183
160
  const showRow = (i, currentPage2) => {
184
161
  if (!maxRows)
@@ -188,74 +165,65 @@ const showRow = (i, currentPage2) => {
188
165
  return overMin && underMax;
189
166
  };
190
167
  sort(sortBy, false);
191
- onMount(() => {
192
- if (prefersReducedMotion()) {
193
- if (transition)
194
- transition.duration = 0;
195
- }
196
- clientJs = true;
197
- });
198
- </script>
199
-
200
- <div class={className} {id}>
201
- <table class={classTable} id={idTable}>
202
- <thead class={classThead}>
203
- <tr class={classTheadTr}>
204
- {#each columns as column}
205
- <th
206
- class="{classTh} {sortBy === column ? classThSorted : ''}"
207
- on:click={() => sort(column)}
208
- >
209
- <slot name="th" {column}>{column}</slot>
210
- </th>
211
- {/each}
212
- </tr>
213
- </thead>
214
- <tbody class={classTbody}>
215
- {#each data as row, i}
216
- {#if showRow(i, currentPage)}
217
- <tr
218
- in:fade={transition ? transition : { duration: 0 }}
219
- class={classTbodyTr}
220
- >
221
- {#each columns as column}
222
- <td class="{classTd} {sortBy === column ? classTdSorted : ''}">
223
- <slot name="td" {row} {column}>{row[column]}</slot>
224
- </td>
225
- {/each}
226
- </tr>
227
- {/if}
228
- {/each}
229
- </tbody>
230
- </table>
231
-
232
- {#if maxRows}
233
- <div class={classFooter}>
234
- <div class={classPageNumber}>
235
- <slot name="pageNumber" {currentPage} {numberOfPages}>
236
- {currentPage} / {numberOfPages}
237
- </slot>
238
- </div>
239
- <div class={classPageControls}>
240
- <button
241
- type="button"
242
- class={classButton}
243
- disabled={!clientJs || currentPage < 2}
244
- on:click={() => currentPage--}
245
- >
246
- <slot name="previous" {currentPage}>Previous</slot>
247
- </button>
248
- <button
249
- type="button"
250
- class={classButton}
251
- disabled={!clientJs || currentPage >= numberOfPages}
252
- on:click={() => currentPage++}
253
- >
254
- <slot name="next" {currentPage}>Next</slot>
255
- </button>
256
- </div>
257
- </div>
258
-
259
- <noscript><div class={classNoscript}>{messageNoScript}</div></noscript>
260
- {/if}
261
- </div>
168
+ onMount(() => clientJs = true);
169
+ </script>
170
+
171
+ <div class={className} {id}>
172
+ <table class={classTable} id={idTable}>
173
+ <thead class={classThead}>
174
+ <tr class="{classTr} {classTheadTr}">
175
+ {#each keys as key}
176
+ <th
177
+ class="{classTh} {sortBy === key ? classThSorted : ''}"
178
+ on:click={() => sort(key)}
179
+ >
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} {sortBy === key ? classTdSorted : ''}">
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
+ {#if maxRows}
203
+ <div class={classFooter}>
204
+ <slot name="pageNumber" {currentPage} {numberOfPages}>
205
+ <div>{currentPage} / {numberOfPages}</div>
206
+ </slot>
207
+ <div class={classPageControls}>
208
+ <button
209
+ type="button"
210
+ class={classButton}
211
+ disabled={!clientJs || currentPage < 2}
212
+ on:click={() => currentPage--}
213
+ >
214
+ <slot name="previous">Previous</slot>
215
+ </button>
216
+ <button
217
+ type="button"
218
+ class={classButton}
219
+ disabled={!clientJs || currentPage >= numberOfPages}
220
+ on:click={() => currentPage++}
221
+ >
222
+ <slot name="next">Next</slot>
223
+ </button>
224
+ </div>
225
+ </div>
226
+
227
+ <noscript><div class={classNoscript}>{messageNoScript}</div></noscript>
228
+ {/if}
229
+ </div>
@@ -1,20 +1,18 @@
1
1
  import { SvelteComponent } from "svelte";
2
- export type DataTableRow<T> = {
3
- [K in keyof T]: T[K];
4
- };
5
- import { type FadeParams } from "svelte/transition";
2
+ export type DataTableItem = Record<string | number, string | number | boolean | Date | undefined | null>;
6
3
  declare const __propDef: {
7
4
  props: {
8
5
  class?: string | undefined;
9
6
  id?: string | undefined;
10
- /** a list of objects to render in the table */ data: DataTableRow<any>[];
11
- /** table columns, in order */ columns?: string[] | undefined;
12
- /** column to sort by, defaults to first column */ sortBy?: string | undefined;
7
+ /** a list of objects to render in the table */ data: DataTableItem[];
8
+ /** table columns to include in the table, in order. Defaults to first item's keys */ keys?: string[] | undefined;
9
+ /** key (column) to sort by, defaults to first key */ sortBy?: string | undefined;
13
10
  /** current sort order */ ascending?: boolean | undefined;
14
11
  /** `table` class */ classTable?: string | undefined;
15
12
  /** `table` id */ idTable?: string | undefined;
16
13
  /** `thead` class */ classThead?: string | undefined;
17
14
  /** `tbody` class */ classTbody?: string | undefined;
15
+ /** `tr` class */ classTr?: string | undefined;
18
16
  /** `thead tr` class */ classTheadTr?: string | undefined;
19
17
  /** `tbody tr` class */ classTbodyTr?: string | undefined;
20
18
  /** `th` class */ classTh?: string | undefined;
@@ -23,11 +21,9 @@ declare const __propDef: {
23
21
  /** currently sorted `td` */ classTdSorted?: string | undefined;
24
22
  /** `button` class */ classButton?: string | undefined;
25
23
  /** footer class */ classFooter?: string | undefined;
26
- /** class of `div` wrapping page numbers */ classPageNumber?: string | undefined;
27
24
  /** class of `div` that wraps the "Previous" and "Next" buttons */ classPageControls?: string | undefined;
28
25
  /** maximum number of rows to show on each page, defaults to `0` - no pagination */ maxRows?: number | undefined;
29
26
  /** current page, defaults to `1` */ currentPage?: number | undefined;
30
- /** fades the rows in, set to `false` to disable */ transition?: false | FadeParams | undefined;
31
27
  /** `noscript` class */ classNoscript?: string | undefined;
32
28
  };
33
29
  events: {
@@ -35,22 +31,21 @@ declare const __propDef: {
35
31
  };
36
32
  slots: {
37
33
  th: {
38
- column: string;
34
+ key: string;
35
+ sortBy: string;
39
36
  };
40
37
  td: {
41
- row: DataTableRow<any>;
42
- column: string;
38
+ item: DataTableItem;
39
+ key: string;
40
+ sortBy: string;
41
+ value: string | number | boolean | Date | null | undefined;
43
42
  };
44
43
  pageNumber: {
45
44
  currentPage: number;
46
45
  numberOfPages: number;
47
46
  };
48
- previous: {
49
- currentPage: number;
50
- };
51
- next: {
52
- currentPage: number;
53
- };
47
+ previous: {};
48
+ next: {};
54
49
  };
55
50
  };
56
51
  export type DataTableProps = typeof __propDef.props;
@@ -59,7 +54,7 @@ export type DataTableSlots = typeof __propDef.slots;
59
54
  /**
60
55
  * ### DataTable
61
56
  *
62
- * Data table to display an array of JS objects. Provides sorting and pagination. Set the `maxRows` prop to enable pagination. Data can be styled conditionally with slot props.
57
+ * 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.
63
58
  *
64
59
  * @props
65
60
  *
@@ -68,7 +63,6 @@ export type DataTableSlots = typeof __propDef.slots;
68
63
  * - `classFooter` - footer class
69
64
  * - `classNoscript` - `noscript` class
70
65
  * - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
71
- * - `classPageNumber` - class of `div` wrapping page numbers
72
66
  * - `classTable` - `table` class
73
67
  * - `classTbodyTr` - `tbody tr` class
74
68
  * - `classTbody` - `tbody` class
@@ -78,36 +72,33 @@ export type DataTableSlots = typeof __propDef.slots;
78
72
  * - `classTh` - `th` class
79
73
  * - `classTheadTr` - `thead tr` class
80
74
  * - `classThead` - `thead` class
75
+ * - `classTr` - `tr` class
81
76
  * - `class`
82
- * - `columns` - table columns, in order
83
77
  * - `currentPage` - current page, defaults to `1`
84
78
  * - `data` - a list of objects to render in the table
85
79
  * - `idTable` - `table` id
86
80
  * - `id`
81
+ * - `keys` - table columns to include in the table, in order. Defaults to first item's keys
87
82
  * - `maxRows` - maximum number of rows to show on each page, defaults to `0` - no pagination
88
- * - `sortBy` - column to sort by, defaults to first column
89
- * - `transition` - fades the rows in, set to `false` to disable
83
+ * - `sortBy` - key (column) to sort by, defaults to first key
90
84
  *
91
85
  * @slots
92
86
  *
93
- * | name | purpose | default value | slot props |
94
- * | ------------ | ------------------------ | -------------------------------- | ------------------------------ |
95
- * | `next` | next button contents | `Next` | `currentPage` |
96
- * | `pageNumber` | page numbers | `currentPage` / `numberOfPages` | `currentPage`, `numberOfPages` |
97
- * | `previous` | previous button contents | `Previous` | `currentPage` |
98
- * | `td` | td contents | `Previous` | `column`, `row` |
99
- * | `th` | th contents | `Previous` | `column` |
87
+ * | name | purpose | default value | slot props |
88
+ * | ------------ | ------------------------ | ------------------------------- | ------------------------------- |
89
+ * | `next` | next button contents | `Next` | |
90
+ * | `pageNumber` | page numbers | `currentPage` / `numberOfPages` | `currentPage`, `numberOfPages` |
91
+ * | `previous` | previous button contents | `Previous` | |
92
+ * | `td` | td contents | `item[key]` | `item`, `key`, `sortBy` `value` |
93
+ * | `th` | th contents | `key` | `key`, `sortBy` |
100
94
  *
101
95
  * @example
102
96
  *
103
97
  * ```svelte
104
98
  * <script lang="ts">
105
- * import { DataTable } from "drab";
106
- * </script>
99
+ * import { DataTable, type DataTableItem } from "drab";
107
100
  *
108
- * <DataTable
109
- * class="mb-12"
110
- * data={[
101
+ * const data: DataTableItem[] = [
111
102
  * { make: "Honda", model: "CR-V", year: 2011, awd: true },
112
103
  * { make: "Volvo", model: "XC-40", year: 2024, awd: true },
113
104
  * { make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
@@ -117,47 +108,30 @@ export type DataTableSlots = typeof __propDef.slots;
117
108
  * { make: "Ford", model: "Bronco", year: 1970, awd: true },
118
109
  * { make: "GMC", model: "Acadia", year: 2008, awd: true },
119
110
  * { make: "BMW", model: "X3", year: 2023, awd: true },
120
- * ]}
121
- * />
111
+ * ];
112
+ * </script>
113
+ *
114
+ * <DataTable {data} class="mb-12" />
122
115
  *
123
116
  * <DataTable
124
- * data={[
125
- * { make: "Honda", model: "CR-V", year: 2011, awd: true },
126
- * { make: "Volvo", model: "XC-40", year: 2024, awd: true },
127
- * { make: "Ferrari", model: "458 Italia", year: 2015, awd: false },
128
- * { make: "Chevrolet", model: "Silverado", year: 2022, awd: true },
129
- * { make: "Ford", model: "Model A", year: 1931, awd: false },
130
- * { make: "Subaru", model: "Outback", year: 2021, awd: true },
131
- * { make: "Ford", model: "Bronco", year: 1970, awd: true },
132
- * { make: "GMC", model: "Acadia", year: 2008, awd: true },
133
- * { make: "BMW", model: "X3", year: 2023, awd: true },
134
- * ]}
117
+ * {data}
135
118
  * sortBy="year"
136
119
  * maxRows={4}
137
120
  * class="tabular-nums"
138
- * classTh="cursor-pointer"
121
+ * classTh="cursor-pointer capitalize"
139
122
  * classThSorted="underline"
140
123
  * classTbodyTr="transition hover:bg-neutral-50"
141
124
  * classFooter="flex justify-between items-center"
142
125
  * classButton="btn"
143
126
  * >
144
- * <svelte:fragment slot="th" let:column>
145
- * {#if column === "awd"}
146
- * <span class="uppercase">{column}</span>
147
- * {:else}
148
- * {column}
149
- * {/if}
127
+ * <svelte:fragment slot="th" let:key>
128
+ * <span class:uppercase={key === "awd"}>{key}</span>
150
129
  * </svelte:fragment>
151
- * <svelte:fragment slot="td" let:column let:row>
152
- * {@const item = row[column]}
153
- * {#if typeof item === "boolean"}
154
- * {#if item}
155
- * Yes
156
- * {:else}
157
- * No
158
- * {/if}
130
+ * <svelte:fragment slot="td" let:value>
131
+ * {#if typeof value === "boolean"}
132
+ * {value ? "Yes" : "No"}
159
133
  * {:else}
160
- * {item}
134
+ * {value}
161
135
  * {/if}
162
136
  * </svelte:fragment>
163
137
  * </DataTable>
@@ -29,23 +29,21 @@ Displays a popover relatively positioned to the target. Does not require the tar
29
29
  let target: HTMLButtonElement;
30
30
 
31
31
  let display = false;
32
+
33
+ const open = () => (display = true);
34
+ const close = () => (display = false);
32
35
  </script>
33
36
 
34
- <button
35
- class="btn"
36
- type="button"
37
- bind:this={target}
38
- on:click={() => (display = !display)}
39
- >
40
- {display ? "Close" : "Open"}
37
+ <button class="btn" type="button" bind:this={target} on:click={open}>
38
+ Open
41
39
  </button>
42
40
 
43
41
  <Popover {target} bind:display class="p-2">
44
42
  <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
45
43
  <div class="font-bold">Bottom</div>
46
- <button class="btn">Button</button>
47
- <button class="btn">Button</button>
48
- <button class="btn">Button</button>
44
+ <button class="btn" on:click={close}>Close</button>
45
+ <button class="btn" on:click={close}>Close</button>
46
+ <button class="btn" on:click={close}>Close</button>
49
47
  </div>
50
48
  </Popover>
51
49
  ```
@@ -105,10 +103,8 @@ $:
105
103
  if (target && popover)
106
104
  setPosition();
107
105
  onMount(() => {
108
- if (prefersReducedMotion()) {
109
- if (transition)
110
- transition.duration = 0;
111
- }
106
+ if (prefersReducedMotion())
107
+ transition = false;
112
108
  });
113
109
  </script>
114
110
 
@@ -48,23 +48,21 @@ export type PopoverSlots = typeof __propDef.slots;
48
48
  * let target: HTMLButtonElement;
49
49
  *
50
50
  * let display = false;
51
+ *
52
+ * const open = () => (display = true);
53
+ * const close = () => (display = false);
51
54
  * </script>
52
55
  *
53
- * <button
54
- * class="btn"
55
- * type="button"
56
- * bind:this={target}
57
- * on:click={() => (display = !display)}
58
- * >
59
- * {display ? "Close" : "Open"}
56
+ * <button class="btn" type="button" bind:this={target} on:click={open}>
57
+ * Open
60
58
  * </button>
61
59
  *
62
60
  * <Popover {target} bind:display class="p-2">
63
61
  * <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
64
62
  * <div class="font-bold">Bottom</div>
65
- * <button class="btn">Button</button>
66
- * <button class="btn">Button</button>
67
- * <button class="btn">Button</button>
63
+ * <button class="btn" on:click={close}>Close</button>
64
+ * <button class="btn" on:click={close}>Close</button>
65
+ * <button class="btn" on:click={close}>Close</button>
68
66
  * </div>
69
67
  * </Popover>
70
68
  * ```