drab 2.2.0 → 2.3.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.
@@ -7,20 +7,25 @@ Displays a list of `details` elements.
7
7
 
8
8
  @props
9
9
 
10
- - `autoClose` - if true, other items close when a new one is opened
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
- - `classIcon` - class of the `div` around the icon
13
- - `classSlot` - class of all the `slot` elements
14
- - `classSummary` - class of all the `summary` elements
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
- Pass components into the `content` prop if needed. `AccordionContent` has `summary` and `slot` attributes of type `string | ComponentType`.
24
+ | name | purpose | default value |
25
+ | ---------- | ----------------------------- | -------------- |
26
+ | `summary` | summary element | `item.summary` |
27
+ | `icon` | icon element | `icon` prop |
28
+ | `content` | content of the accordion item | `item.content` |
24
29
 
25
30
  @example
26
31
 
@@ -29,20 +34,51 @@ 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
- content={[
34
- { summary: "Is it accessible?", slot: "Yes." },
37
+ <Accordion
38
+ items={[
39
+ { summary: "Is it accessible?", content: "Yes." },
35
40
  {
36
41
  summary: "Is it styled?",
37
- slot: "Nope, style with global styles.",
42
+ content: "Nope, style with global styles.",
38
43
  },
39
44
  {
40
45
  summary: "Is it animated?",
41
- slot: "Yes, with the transition prop.",
46
+ content: "Yes, with the transition prop.",
42
47
  },
43
- { summary: "Does it work without Javascript?", slot: "Yes." },
48
+ { summary: "Does it work without Javascript?", content: "Yes." },
44
49
  ]}
45
- />
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
+
58
+ To render a component on unique items, pass it into the `data` prop and utilize `<svelte:component this={item.data.component}>` inside of the slot.
59
+
60
+ ```svelte
61
+ <script>
62
+ import { Accordion, FullScreenButton } from "drab";
63
+ </script>
64
+
65
+ <Accordion
66
+ items={[
67
+ {
68
+ summary: "A Component",
69
+ content: "Rendered only on this item.",
70
+ data: { component: FullscreenButton },
71
+ },
72
+ { summary: "Summary", content: "Some other content" },
73
+ ]}
74
+ >
75
+ <div slot="content" let:item>
76
+ {item.content}
77
+ {#if item.data?.component}
78
+ <svelte:component this={item.data.component} />
79
+ {/if}
80
+ </div>
81
+ </Accordion>
46
82
  ```
47
83
  -->
48
84
 
@@ -54,28 +90,21 @@ import { prefersReducedMotion } from "../util/accessibility";
54
90
  let className = "";
55
91
  export { className as class };
56
92
  export let id = "";
57
- export let content;
93
+ export let items;
58
94
  export let icon = "";
59
95
  export let classDetails = "";
96
+ export let classHeader = "";
60
97
  export let classSummary = "";
61
- export let classSlot = "";
98
+ export let classContent = "";
62
99
  export let classIcon = "";
63
100
  export let transition = {};
64
101
  export let autoClose = true;
65
102
  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
103
  const toggleOpen = (i) => {
75
- content[i].open = !content[i].open;
104
+ items[i].open = !items[i].open;
76
105
  if (autoClose) {
77
- for (let j = 0; j < content.length; j++) {
78
- const item = content[j];
106
+ for (let j = 0; j < items.length; j++) {
107
+ const item = items[j];
79
108
  if (j !== i)
80
109
  item.open = false;
81
110
  }
@@ -88,64 +117,51 @@ onMount(() => {
88
117
  });
89
118
  </script>
90
119
 
91
- <div class="transition"></div>
92
-
93
120
  <div class={className} {id}>
94
- {#each content as { classContentDetails, summary, classContentSummary, slot, classContentSlot, open }, i}
95
- <div class="{classDetails} {classContentDetails}">
96
- <details bind:open>
121
+ {#each items as item, index}
122
+ <div class={classDetails}>
123
+ <details bind:open={item.open}>
97
124
  <!-- svelte-ignore a11y-no-redundant-roles -->
98
125
  <summary
99
126
  role="button"
100
127
  tabindex="0"
101
- class={classSummary}
102
- on:click={(e) => {
103
- e.preventDefault();
104
- toggleOpen(i);
105
- }}
128
+ class={classHeader}
129
+ on:click|preventDefault={() => toggleOpen(index)}
106
130
  on:keydown={(e) => {
107
131
  if (e.key === "Enter") {
108
132
  e.preventDefault();
109
- toggleOpen(i);
133
+ toggleOpen(index);
110
134
  }
111
135
  }}
112
136
  >
113
- {#if typeof summary !== "string"}
114
- <svelte:component this={summary} class={classContentSummary} />
115
- {:else}
116
- <span class={classContentSummary}>{summary}</span>
117
- {/if}
118
- {#if icon}
119
- <div
120
- class={classIcon}
121
- class:db-rotate-180={open}
122
- class:db-transition={transition}
123
- >
124
- {#if typeof icon !== "string"}
125
- <svelte:component this={icon} />
126
- {:else}
127
- <span>{icon}</span>
128
- {/if}
129
- </div>
130
- {/if}
137
+ <div class={classSummary}>
138
+ <slot name="summary" {item} {index}>{item.summary}</slot>
139
+ </div>
140
+ <slot name="icon" {item} {index}>
141
+ {#if icon}
142
+ <div
143
+ class={classIcon}
144
+ class:d-rotate-180={item.open}
145
+ class:d-transition={transition}
146
+ >
147
+ {#if typeof icon !== "string"}
148
+ <svelte:component this={icon} />
149
+ {:else}
150
+ <span>{icon}</span>
151
+ {/if}
152
+ </div>
153
+ {/if}
154
+ </slot>
131
155
  </summary>
132
156
  {#if !clientJs || !transition}
133
- <div class={classSlot}>
134
- {#if typeof slot !== "string"}
135
- <svelte:component this={slot} class={classContentSlot} />
136
- {:else}
137
- <div class={classContentSlot}>{slot}</div>
138
- {/if}
157
+ <div class={classContent}>
158
+ <slot name="content" {item} {index}>{item.content}</slot>
139
159
  </div>
140
160
  {/if}
141
161
  </details>
142
- {#if clientJs && open && transition}
143
- <div transition:slide={transition} class={classSlot}>
144
- {#if typeof slot !== "string"}
145
- <svelte:component this={slot} class={classContentSlot} />
146
- {:else}
147
- <div class={classContentSlot}>{slot}</div>
148
- {/if}
162
+ {#if clientJs && item.open && transition}
163
+ <div class={classContent} transition:slide={transition}>
164
+ <slot name="content" {item} {index}>{item.content}</slot>
149
165
  </div>
150
166
  {/if}
151
167
  </div>
@@ -153,10 +169,16 @@ onMount(() => {
153
169
  </div>
154
170
 
155
171
  <style>
156
- .db-rotate-180 {
172
+ summary {
173
+ list-style: none;
174
+ }
175
+ summary::-webkit-details-marker {
176
+ display: none;
177
+ }
178
+ .d-rotate-180 {
157
179
  transform: rotate(180deg);
158
180
  }
159
- .db-transition {
181
+ .d-transition {
160
182
  transition-property: transform;
161
183
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
162
184
  transition-duration: 150ms;
@@ -1,37 +1,48 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { ComponentType } from "svelte";
3
- export interface AccordionContent {
4
- /** `details` element class */
5
- classContentDetails?: string;
6
- /** content of the `summary` element */
7
- summary: string | ComponentType;
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
+ /** use `data` to pass anything back to the parent */
3
+ export interface AccordionItem<T = any> {
4
+ /** text summary of the item */
5
+ summary?: string;
6
+ /** text content of the item */
7
+ content?: string;
8
+ /** controls whether the content is displayed */
15
9
  open?: boolean;
10
+ /** any data to pass back */
11
+ data?: T;
16
12
  }
13
+ import { type ComponentType } from "svelte";
17
14
  import { type SlideParams } from "svelte/transition";
18
15
  declare const __propDef: {
19
16
  props: {
20
17
  class?: string | undefined;
21
18
  id?: string | undefined;
22
- /** array of `AccordionContent` elements */ content: AccordionContent[];
19
+ /** array of `AccordionItem` elements */ items: AccordionItem[];
23
20
  icon?: string | ComponentType | undefined;
24
21
  /** class of the `div` around each `details` element */ classDetails?: string | undefined;
25
- /** class of all the `summary` elements */ classSummary?: string | undefined;
26
- /** class of all the `slot` elements */ classSlot?: string | undefined;
27
- /** class of the `div` around the icon */ classIcon?: string | undefined;
22
+ /** class of all the `summary` elements */ classHeader?: string | undefined;
23
+ /** class of all the `div`s that wrap the `summary` slot */ classSummary?: string | undefined;
24
+ /** class of all the `div`s that wrap the `content` slot */ classContent?: string | undefined;
25
+ /** class of the `div` that wrap the icon if displayed */ classIcon?: string | undefined;
28
26
  /** rotates the icon, slides the content, defaults to empty object, set to false to remove */ transition?: false | SlideParams | undefined;
29
- /** if true, other items close when a new one is opened */ autoClose?: boolean | undefined;
27
+ /** if `true`, other items close when a new one is opened */ autoClose?: boolean | undefined;
30
28
  };
31
29
  events: {
32
30
  [evt: string]: CustomEvent<any>;
33
31
  };
34
- slots: {};
32
+ slots: {
33
+ summary: {
34
+ item: AccordionItem<any>;
35
+ index: any;
36
+ };
37
+ icon: {
38
+ item: AccordionItem<any>;
39
+ index: any;
40
+ };
41
+ content: {
42
+ item: AccordionItem<any>;
43
+ index: any;
44
+ };
45
+ };
35
46
  };
36
47
  export type AccordionProps = typeof __propDef.props;
37
48
  export type AccordionEvents = typeof __propDef.events;
@@ -43,20 +54,25 @@ export type AccordionSlots = typeof __propDef.slots;
43
54
  *
44
55
  * @props
45
56
  *
46
- * - `autoClose` - if true, other items close when a new one is opened
57
+ * - `autoClose` - if `true`, other items close when a new one is opened
58
+ * - `classContent` - class of all the `div`s that wrap the `content` slot
47
59
  * - `classDetails` - class of the `div` around each `details` element
48
- * - `classIcon` - class of the `div` around the icon
49
- * - `classSlot` - class of all the `slot` elements
50
- * - `classSummary` - class of all the `summary` elements
60
+ * - `classHeader` - class of all the `summary` elements
61
+ * - `classIcon` - class of the `div` that wrap the icon if displayed
62
+ * - `classSummary` - class of all the `div`s that wrap the `summary` slot
51
63
  * - `class`
52
- * - `content` - array of `AccordionContent` elements
53
64
  * - `icon`
54
65
  * - `id`
66
+ * - `items` - array of `AccordionItem` elements
55
67
  * - `transition` - rotates the icon, slides the content, defaults to empty object, set to false to remove
56
68
  *
57
69
  * @slots
58
70
  *
59
- * Pass components into the `content` prop if needed. `AccordionContent` has `summary` and `slot` attributes of type `string | ComponentType`.
71
+ * | name | purpose | default value |
72
+ * | ---------- | ----------------------------- | -------------- |
73
+ * | `summary` | summary element | `item.summary` |
74
+ * | `icon` | icon element | `icon` prop |
75
+ * | `content` | content of the accordion item | `item.content` |
60
76
  *
61
77
  * @example
62
78
  *
@@ -66,19 +82,50 @@ export type AccordionSlots = typeof __propDef.slots;
66
82
  * </script>
67
83
  *
68
84
  * <Accordion
69
- * content={[
70
- * { summary: "Is it accessible?", slot: "Yes." },
85
+ * items={[
86
+ * { summary: "Is it accessible?", content: "Yes." },
71
87
  * {
72
88
  * summary: "Is it styled?",
73
- * slot: "Nope, style with global styles.",
89
+ * content: "Nope, style with global styles.",
74
90
  * },
75
91
  * {
76
92
  * summary: "Is it animated?",
77
- * slot: "Yes, with the transition prop.",
93
+ * content: "Yes, with the transition prop.",
94
+ * },
95
+ * { summary: "Does it work without Javascript?", content: "Yes." },
96
+ * ]}
97
+ * >
98
+ * <div slot="content" let:item let:index>
99
+ * <span>{index + 1}.</span>
100
+ * <span>{item.content}</span>
101
+ * </div>
102
+ * </Accordion>
103
+ * ```
104
+ *
105
+ * To render a component on unique items, pass it into the `data` prop and utilize `<svelte:component this={item.data.component}>` inside of the slot.
106
+ *
107
+ * ```svelte
108
+ * <script>
109
+ * import { Accordion, FullScreenButton } from "drab";
110
+ * </script>
111
+ *
112
+ * <Accordion
113
+ * items={[
114
+ * {
115
+ * summary: "A Component",
116
+ * content: "Rendered only on this item.",
117
+ * data: { component: FullscreenButton },
78
118
  * },
79
- * { summary: "Does it work without Javascript?", slot: "Yes." },
119
+ * { summary: "Summary", content: "Some other content" },
80
120
  * ]}
81
- * />
121
+ * >
122
+ * <div slot="content" let:item>
123
+ * {item.content}
124
+ * {#if item.data?.component}
125
+ * <svelte:component this={item.data.component} />
126
+ * {/if}
127
+ * </div>
128
+ * </Accordion>
82
129
  * ```
83
130
  */
84
131
  export default class Accordion extends SvelteComponent<AccordionProps, AccordionEvents, AccordionSlots> {
@@ -7,7 +7,7 @@ Displays when the parent element is right clicked.
7
7
 
8
8
  @props
9
9
 
10
- - `classNoscript` - noscript class
10
+ - `classNoscript` - `noscript` class
11
11
  - `class`
12
12
  - `display` - controls `display` css property
13
13
  - `id`
@@ -25,14 +25,14 @@ Displays when the parent element is right clicked.
25
25
  import { ContextMenu } from "drab";
26
26
  </script>
27
27
 
28
- <div class="p-12 border border-dashed flex justify-center">
28
+ <div>
29
29
  <div>Right click here</div>
30
- <ContextMenu class="rounded shadow p-2 bg-white">
31
- <div class="flex flex-col gap-2 not-prose w-48">
32
- <div class="font-bold">Context Menu</div>
33
- <button class="btn">Button</button>
34
- <button class="btn">Button</button>
35
- <button class="btn">Button</button>
30
+ <ContextMenu>
31
+ <div>
32
+ <div>Context Menu</div>
33
+ <button>Button</button>
34
+ <button>Button</button>
35
+ <button>Button</button>
36
36
  </div>
37
37
  </ContextMenu>
38
38
  </div>
@@ -4,7 +4,7 @@ declare const __propDef: {
4
4
  class?: string | undefined;
5
5
  id?: string | undefined;
6
6
  /** controls `display` css property */ display?: boolean | undefined;
7
- /** noscript class */ classNoscript?: string | undefined;
7
+ /** `noscript` class */ classNoscript?: string | undefined;
8
8
  };
9
9
  events: {
10
10
  [evt: string]: CustomEvent<any>;
@@ -23,7 +23,7 @@ export type ContextMenuSlots = typeof __propDef.slots;
23
23
  *
24
24
  * @props
25
25
  *
26
- * - `classNoscript` - noscript class
26
+ * - `classNoscript` - `noscript` class
27
27
  * - `class`
28
28
  * - `display` - controls `display` css property
29
29
  * - `id`
@@ -41,14 +41,14 @@ export type ContextMenuSlots = typeof __propDef.slots;
41
41
  * import { ContextMenu } from "drab";
42
42
  * </script>
43
43
  *
44
- * <div class="p-12 border border-dashed flex justify-center">
44
+ * <div>
45
45
  * <div>Right click here</div>
46
- * <ContextMenu class="rounded shadow p-2 bg-white">
47
- * <div class="flex flex-col gap-2 not-prose w-48">
48
- * <div class="font-bold">Context Menu</div>
49
- * <button class="btn">Button</button>
50
- * <button class="btn">Button</button>
51
- * <button class="btn">Button</button>
46
+ * <ContextMenu>
47
+ * <div>
48
+ * <div>Context Menu</div>
49
+ * <button>Button</button>
50
+ * <button>Button</button>
51
+ * <button>Button</button>
52
52
  * </div>
53
53
  * </ContextMenu>
54
54
  * </div>
@@ -7,7 +7,7 @@ Uses the navigator api to copy text to the clipboard.
7
7
 
8
8
  @props
9
9
 
10
- - `classNoscript` - noscript class
10
+ - `classNoscript` - `noscript` class
11
11
  - `class`
12
12
  - `id`
13
13
  - `text` - text to copy
@@ -5,7 +5,7 @@ declare const __propDef: {
5
5
  id?: string | undefined;
6
6
  title?: string | undefined;
7
7
  /** text to copy */ text: string;
8
- /** noscript class */ classNoscript?: string | undefined;
8
+ /** `noscript` class */ classNoscript?: string | undefined;
9
9
  };
10
10
  events: {
11
11
  [evt: string]: CustomEvent<any>;
@@ -25,7 +25,7 @@ export type CopyButtonSlots = typeof __propDef.slots;
25
25
  *
26
26
  * @props
27
27
  *
28
- * - `classNoscript` - noscript class
28
+ * - `classNoscript` - `noscript` class
29
29
  * - `class`
30
30
  * - `id`
31
31
  * - `text` - text to copy
@@ -8,24 +8,24 @@ Data table to display an array of JS objects. Click a column header to sort.
8
8
  @props
9
9
 
10
10
  - `ascending` - default sort order
11
- - `classButton` - button class
12
- - `classFooter` - footer class
13
- - `classNoscript` - noscript class
11
+ - `classButton` - `button` class
12
+ - `classFooter` - `footer` class
13
+ - `classNoscript` - `noscript` class
14
14
  - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
15
15
  - `classPageNumber` - class of `div` wrapping page numbers
16
- - `classTable` - table class
17
- - `classTbodyTr` - tbody tr class
18
- - `classTbody` - tbody class
19
- - `classTdSorted` - currently sorted td
20
- - `classTd` - td class
21
- - `classThSorted` - currently sorted th
22
- - `classTh` - th class
23
- - `classTheadTr` - thead tr class
24
- - `classThead` - thead class
16
+ - `classTable` - `table` class
17
+ - `classTbodyTr` - `tbody tr` class
18
+ - `classTbody` - `tbody` class
19
+ - `classTdSorted` - currently sorted `td`
20
+ - `classTd` - `td` class
21
+ - `classThSorted` - currently sorted `th`
22
+ - `classTh` - `th` class
23
+ - `classTheadTr` - `thead tr` class
24
+ - `classThead` - `thead` class
25
25
  - `columns` - table columns, in order
26
26
  - `currentPage` - current page, defaults to `1`
27
27
  - `data` - a list of objects to render in the table
28
- - `idTable` - table id
28
+ - `idTable` - `table` id
29
29
  - `paginate` - number of rows to show on each page, defaults to `0` - no pagination
30
30
  - `sortBy` - column to sort by--defaults to first column
31
31
 
@@ -8,23 +8,23 @@ declare const __propDef: {
8
8
  /** table columns, in order */ columns?: string[] | undefined;
9
9
  /** column to sort by--defaults to first column */ sortBy?: string | undefined;
10
10
  /** default sort order */ ascending?: boolean | undefined;
11
- /** table class */ classTable?: string | undefined;
12
- /** table id */ idTable?: string | undefined;
13
- /** thead class */ classThead?: string | undefined;
14
- /** tbody class */ classTbody?: string | undefined;
15
- /** thead tr class */ classTheadTr?: string | undefined;
16
- /** tbody tr class */ classTbodyTr?: string | undefined;
17
- /** th class */ classTh?: string | undefined;
18
- /** td class */ classTd?: string | undefined;
19
- /** currently sorted th */ classThSorted?: string | undefined;
20
- /** currently sorted td */ classTdSorted?: string | undefined;
21
- /** button class */ classButton?: string | undefined;
22
- /** footer class */ classFooter?: string | undefined;
11
+ /** `table` class */ classTable?: string | undefined;
12
+ /** `table` id */ idTable?: string | undefined;
13
+ /** `thead` class */ classThead?: string | undefined;
14
+ /** `tbody` class */ classTbody?: string | undefined;
15
+ /** `thead tr` class */ classTheadTr?: string | undefined;
16
+ /** `tbody tr` class */ classTbodyTr?: string | undefined;
17
+ /** `th` class */ classTh?: string | undefined;
18
+ /** `td` class */ classTd?: string | undefined;
19
+ /** currently sorted `th` */ classThSorted?: string | undefined;
20
+ /** currently sorted `td` */ classTdSorted?: string | undefined;
21
+ /** `button` class */ classButton?: string | undefined;
22
+ /** `footer` class */ classFooter?: string | undefined;
23
23
  /** class of `div` wrapping page numbers */ classPageNumber?: string | undefined;
24
24
  /** class of `div` that wraps the "Previous" and "Next" buttons */ classPageControls?: string | undefined;
25
25
  /** number of rows to show on each page, defaults to `0` - no pagination */ paginate?: number | undefined;
26
26
  /** current page, defaults to `1` */ currentPage?: number | undefined;
27
- /** noscript class */ classNoscript?: string | undefined;
27
+ /** `noscript` class */ classNoscript?: string | undefined;
28
28
  };
29
29
  events: {
30
30
  [evt: string]: CustomEvent<any>;
@@ -45,24 +45,24 @@ export type DataTableSlots = typeof __propDef.slots;
45
45
  * @props
46
46
  *
47
47
  * - `ascending` - default sort order
48
- * - `classButton` - button class
49
- * - `classFooter` - footer class
50
- * - `classNoscript` - noscript class
48
+ * - `classButton` - `button` class
49
+ * - `classFooter` - `footer` class
50
+ * - `classNoscript` - `noscript` class
51
51
  * - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
52
52
  * - `classPageNumber` - class of `div` wrapping page numbers
53
- * - `classTable` - table class
54
- * - `classTbodyTr` - tbody tr class
55
- * - `classTbody` - tbody class
56
- * - `classTdSorted` - currently sorted td
57
- * - `classTd` - td class
58
- * - `classThSorted` - currently sorted th
59
- * - `classTh` - th class
60
- * - `classTheadTr` - thead tr class
61
- * - `classThead` - thead class
53
+ * - `classTable` - `table` class
54
+ * - `classTbodyTr` - `tbody tr` class
55
+ * - `classTbody` - `tbody` class
56
+ * - `classTdSorted` - currently sorted `td`
57
+ * - `classTd` - `td` class
58
+ * - `classThSorted` - currently sorted `th`
59
+ * - `classTh` - `th` class
60
+ * - `classTheadTr` - `thead tr` class
61
+ * - `classThead` - `thead` class
62
62
  * - `columns` - table columns, in order
63
63
  * - `currentPage` - current page, defaults to `1`
64
64
  * - `data` - a list of objects to render in the table
65
- * - `idTable` - table id
65
+ * - `idTable` - `table` id
66
66
  * - `paginate` - number of rows to show on each page, defaults to `0` - no pagination
67
67
  * - `sortBy` - column to sort by--defaults to first column
68
68
  *
@@ -9,9 +9,9 @@ Text editor with controls to add elements and keyboard shortcuts.
9
9
 
10
10
  - `classButton` - `class` of all the `button` elements
11
11
  - `classControls` - `class` of the `div` that wraps the controls
12
- - `classNoscript` - noscript class
12
+ - `classNoscript` - `noscript` class
13
13
  - `classTextarea` - `class` of the `textarea` element
14
- - `contentElements` - an array of content elements for the controls
14
+ - `contentElements` - an array of `EditorContentElement`s for the controls
15
15
  - `idControls` - `id` of the `div` that wraps the controls
16
16
  - `idTextarea` - `id` of the `textarea` element
17
17
  - `keyPairs` - keys that will auto-close if typed, value is their closing character
@@ -12,16 +12,16 @@ export interface EditorContentElement {
12
12
  text: string;
13
13
  /** controls how the text is added */
14
14
  display: "inline" | "block" | "wrap";
15
- /** contents of the button */
15
+ /** contents of the `button` */
16
16
  icon: string | ComponentType;
17
17
  /** keyboard shortcut */
18
18
  key?: string;
19
- /** class to apply to the specific button */
19
+ /** class to apply to the specific `button` */
20
20
  class?: string;
21
21
  }
22
22
  declare const __propDef: {
23
23
  props: {
24
- /** an array of content elements for the controls */ contentElements?: EditorContentElement[] | undefined;
24
+ /** an array of `EditorContentElement`s for the controls */ contentElements?: EditorContentElement[] | undefined;
25
25
  /** `value` of the `textarea` element */ valueTextarea?: string | undefined;
26
26
  /** `placeholder` of the `textarea` element */ placeholderTextarea?: string | undefined;
27
27
  /** `class` of the `textarea` element */ classTextarea?: string | undefined;
@@ -34,7 +34,7 @@ declare const __propDef: {
34
34
  /** keys that will auto-close if typed, value is their closing character */ keyPairs?: {
35
35
  [key: string]: string;
36
36
  } | undefined;
37
- /** noscript class */ classNoscript?: string | undefined;
37
+ /** `noscript` class */ classNoscript?: string | undefined;
38
38
  };
39
39
  events: {
40
40
  input: Event;
@@ -55,9 +55,9 @@ export type EditorSlots = typeof __propDef.slots;
55
55
  *
56
56
  * - `classButton` - `class` of all the `button` elements
57
57
  * - `classControls` - `class` of the `div` that wraps the controls
58
- * - `classNoscript` - noscript class
58
+ * - `classNoscript` - `noscript` class
59
59
  * - `classTextarea` - `class` of the `textarea` element
60
- * - `contentElements` - an array of content elements for the controls
60
+ * - `contentElements` - an array of `EditorContentElement`s for the controls
61
61
  * - `idControls` - `id` of the `div` that wraps the controls
62
62
  * - `idTextarea` - `id` of the `textarea` element
63
63
  * - `keyPairs` - keys that will auto-close if typed, value is their closing character
@@ -7,7 +7,7 @@ Make the document or a specific element fullscreen.
7
7
 
8
8
  @props
9
9
 
10
- - `classNoscript` - noscript class
10
+ - `classNoscript` - `noscript` class
11
11
  - `class`
12
12
  - `confirmMessage` - message to display in the `confirm` popup, set this to empty string `""` to disable `confirm`
13
13
  - `id`
@@ -6,7 +6,7 @@ declare const __propDef: {
6
6
  title?: string | undefined;
7
7
  /** element to make fullscreen (defaults to `document.documentElement` upon mount) */ targetElement?: HTMLElement | null | undefined;
8
8
  /** message to display in the `confirm` popup, set this to empty string `""` to disable `confirm` */ confirmMessage?: string | undefined;
9
- /** noscript class */ classNoscript?: string | undefined;
9
+ /** `noscript` class */ classNoscript?: string | undefined;
10
10
  };
11
11
  events: {
12
12
  [evt: string]: CustomEvent<any>;
@@ -26,7 +26,7 @@ export type FullscreenButtonSlots = typeof __propDef.slots;
26
26
  *
27
27
  * @props
28
28
  *
29
- * - `classNoscript` - noscript class
29
+ * - `classNoscript` - `noscript` class
30
30
  * - `class`
31
31
  * - `confirmMessage` - message to display in the `confirm` popup, set this to empty string `""` to disable `confirm`
32
32
  * - `id`
@@ -7,12 +7,12 @@ Displays a popover relatively positioned to the button.
7
7
 
8
8
  @props
9
9
 
10
- - `classButton` - button class
10
+ - `classButton` - `button` class
11
11
  - `classPopover` - popover class
12
12
  - `class`
13
13
  - `display` - if `eventType="click"`, controls the display
14
14
  - `eventType` - controls if hovering or clicking the button displays the popover
15
- - `idButton` - button id
15
+ - `idButton` - `button` id
16
16
  - `idPopover` - popover id
17
17
  - `id`
18
18
  - `position` - where the popover is displayed in relation to the button
@@ -3,9 +3,9 @@ declare const __propDef: {
3
3
  props: {
4
4
  class?: string | undefined;
5
5
  id?: string | undefined;
6
- /** button class */ classButton?: string | undefined;
6
+ /** `button` class */ classButton?: string | undefined;
7
7
  /** popover class */ classPopover?: string | undefined;
8
- /** button id */ idButton?: string | undefined;
8
+ /** `button` id */ idButton?: string | undefined;
9
9
  /** popover id */ idPopover?: string | undefined;
10
10
  /** if `eventType="click"`, controls the display */ display?: boolean | undefined;
11
11
  /** where the popover is displayed in relation to the button */ position?: "top" | "bottom" | "left" | "right" | undefined;
@@ -29,12 +29,12 @@ export type PopoverSlots = typeof __propDef.slots;
29
29
  *
30
30
  * @props
31
31
  *
32
- * - `classButton` - button class
32
+ * - `classButton` - `button` class
33
33
  * - `classPopover` - popover class
34
34
  * - `class`
35
35
  * - `display` - if `eventType="click"`, controls the display
36
36
  * - `eventType` - controls if hovering or clicking the button displays the popover
37
- * - `idButton` - button id
37
+ * - `idButton` - `button` id
38
38
  * - `idPopover` - popover id
39
39
  * - `id`
40
40
  * - `position` - where the popover is displayed in relation to the button
@@ -7,11 +7,11 @@ Uses the navigator api to share or copy a url link depending on browser support.
7
7
 
8
8
  @props
9
9
 
10
- - `classNoscript` - noscript class
10
+ - `classNoscript` - `noscript` class
11
11
  - `class`
12
12
  - `id`
13
13
  - `text` - prefixed text in share message
14
- - `title` - title of share message and button attribute, defaults to end of url
14
+ - `title` - title of share message and `button` attribute, defaults to end of url
15
15
  - `url` - url to be shared
16
16
 
17
17
  @slots
@@ -5,8 +5,8 @@ declare const __propDef: {
5
5
  id?: string | undefined;
6
6
  /** prefixed text in share message */ text?: string | undefined;
7
7
  /** url to be shared */ url: string;
8
- /** title of share message and button attribute, defaults to end of url */ title?: string | undefined;
9
- /** noscript class */ classNoscript?: string | undefined;
8
+ /** title of share message and `button` attribute, defaults to end of url */ title?: string | undefined;
9
+ /** `noscript` class */ classNoscript?: string | undefined;
10
10
  };
11
11
  events: {
12
12
  [evt: string]: CustomEvent<any>;
@@ -26,11 +26,11 @@ export type ShareButtonSlots = typeof __propDef.slots;
26
26
  *
27
27
  * @props
28
28
  *
29
- * - `classNoscript` - noscript class
29
+ * - `classNoscript` - `noscript` class
30
30
  * - `class`
31
31
  * - `id`
32
32
  * - `text` - prefixed text in share message
33
- * - `title` - title of share message and button attribute, defaults to end of url
33
+ * - `title` - title of share message and `button` attribute, defaults to end of url
34
34
  * - `url` - url to be shared
35
35
  *
36
36
  * @slots
@@ -0,0 +1,102 @@
1
+ <!--
2
+ @component
3
+
4
+ ### Tabs
5
+
6
+ Displays tabs and slotted content.
7
+
8
+ @props
9
+
10
+ - `classButtonActive` - class of the active tab's `button`
11
+ - `classButtonInactive` - class of all the inactive tabs' `button`s
12
+ - `classButton` - `button` class
13
+ - `classHeader` - class of the `div` that wraps the `button`s
14
+ - `classNoscript` - `noscript` class
15
+ - `classSlot` - class of `div` that wraps the slotted content
16
+ - `class`
17
+ - `content` - array of `TabContent` elements
18
+ - `id`
19
+ - `transition` - fades the content in, defaults to empty object, set to false to remove
20
+
21
+ @slots
22
+
23
+ Pass components into the `content` prop if needed. `TabsContent` has a `slot` attribute of type `string | ComponentType`.
24
+
25
+ @example
26
+
27
+ ```svelte
28
+ <script>
29
+ import { Tabs } from "drab";
30
+ import { FullscreenButton } from "drab";
31
+ </script>
32
+
33
+ <Tabs content={[
34
+ { name: "String", slot: "Slot" },
35
+ { name: "Component", slot: FullscreenButton },
36
+ ]}
37
+ />
38
+ ```
39
+ -->
40
+
41
+ <script context="module"></script>
42
+
43
+ <script>import { onMount } from "svelte";
44
+ import { fade } from "svelte/transition";
45
+ import { messageNoScript } from "../util/messages";
46
+ let className = "";
47
+ export { className as class };
48
+ export let id = "";
49
+ export let classHeader = "";
50
+ export let classButton = "";
51
+ export let classButtonActive = "";
52
+ export let classButtonInactive = "";
53
+ export let classNoscript = "";
54
+ export let classSlot = "";
55
+ export let content;
56
+ export let transition = {};
57
+ const fadeTransition = transition ? transition : { duration: 0 };
58
+ let clientJs = false;
59
+ let activeIndex = 0;
60
+ for (const item of content) {
61
+ if (!item.classContentSlot)
62
+ item.classContentSlot = "";
63
+ }
64
+ $:
65
+ activeTab = content[activeIndex];
66
+ onMount(() => clientJs = true);
67
+ </script>
68
+
69
+ <div class={className} {id}>
70
+ <div class={classHeader}>
71
+ {#each content as { name }, i}
72
+ <button
73
+ disabled={!clientJs}
74
+ class="{classButton} {activeIndex === i
75
+ ? classButtonActive
76
+ : ''} {activeIndex !== i ? classButtonInactive : ''}"
77
+ on:click={() => (activeIndex = i)}
78
+ >
79
+ {name}
80
+ </button>
81
+ {/each}
82
+ </div>
83
+ <div class={classSlot}>
84
+ {#if typeof activeTab.slot !== "string"}
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}
96
+ </div>
97
+ <noscript>
98
+ <div class={classNoscript}>
99
+ {messageNoScript}
100
+ </div>
101
+ </noscript>
102
+ </div>
@@ -0,0 +1,72 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { ComponentType } from "svelte";
3
+ export interface TabsContent {
4
+ /** tab name, displayed in `button` element */
5
+ name: string;
6
+ /** slotted content, displayed once tab is clicked */
7
+ slot: string | ComponentType;
8
+ /** class of the slotted content */
9
+ classContentSlot?: string;
10
+ }
11
+ import { type FadeParams } from "svelte/transition";
12
+ declare const __propDef: {
13
+ props: {
14
+ class?: string | undefined;
15
+ id?: string | undefined;
16
+ /** class of the `div` that wraps the `button`s */ classHeader?: string | undefined;
17
+ /** `button` class */ classButton?: string | undefined;
18
+ /** class of the active tab's `button` */ classButtonActive?: string | undefined;
19
+ /** class of all the inactive tabs' `button`s */ classButtonInactive?: string | undefined;
20
+ /** `noscript` class */ classNoscript?: string | undefined;
21
+ /** class of `div` that wraps the slotted content */ classSlot?: string | undefined;
22
+ /** array of `TabContent` elements */ content: TabsContent[];
23
+ /** fades the content in, defaults to empty object, set to false to remove */ transition?: false | FadeParams | undefined;
24
+ };
25
+ events: {
26
+ [evt: string]: CustomEvent<any>;
27
+ };
28
+ slots: {};
29
+ };
30
+ export type TabsProps = typeof __propDef.props;
31
+ export type TabsEvents = typeof __propDef.events;
32
+ export type TabsSlots = typeof __propDef.slots;
33
+ /**
34
+ * ### Tabs
35
+ *
36
+ * Displays tabs and slotted content.
37
+ *
38
+ * @props
39
+ *
40
+ * - `classButtonActive` - class of the active tab's `button`
41
+ * - `classButtonInactive` - class of all the inactive tabs' `button`s
42
+ * - `classButton` - `button` class
43
+ * - `classHeader` - class of the `div` that wraps the `button`s
44
+ * - `classNoscript` - `noscript` class
45
+ * - `classSlot` - class of `div` that wraps the slotted content
46
+ * - `class`
47
+ * - `content` - array of `TabContent` elements
48
+ * - `id`
49
+ * - `transition` - fades the content in, defaults to empty object, set to false to remove
50
+ *
51
+ * @slots
52
+ *
53
+ * Pass components into the `content` prop if needed. `TabsContent` has a `slot` attribute of type `string | ComponentType`.
54
+ *
55
+ * @example
56
+ *
57
+ * ```svelte
58
+ * <script>
59
+ * import { Tabs } from "drab";
60
+ * import { FullscreenButton } from "drab";
61
+ * </script>
62
+ *
63
+ * <Tabs content={[
64
+ * { name: "String", slot: "Slot" },
65
+ * { name: "Component", slot: FullscreenButton },
66
+ * ]}
67
+ * />
68
+ * ```
69
+ */
70
+ export default class Tabs extends SvelteComponent<TabsProps, TabsEvents, TabsSlots> {
71
+ }
72
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import Accordion from "./components/Accordion.svelte";
2
- import type { AccordionContent } from "./components/Accordion.svelte";
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";
@@ -12,4 +12,4 @@ import FullscreenButton from "./components/FullscreenButton.svelte";
12
12
  import Popover from "./components/Popover.svelte";
13
13
  import ShareButton from "./components/ShareButton.svelte";
14
14
  import YouTube from "./components/YouTube.svelte";
15
- export { Accordion, type AccordionContent, Chord, type ChordNote, ContextMenu, CopyButton, DataTable, type DataTableRow, Editor, type EditorContentElement, FullscreenButton, Popover, ShareButton, YouTube, };
15
+ export { Accordion, type AccordionItem, Chord, type ChordNote, ContextMenu, CopyButton, DataTable, type DataTableRow, Editor, type EditorContentElement, FullscreenButton, Popover, ShareButton, YouTube, };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drab",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "An unstyled Svelte component library",
5
5
  "keywords": [
6
6
  "components",