drab 1.10.1 → 2.1.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.
@@ -47,6 +47,8 @@ Generates a guitar chord `svg`.
47
47
  ```
48
48
  -->
49
49
 
50
+ <script context="module"></script>
51
+
50
52
  <script>let className = "";
51
53
  export { className as class };
52
54
  export let id = "";
@@ -1,4 +1,12 @@
1
1
  import { SvelteComponent } from "svelte";
2
+ export interface ChordNote {
3
+ /** recommended finger to use */
4
+ finger: number | string;
5
+ /** string number */
6
+ string: number;
7
+ /** fret number */
8
+ fret: number;
9
+ }
2
10
  declare const __propDef: {
3
11
  props: {
4
12
  class?: string | undefined;
@@ -6,14 +14,7 @@ declare const __propDef: {
6
14
  /** total number of strings for the instrument */ strings?: number | undefined;
7
15
  /** name of chord */ name?: string | undefined;
8
16
  /** total size of chord square */ size?: number | undefined;
9
- /** list of the positioning of the notes required for the chord */ notes?: {
10
- /** recommended finger to use */
11
- finger: number | string;
12
- /** string number */
13
- string: number;
14
- /** fret number */
15
- fret: number;
16
- }[] | undefined;
17
+ /** list of the positioning of the notes required for the chord */ notes?: ChordNote[] | undefined;
17
18
  };
18
19
  events: {
19
20
  [evt: string]: CustomEvent<any>;
@@ -7,6 +7,7 @@ Displays when the parent element is right clicked.
7
7
 
8
8
  @props
9
9
 
10
+ - `classNoscript` - noscript class
10
11
  - `class`
11
12
  - `display` - controls `display` css property
12
13
  - `id`
@@ -43,29 +44,36 @@ let className = "";
43
44
  export { className as class };
44
45
  export let id = "";
45
46
  export let display = false;
47
+ export let classNoscript = "";
46
48
  let contextMenu;
47
- let position = { x: 0, y: 0 };
49
+ let coordinates = { x: 0, y: 0 };
48
50
  const hide = () => display = false;
51
+ const onKeyDown = (e) => {
52
+ if (e.key === "Escape") {
53
+ display = false;
54
+ }
55
+ };
49
56
  onMount(() => {
50
- const parent = contextMenu.parentElement;
51
- if (parent) {
52
- parent.addEventListener("contextmenu", async (e) => {
57
+ const parentElement = contextMenu.parentElement;
58
+ if (parentElement) {
59
+ parentElement.addEventListener("contextmenu", async (e) => {
53
60
  if (contextMenu) {
54
61
  e.preventDefault();
55
62
  const scrollY = window.scrollY;
56
- position.x = e.clientX;
57
- position.y = e.clientY + scrollY;
63
+ const scrollX = window.scrollX;
64
+ coordinates.x = e.clientX + scrollX;
65
+ coordinates.y = e.clientY + scrollY;
58
66
  display = true;
59
67
  await tick();
60
68
  const offsetWidth = contextMenu.offsetWidth + 24;
61
69
  const offsetHeight = contextMenu.offsetHeight + 6;
62
70
  const innerWidth = window.innerWidth;
63
71
  const innerHeight = window.innerHeight;
64
- if (position.x + offsetWidth > innerWidth) {
65
- position.x = innerWidth - offsetWidth;
72
+ if (coordinates.x + offsetWidth > scrollX + innerWidth) {
73
+ coordinates.x = scrollX + innerWidth - offsetWidth;
66
74
  }
67
- if (position.y + offsetHeight > scrollY + innerHeight) {
68
- position.y = scrollY + innerHeight - offsetHeight;
75
+ if (coordinates.y + offsetHeight > scrollY + innerHeight) {
76
+ coordinates.y = scrollY + innerHeight - offsetHeight;
69
77
  }
70
78
  }
71
79
  });
@@ -73,21 +81,29 @@ onMount(() => {
73
81
  });
74
82
  </script>
75
83
 
76
- <svelte:document on:click={hide} />
84
+ <svelte:document on:click={hide} on:keydown={onKeyDown} />
77
85
 
78
86
  <div
79
87
  class={className}
80
88
  {id}
81
89
  bind:this={contextMenu}
82
- style="display: {display
83
- ? 'block'
84
- : 'none'}; top: {position.y}px; left: {position.x}px;"
90
+ style:z-index={display ? "10" : "-10"}
91
+ style:opacity={display ? "100%" : "0%"}
92
+ style:top="{coordinates.y}px"
93
+ style:left="{coordinates.x}px"
85
94
  >
86
95
  <slot>Context Menu</slot>
87
96
  </div>
88
97
 
98
+ <noscript>
99
+ <div class={classNoscript}>
100
+ <slot />
101
+ </div>
102
+ </noscript>
103
+
89
104
  <style>
90
105
  div {
91
106
  position: absolute;
107
+ z-index: 1;
92
108
  }
93
109
  </style>
@@ -4,6 +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
8
  };
8
9
  events: {
9
10
  [evt: string]: CustomEvent<any>;
@@ -22,6 +23,7 @@ export type ContextMenuSlots = typeof __propDef.slots;
22
23
  *
23
24
  * @props
24
25
  *
26
+ * - `classNoscript` - noscript class
25
27
  * - `class`
26
28
  * - `display` - controls `display` css property
27
29
  * - `id`
@@ -7,6 +7,7 @@ Uses the navigator api to copy text to the clipboard.
7
7
 
8
8
  @props
9
9
 
10
+ - `classNoscript` - noscript class
10
11
  - `class`
11
12
  - `id`
12
13
  - `text` - text to copy
@@ -30,11 +31,14 @@ Uses the navigator api to copy text to the clipboard.
30
31
  ```
31
32
  -->
32
33
 
33
- <script>let className = "";
34
+ <script>import { onMount } from "svelte";
35
+ let className = "";
34
36
  export { className as class };
35
37
  export let id = "";
36
38
  export let title = "Copy";
37
39
  export let text;
40
+ export let classNoscript = "";
41
+ let clientJs = false;
38
42
  let complete = false;
39
43
  const copyText = async () => {
40
44
  try {
@@ -45,12 +49,15 @@ const copyText = async () => {
45
49
  console.error(error);
46
50
  }
47
51
  };
52
+ onMount(() => clientJs = true);
48
53
  </script>
49
54
 
50
- <button on:click={copyText} class={className} {id} {title}>
55
+ <button disabled={!clientJs} on:click={copyText} class={className} {id} {title}>
51
56
  {#if complete}
52
57
  <slot name="complete">Copied</slot>
53
58
  {:else}
54
59
  <slot>Copy</slot>
55
60
  {/if}
56
61
  </button>
62
+
63
+ <noscript><span class={classNoscript}>{text}</span></noscript>
@@ -5,6 +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
9
  };
9
10
  events: {
10
11
  [evt: string]: CustomEvent<any>;
@@ -24,6 +25,7 @@ export type CopyButtonSlots = typeof __propDef.slots;
24
25
  *
25
26
  * @props
26
27
  *
28
+ * - `classNoscript` - noscript class
27
29
  * - `class`
28
30
  * - `id`
29
31
  * - `text` - text to copy
@@ -8,25 +8,26 @@ 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
- - `buttonClass` - button class
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
+ - `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
12
25
  - `columns` - table columns, in order
13
26
  - `currentPage` - current page, defaults to `1`
14
27
  - `data` - a list of objects to render in the table
15
- - `footerClass` - footer class
16
- - `pageControlsClass` - class of `div` that wraps the "Previous" and "Next" buttons
17
- - `pageNumberClass` - class of `div` wrapping page numbers
28
+ - `idTable` - table id
18
29
  - `paginate` - number of rows to show on each page, defaults to `0` - no pagination
19
30
  - `sortBy` - column to sort by--defaults to first column
20
- - `sortedTdClass` - currently sorted td
21
- - `sortedThClass` - currently sorted th
22
- - `tBodyClass` - tbody class
23
- - `tBodyTrClass` - tbody tr class
24
- - `tHeadClass` - thead class
25
- - `tHeadTrClass` - thead tr class
26
- - `tableClass` - table class
27
- - `tableId` - table id
28
- - `tdClass` - td class
29
- - `thClass` - th class
30
31
 
31
32
  @slots
32
33
 
@@ -57,29 +58,33 @@ Data table to display an array of JS objects. Click a column header to sort.
57
58
 
58
59
  <script context="module"></script>
59
60
 
60
- <script>export let data;
61
+ <script>import { messageNoScript } from "../util/messages";
62
+ import { onMount } from "svelte";
63
+ export let data;
61
64
  export let columns = [];
62
65
  if (!columns.length && data[0]) {
63
66
  columns = Object.keys(data[0]);
64
67
  }
65
68
  export let sortBy = columns[0];
66
69
  export let ascending = true;
67
- export let tableClass = "";
68
- export let tableId = "";
69
- export let tHeadClass = "";
70
- export let tBodyClass = "";
71
- export let tHeadTrClass = "";
72
- export let tBodyTrClass = "";
73
- export let thClass = "";
74
- export let tdClass = "";
75
- export let sortedThClass = "";
76
- export let sortedTdClass = "";
77
- export let buttonClass = "";
78
- export let footerClass = "";
79
- export let pageNumberClass = "";
80
- export let pageControlsClass = "";
70
+ export let classTable = "";
71
+ export let idTable = "";
72
+ export let classThead = "";
73
+ export let classTbody = "";
74
+ export let classTheadTr = "";
75
+ export let classTbodyTr = "";
76
+ export let classTh = "";
77
+ export let classTd = "";
78
+ export let classThSorted = "";
79
+ export let classTdSorted = "";
80
+ export let classButton = "";
81
+ export let classFooter = "";
82
+ export let classPageNumber = "";
83
+ export let classPageControls = "";
81
84
  export let paginate = 0;
82
85
  export let currentPage = 1;
86
+ export let classNoscript = "";
87
+ let clientJs = false;
83
88
  $:
84
89
  numberOfPages = Math.floor(data.length / paginate) + 1;
85
90
  const sort = (column, toggleAscending = true) => {
@@ -117,14 +122,15 @@ const sort = (column, toggleAscending = true) => {
117
122
  sortBy = column;
118
123
  };
119
124
  sort(sortBy, false);
125
+ onMount(() => clientJs = true);
120
126
  </script>
121
127
 
122
- <table class={tableClass} id={tableId}>
123
- <thead class={tHeadClass}>
124
- <tr class={tHeadTrClass}>
128
+ <table class={classTable} id={idTable}>
129
+ <thead class={classThead}>
130
+ <tr class={classTheadTr}>
125
131
  {#each columns as column}
126
132
  <th
127
- class="{thClass} {sortBy === column ? sortedThClass : ''}"
133
+ class="{classTh} {sortBy === column ? classThSorted : ''}"
128
134
  on:click={() => sort(column)}
129
135
  >
130
136
  {column}
@@ -132,14 +138,14 @@ sort(sortBy, false);
132
138
  {/each}
133
139
  </tr>
134
140
  </thead>
135
- <tbody class={tBodyClass}>
141
+ <tbody class={classTbody}>
136
142
  {#each data as row, i}
137
143
  {@const showRow =
138
144
  i < paginate * currentPage && i >= paginate * (currentPage - 1)}
139
145
  {#if paginate ? showRow : true}
140
- <tr class={tBodyTrClass}>
146
+ <tr class={classTbodyTr}>
141
147
  {#each columns as column}
142
- <td class="{tdClass} {sortBy === column ? sortedTdClass : ''}">
148
+ <td class="{classTd} {sortBy === column ? classTdSorted : ''}">
143
149
  {row[column]}
144
150
  </td>
145
151
  {/each}
@@ -150,23 +156,29 @@ sort(sortBy, false);
150
156
  </table>
151
157
 
152
158
  {#if paginate}
153
- <div class={footerClass}>
154
- <div class={pageNumberClass}>{currentPage} / {numberOfPages}</div>
155
- <div class={pageControlsClass}>
159
+ <div class={classFooter}>
160
+ <div class={classPageNumber}>{currentPage} / {numberOfPages}</div>
161
+ <div class={classPageControls}>
156
162
  <button
157
- class={buttonClass}
158
- disabled={currentPage < 2}
163
+ class={classButton}
164
+ disabled={!clientJs || currentPage < 2}
159
165
  on:click={() => currentPage--}
160
166
  >
161
167
  <slot name="previous">Previous</slot>
162
168
  </button>
163
169
  <button
164
- class={buttonClass}
165
- disabled={currentPage >= numberOfPages}
170
+ class={classButton}
171
+ disabled={!clientJs || currentPage >= numberOfPages}
166
172
  on:click={() => currentPage++}
167
173
  >
168
174
  <slot name="next">Next</slot>
169
175
  </button>
170
176
  </div>
171
177
  </div>
178
+
179
+ <noscript>
180
+ <div class={classNoscript}>
181
+ {messageNoScript}
182
+ </div>
183
+ </noscript>
172
184
  {/if}
@@ -8,22 +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 */ tableClass?: string | undefined;
12
- /** table id */ tableId?: string | undefined;
13
- /** thead class */ tHeadClass?: string | undefined;
14
- /** tbody class */ tBodyClass?: string | undefined;
15
- /** thead tr class */ tHeadTrClass?: string | undefined;
16
- /** tbody tr class */ tBodyTrClass?: string | undefined;
17
- /** th class */ thClass?: string | undefined;
18
- /** td class */ tdClass?: string | undefined;
19
- /** currently sorted th */ sortedThClass?: string | undefined;
20
- /** currently sorted td */ sortedTdClass?: string | undefined;
21
- /** button class */ buttonClass?: string | undefined;
22
- /** footer class */ footerClass?: string | undefined;
23
- /** class of `div` wrapping page numbers */ pageNumberClass?: string | undefined;
24
- /** class of `div` that wraps the "Previous" and "Next" buttons */ pageControlsClass?: 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
+ /** class of `div` wrapping page numbers */ classPageNumber?: string | undefined;
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
28
  };
28
29
  events: {
29
30
  [evt: string]: CustomEvent<any>;
@@ -44,25 +45,26 @@ export type DataTableSlots = typeof __propDef.slots;
44
45
  * @props
45
46
  *
46
47
  * - `ascending` - default sort order
47
- * - `buttonClass` - button class
48
+ * - `classButton` - button class
49
+ * - `classFooter` - footer class
50
+ * - `classNoscript` - noscript class
51
+ * - `classPageControls` - class of `div` that wraps the "Previous" and "Next" buttons
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
48
62
  * - `columns` - table columns, in order
49
63
  * - `currentPage` - current page, defaults to `1`
50
64
  * - `data` - a list of objects to render in the table
51
- * - `footerClass` - footer class
52
- * - `pageControlsClass` - class of `div` that wraps the "Previous" and "Next" buttons
53
- * - `pageNumberClass` - class of `div` wrapping page numbers
65
+ * - `idTable` - table id
54
66
  * - `paginate` - number of rows to show on each page, defaults to `0` - no pagination
55
67
  * - `sortBy` - column to sort by--defaults to first column
56
- * - `sortedTdClass` - currently sorted td
57
- * - `sortedThClass` - currently sorted th
58
- * - `tBodyClass` - tbody class
59
- * - `tBodyTrClass` - tbody tr class
60
- * - `tHeadClass` - thead class
61
- * - `tHeadTrClass` - thead tr class
62
- * - `tableClass` - table class
63
- * - `tableId` - table id
64
- * - `tdClass` - td class
65
- * - `thClass` - th class
66
68
  *
67
69
  * @slots
68
70
  *
@@ -7,17 +7,18 @@ Text editor with controls to add elements and keyboard shortcuts.
7
7
 
8
8
  @props
9
9
 
10
- - `buttonClass` - `class` of all the `button` elements
10
+ - `classButton` - `class` of all the `button` elements
11
+ - `classControls` - `class` of the `div` that wraps the controls
12
+ - `classNoscript` - noscript class
13
+ - `classTextarea` - `class` of the `textarea` element
11
14
  - `contentElements` - an array of content elements for the controls
12
- - `controlsClass` - `class` of the `div` that wraps the controls
13
- - `controlsId` - `id` of the `div` that wraps the controls
15
+ - `idControls` - `id` of the `div` that wraps the controls
16
+ - `idTextarea` - `id` of the `textarea` element
14
17
  - `keyPairs` - keys that will auto-close if typed, value is their closing character
18
+ - `nameTextarea` - `name` of the `textarea` element
19
+ - `placeholderTextarea` - `placeholder` of the `textarea` element
15
20
  - `selectionStart` - `selectionStart` value of the text area
16
- - `textAreaClass` - `class` of the `textarea` element
17
- - `textAreaId` - `id` of the `textarea` element
18
- - `textAreaName` - `name` of the `textarea` element
19
- - `textAreaPlaceholder` - `placeholder` of the `textarea` element
20
- - `textAreaValue` - `value` of the `textarea` element
21
+ - `valueTextarea` - `value` of the `textarea` element
21
22
 
22
23
  @example
23
24
 
@@ -55,15 +56,17 @@ Text editor with controls to add elements and keyboard shortcuts.
55
56
 
56
57
  <script context="module"></script>
57
58
 
58
- <script>export let contentElements = [];
59
- export let textAreaValue = "";
60
- export let textAreaPlaceholder = "";
61
- export let textAreaClass = "";
62
- export let textAreaId = "";
63
- export let textAreaName = "";
64
- export let buttonClass = "";
65
- export let controlsClass = "";
66
- export let controlsId = "";
59
+ <script>import { onMount } from "svelte";
60
+ import { messageNoScript } from "../util/messages";
61
+ export let contentElements = [];
62
+ export let valueTextarea = "";
63
+ export let placeholderTextarea = "";
64
+ export let classTextarea = "";
65
+ export let idTextarea = "";
66
+ export let nameTextarea = "";
67
+ export let classButton = "";
68
+ export let classControls = "";
69
+ export let idControls = "";
67
70
  export let selectionStart = 0;
68
71
  export let keyPairs = {
69
72
  "(": ")",
@@ -73,6 +76,8 @@ export let keyPairs = {
73
76
  '"': '"',
74
77
  "`": "`"
75
78
  };
79
+ export let classNoscript = "";
80
+ let clientJs = false;
76
81
  let textArea;
77
82
  contentElements.forEach((el) => {
78
83
  if (el.display === "wrap")
@@ -87,11 +92,11 @@ const removeChar = (str, index) => {
87
92
  };
88
93
  const insertText = async (el, selectionStart2, selectionEnd) => {
89
94
  if (el.display === "inline") {
90
- textAreaValue = `${textAreaValue.slice(0, selectionEnd)}${el.text}${textAreaValue.slice(selectionEnd)}`;
95
+ valueTextarea = `${valueTextarea.slice(0, selectionEnd)}${el.text}${valueTextarea.slice(selectionEnd)}`;
91
96
  } else if (el.display === "wrap") {
92
- textAreaValue = insertChar(textAreaValue, el.text, selectionStart2);
93
- textAreaValue = insertChar(
94
- textAreaValue,
97
+ valueTextarea = insertChar(valueTextarea, el.text, selectionStart2);
98
+ valueTextarea = insertChar(
99
+ valueTextarea,
95
100
  keyPairs[el.text],
96
101
  selectionEnd + el.text.length
97
102
  );
@@ -104,15 +109,15 @@ const insertText = async (el, selectionStart2, selectionEnd) => {
104
109
  } else {
105
110
  lines[lineNumber] = el.text + lines[lineNumber];
106
111
  }
107
- textAreaValue = lines.join("\n");
112
+ valueTextarea = lines.join("\n");
108
113
  }
109
114
  };
110
115
  const setCaretPosition = async (text, selectionStart2, selectionEnd) => {
111
116
  let startPos = 0;
112
117
  let endPos = 0;
113
118
  if (/[a-z]/i.test(text)) {
114
- for (let i = selectionEnd; i < textAreaValue.length; i++) {
115
- if (textAreaValue[i].match(/[a-z]/i)) {
119
+ for (let i = selectionEnd; i < valueTextarea.length; i++) {
120
+ if (valueTextarea[i].match(/[a-z]/i)) {
116
121
  if (!startPos) {
117
122
  startPos = i;
118
123
  } else {
@@ -137,17 +142,17 @@ const addContent = async (el) => {
137
142
  };
138
143
  const onKeyDown = async (e) => {
139
144
  const resetKeys = ["ArrowUp", "ArrowDown", "Delete"];
140
- const nextChar = textAreaValue[textArea.selectionEnd];
145
+ const nextChar = valueTextarea[textArea.selectionEnd];
141
146
  if (resetKeys.includes(e.key)) {
142
147
  openChars = [];
143
148
  } else if (e.key === "Backspace") {
144
- const prevChar = textAreaValue[textArea.selectionStart - 1];
149
+ const prevChar = valueTextarea[textArea.selectionStart - 1];
145
150
  if (prevChar in keyPairs && nextChar === keyPairs[prevChar]) {
146
151
  e.preventDefault();
147
152
  const start = textArea.selectionStart - 1;
148
153
  const end = textArea.selectionEnd - 1;
149
- textAreaValue = removeChar(textAreaValue, start);
150
- textAreaValue = removeChar(textAreaValue, end);
154
+ valueTextarea = removeChar(valueTextarea, start);
155
+ valueTextarea = removeChar(valueTextarea, end);
151
156
  setTimeout(() => {
152
157
  textArea.setSelectionRange(start, end);
153
158
  }, 0);
@@ -158,7 +163,7 @@ const onKeyDown = async (e) => {
158
163
  const newPos = textArea.selectionStart - 1;
159
164
  const { lineNumber } = getLineInfo();
160
165
  correctFollowing(lineNumber, true);
161
- textAreaValue = removeChar(textAreaValue, newPos);
166
+ valueTextarea = removeChar(valueTextarea, newPos);
162
167
  setTimeout(async () => {
163
168
  textArea.setSelectionRange(newPos, newPos);
164
169
  }, 0);
@@ -197,8 +202,8 @@ ${repeat}`,
197
202
  const selectionEnd = textArea.selectionEnd;
198
203
  const newPos = selectionEnd - original.length;
199
204
  for (let i = 0; i < original.length; i++) {
200
- textAreaValue = removeChar(
201
- textAreaValue,
205
+ valueTextarea = removeChar(
206
+ valueTextarea,
202
207
  textArea.selectionEnd - (i + 1)
203
208
  );
204
209
  }
@@ -242,13 +247,13 @@ ${repeat}`,
242
247
  };
243
248
  const trimSelection = () => {
244
249
  if (textArea.selectionStart !== textArea.selectionEnd) {
245
- if (textAreaValue[textArea.selectionStart] === " ") {
250
+ if (valueTextarea[textArea.selectionStart] === " ") {
246
251
  textArea.setSelectionRange(
247
252
  textArea.selectionStart + 1,
248
253
  textArea.selectionEnd
249
254
  );
250
255
  }
251
- if (textAreaValue[textArea.selectionEnd - 1] === " ") {
256
+ if (valueTextarea[textArea.selectionEnd - 1] === " ") {
252
257
  textArea.setSelectionRange(
253
258
  textArea.selectionStart,
254
259
  textArea.selectionEnd - 1
@@ -260,7 +265,7 @@ const updateSelectionStart = () => {
260
265
  selectionStart = textArea.selectionStart;
261
266
  };
262
267
  const getLineInfo = () => {
263
- const lines = textAreaValue.split("\n");
268
+ const lines = valueTextarea.split("\n");
264
269
  let characterCount = 0;
265
270
  for (let i = 0; i < lines.length; i++) {
266
271
  characterCount++;
@@ -276,7 +281,7 @@ const getLineInfo = () => {
276
281
  return { lines, lineNumber: 0, columnNumber: 0 };
277
282
  };
278
283
  const getCurrentBlock = () => {
279
- const blocks = textAreaValue.split("```");
284
+ const blocks = valueTextarea.split("```");
280
285
  let totalChars = 0;
281
286
  for (const [i, block] of blocks.entries()) {
282
287
  totalChars += block.length + 3;
@@ -328,19 +333,20 @@ const correctFollowing = (currentLineNumber, decrement = false) => {
328
333
  lines[i] = String(newNum) + lines[i];
329
334
  }
330
335
  }
331
- textAreaValue = lines.join("\n");
336
+ valueTextarea = lines.join("\n");
332
337
  };
338
+ onMount(() => clientJs = true);
333
339
  </script>
334
340
 
335
341
  <textarea
336
- id={textAreaId}
337
- class={textAreaClass}
338
- name={textAreaName}
339
- placeholder={textAreaPlaceholder}
342
+ id={idTextarea}
343
+ class={classTextarea}
344
+ name={nameTextarea}
345
+ placeholder={placeholderTextarea}
340
346
  on:keydown={onKeyDown}
341
347
  on:keyup={updateSelectionStart}
342
348
  on:dblclick={trimSelection}
343
- bind:value={textAreaValue}
349
+ bind:value={valueTextarea}
344
350
  bind:this={textArea}
345
351
  on:click={() => {
346
352
  openChars = [];
@@ -348,13 +354,14 @@ const correctFollowing = (currentLineNumber, decrement = false) => {
348
354
  }}
349
355
  on:input
350
356
  />
351
- <div id={controlsId} class={controlsClass}>
357
+
358
+ <div id={idControls} class={classControls}>
352
359
  {#each contentElements as el}
353
360
  <button
354
- class={el.class ? `${buttonClass} ${el.class}` : buttonClass}
361
+ class={el.class ? `${classButton} ${el.class}` : classButton}
355
362
  on:click={() => addContent(el)}
356
363
  title={el.name}
357
- aria-label={el.name}
364
+ disabled={!clientJs}
358
365
  >
359
366
  {#if typeof el.icon !== "string"}
360
367
  <svelte:component this={el.icon} />
@@ -364,3 +371,9 @@ const correctFollowing = (currentLineNumber, decrement = false) => {
364
371
  </button>
365
372
  {/each}
366
373
  </div>
374
+
375
+ <noscript>
376
+ <div class={classNoscript}>
377
+ {messageNoScript}
378
+ </div>
379
+ </noscript>
@@ -18,22 +18,23 @@ export interface EditorContentElement {
18
18
  /** class to apply to the specific button */
19
19
  class?: string;
20
20
  }
21
- import type { ComponentType } from "svelte";
21
+ import { type ComponentType } from "svelte";
22
22
  declare const __propDef: {
23
23
  props: {
24
24
  /** an array of content elements for the controls */ contentElements?: EditorContentElement[] | undefined;
25
- /** `value` of the `textarea` element */ textAreaValue?: string | undefined;
26
- /** `placeholder` of the `textarea` element */ textAreaPlaceholder?: string | undefined;
27
- /** `class` of the `textarea` element */ textAreaClass?: string | undefined;
28
- /** `id` of the `textarea` element */ textAreaId?: string | undefined;
29
- /** `name` of the `textarea` element */ textAreaName?: string | undefined;
30
- /** `class` of all the `button` elements */ buttonClass?: string | undefined;
31
- /** `class` of the `div` that wraps the controls */ controlsClass?: string | undefined;
32
- /** `id` of the `div` that wraps the controls */ controlsId?: string | undefined;
25
+ /** `value` of the `textarea` element */ valueTextarea?: string | undefined;
26
+ /** `placeholder` of the `textarea` element */ placeholderTextarea?: string | undefined;
27
+ /** `class` of the `textarea` element */ classTextarea?: string | undefined;
28
+ /** `id` of the `textarea` element */ idTextarea?: string | undefined;
29
+ /** `name` of the `textarea` element */ nameTextarea?: string | undefined;
30
+ /** `class` of all the `button` elements */ classButton?: string | undefined;
31
+ /** `class` of the `div` that wraps the controls */ classControls?: string | undefined;
32
+ /** `id` of the `div` that wraps the controls */ idControls?: string | undefined;
33
33
  /** `selectionStart` value of the text area */ selectionStart?: number | undefined;
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
38
  };
38
39
  events: {
39
40
  input: Event;
@@ -52,17 +53,18 @@ export type EditorSlots = typeof __propDef.slots;
52
53
  *
53
54
  * @props
54
55
  *
55
- * - `buttonClass` - `class` of all the `button` elements
56
+ * - `classButton` - `class` of all the `button` elements
57
+ * - `classControls` - `class` of the `div` that wraps the controls
58
+ * - `classNoscript` - noscript class
59
+ * - `classTextarea` - `class` of the `textarea` element
56
60
  * - `contentElements` - an array of content elements for the controls
57
- * - `controlsClass` - `class` of the `div` that wraps the controls
58
- * - `controlsId` - `id` of the `div` that wraps the controls
61
+ * - `idControls` - `id` of the `div` that wraps the controls
62
+ * - `idTextarea` - `id` of the `textarea` element
59
63
  * - `keyPairs` - keys that will auto-close if typed, value is their closing character
64
+ * - `nameTextarea` - `name` of the `textarea` element
65
+ * - `placeholderTextarea` - `placeholder` of the `textarea` element
60
66
  * - `selectionStart` - `selectionStart` value of the text area
61
- * - `textAreaClass` - `class` of the `textarea` element
62
- * - `textAreaId` - `id` of the `textarea` element
63
- * - `textAreaName` - `name` of the `textarea` element
64
- * - `textAreaPlaceholder` - `placeholder` of the `textarea` element
65
- * - `textAreaValue` - `value` of the `textarea` element
67
+ * - `valueTextarea` - `value` of the `textarea` element
66
68
  *
67
69
  * @example
68
70
  *
@@ -7,6 +7,7 @@ Make the document or a specific element fullscreen.
7
7
 
8
8
  @props
9
9
 
10
+ - `classNoscript` - noscript class
10
11
  - `class`
11
12
  - `confirmMessage` - message to display in the `confirm` popup, set this to empty string `""` to disable `confirm`
12
13
  - `id`
@@ -17,8 +18,8 @@ Make the document or a specific element fullscreen.
17
18
 
18
19
  | name | purpose | default value |
19
20
  | ---------- | ---------------------------------------------- | -------------------- |
21
+ | `default` | content to display when fullscreen is disabled | `Enabled Fullscreen` |
20
22
  | `enabled` | content to display when fullscreen is enabled | `Exit Fullscreen` |
21
- | `disabled` | content to display when fullscreen is disabled | `Enabled Fullscreen` |
22
23
 
23
24
  @example
24
25
 
@@ -42,17 +43,16 @@ Make the document or a specific element fullscreen.
42
43
  -->
43
44
 
44
45
  <script>import { onMount } from "svelte";
46
+ import { messageNoScript } from "../util/messages";
45
47
  let className = "";
46
48
  export { className as class };
47
49
  export let id = "";
48
50
  export let title = "Fullscreen";
49
51
  export let targetElement = null;
50
52
  export let confirmMessage = "";
53
+ export let classNoscript = "";
54
+ let clientJs = false;
51
55
  let fullscreen = false;
52
- onMount(() => {
53
- if (!targetElement)
54
- targetElement = document.documentElement;
55
- });
56
56
  const onClick = () => {
57
57
  if (fullscreen) {
58
58
  document.exitFullscreen();
@@ -68,14 +68,25 @@ const onClick = () => {
68
68
  }
69
69
  }
70
70
  };
71
+ onMount(() => {
72
+ clientJs = true;
73
+ if (!targetElement)
74
+ targetElement = document.documentElement;
75
+ });
71
76
  </script>
72
77
 
73
78
  <svelte:window on:fullscreenchange={() => (fullscreen = !fullscreen)} />
74
79
 
75
- <button on:click={onClick} class={className} {id} {title}>
80
+ <button disabled={!clientJs} on:click={onClick} class={className} {id} {title}>
76
81
  {#if fullscreen}
77
82
  <slot name="enabled">Exit Fullscreen</slot>
78
83
  {:else}
79
- <slot name="disabled">Enable Fullscreen</slot>
84
+ <slot>Enable Fullscreen</slot>
80
85
  {/if}
81
86
  </button>
87
+
88
+ <noscript>
89
+ <div class={classNoscript}>
90
+ {messageNoScript}
91
+ </div>
92
+ </noscript>
@@ -6,13 +6,14 @@ 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
10
  };
10
11
  events: {
11
12
  [evt: string]: CustomEvent<any>;
12
13
  };
13
14
  slots: {
14
15
  enabled: {};
15
- disabled: {};
16
+ default: {};
16
17
  };
17
18
  };
18
19
  export type FullscreenButtonProps = typeof __propDef.props;
@@ -25,6 +26,7 @@ export type FullscreenButtonSlots = typeof __propDef.slots;
25
26
  *
26
27
  * @props
27
28
  *
29
+ * - `classNoscript` - noscript class
28
30
  * - `class`
29
31
  * - `confirmMessage` - message to display in the `confirm` popup, set this to empty string `""` to disable `confirm`
30
32
  * - `id`
@@ -35,8 +37,8 @@ export type FullscreenButtonSlots = typeof __propDef.slots;
35
37
  *
36
38
  * | name | purpose | default value |
37
39
  * | ---------- | ---------------------------------------------- | -------------------- |
40
+ * | `default` | content to display when fullscreen is disabled | `Enabled Fullscreen` |
38
41
  * | `enabled` | content to display when fullscreen is enabled | `Exit Fullscreen` |
39
- * | `disabled` | content to display when fullscreen is disabled | `Enabled Fullscreen` |
40
42
  *
41
43
  * @example
42
44
  *
@@ -0,0 +1,155 @@
1
+ <!--
2
+ @component
3
+
4
+ ### Popover
5
+
6
+ Displays a popover relatively positioned to the button.
7
+
8
+ @props
9
+
10
+ - `classButton` - button class
11
+ - `classPopover` - popover class
12
+ - `class`
13
+ - `display` - if `eventType="click"`, controls the display
14
+ - `eventType` - controls if hovering or clicking the button displays the popover
15
+ - `idButton` - button id
16
+ - `idPopover` - popover id
17
+ - `id`
18
+ - `position` - where the popover is displayed in relation to the button
19
+
20
+ @slots
21
+
22
+ | name | purpose | default value |
23
+ | ---------- | ------------------------------- | ------------- |
24
+ | `default` | default | Popover |
25
+ | `button` | button contents | Open |
26
+
27
+ @example
28
+
29
+ ```svelte
30
+ <script>
31
+ import { Popover } from "drab";
32
+ </script>
33
+
34
+ <Popover>
35
+ <span slot="button">Hover</span>
36
+ <div>
37
+ <div>Popover</div>
38
+ <button>Button</button>
39
+ <button>Button</button>
40
+ <button>Button</button>
41
+ </div>
42
+ </Popover>
43
+ ```
44
+ -->
45
+
46
+ <script>import { onMount, tick } from "svelte";
47
+ let className = "";
48
+ export { className as class };
49
+ export let id = "";
50
+ export let classButton = "";
51
+ export let classPopover = "";
52
+ export let idButton = "";
53
+ export let idPopover = "";
54
+ export let display = false;
55
+ export let position = "bottom";
56
+ export let eventType = "hover";
57
+ let clientEventType = "hover";
58
+ let popover;
59
+ let button;
60
+ let coordinates = { x: 0, y: 0 };
61
+ const correctPosition = async () => {
62
+ if (position === "top" || position === "bottom") {
63
+ coordinates.x = button.offsetWidth / 2 - popover.offsetWidth / 2;
64
+ if (position === "top") {
65
+ coordinates.y = -popover.offsetHeight;
66
+ } else {
67
+ coordinates.y = button.offsetHeight;
68
+ }
69
+ } else {
70
+ coordinates.y = button.offsetHeight / 2 - popover.offsetHeight / 2;
71
+ if (position === "left") {
72
+ coordinates.x = -popover.offsetWidth;
73
+ } else {
74
+ coordinates.x = button.offsetWidth;
75
+ }
76
+ }
77
+ await tick();
78
+ const rect = popover.getBoundingClientRect();
79
+ if (rect.x < 0) {
80
+ coordinates.x += Math.abs(rect.x);
81
+ } else if (rect.x + popover.offsetWidth > window.innerWidth) {
82
+ coordinates.x -= rect.x + popover.offsetWidth - window.innerWidth + 16;
83
+ }
84
+ if (rect.y < 0) {
85
+ coordinates.y += Math.abs(rect.y);
86
+ } else if (rect.y + popover.offsetHeight > window.innerHeight) {
87
+ coordinates.y -= rect.y + popover.offsetHeight - window.innerHeight;
88
+ }
89
+ };
90
+ const clickOutside = (e) => {
91
+ if (popover && e.target instanceof HTMLElement) {
92
+ if (!popover.contains(e.target)) {
93
+ display = false;
94
+ }
95
+ }
96
+ };
97
+ const onKeyDown = (e) => {
98
+ if (e.key === "Escape") {
99
+ display = false;
100
+ }
101
+ };
102
+ const openPopover = async (e) => {
103
+ e.stopPropagation();
104
+ display = true;
105
+ };
106
+ onMount(() => {
107
+ clientEventType = eventType;
108
+ correctPosition();
109
+ });
110
+ </script>
111
+
112
+ <svelte:document on:keydown={onKeyDown} on:click={clickOutside} />
113
+
114
+ <div class="db-relative {className}" {id}>
115
+ <button
116
+ bind:this={button}
117
+ id={idButton}
118
+ class={classButton}
119
+ on:click={openPopover}
120
+ on:mouseover={correctPosition}
121
+ on:focus={correctPosition}
122
+ >
123
+ <slot name="button">Open</slot>
124
+ </button>
125
+ <div
126
+ bind:this={popover}
127
+ id={idPopover}
128
+ class="db-popover {classPopover}"
129
+ class:db-type-click={clientEventType === "click" && display}
130
+ class:db-type-hover={clientEventType === "hover"}
131
+ style:top="{coordinates.y}px"
132
+ style:left="{coordinates.x}px"
133
+ >
134
+ <slot>Popover</slot>
135
+ </div>
136
+ </div>
137
+
138
+ <style>
139
+ .db-relative {
140
+ position: relative;
141
+ }
142
+ .db-popover {
143
+ position: absolute;
144
+ opacity: 0;
145
+ z-index: -10;
146
+ }
147
+ button:hover + .db-type-hover,
148
+ button:focus + .db-type-hover,
149
+ .db-type-hover:hover,
150
+ .db-type-hover:focus-within,
151
+ .db-type-click {
152
+ opacity: 1;
153
+ z-index: 10;
154
+ }
155
+ </style>
@@ -0,0 +1,69 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ class?: string | undefined;
5
+ id?: string | undefined;
6
+ /** button class */ classButton?: string | undefined;
7
+ /** popover class */ classPopover?: string | undefined;
8
+ /** button id */ idButton?: string | undefined;
9
+ /** popover id */ idPopover?: string | undefined;
10
+ /** if `eventType="click"`, controls the display */ display?: boolean | undefined;
11
+ /** where the popover is displayed in relation to the button */ position?: "top" | "bottom" | "left" | "right" | undefined;
12
+ /** controls if hovering or clicking the button displays the popover */ eventType?: ("click" | "hover") | undefined;
13
+ };
14
+ events: {
15
+ [evt: string]: CustomEvent<any>;
16
+ };
17
+ slots: {
18
+ button: {};
19
+ default: {};
20
+ };
21
+ };
22
+ export type PopoverProps = typeof __propDef.props;
23
+ export type PopoverEvents = typeof __propDef.events;
24
+ export type PopoverSlots = typeof __propDef.slots;
25
+ /**
26
+ * ### Popover
27
+ *
28
+ * Displays a popover relatively positioned to the button.
29
+ *
30
+ * @props
31
+ *
32
+ * - `classButton` - button class
33
+ * - `classPopover` - popover class
34
+ * - `class`
35
+ * - `display` - if `eventType="click"`, controls the display
36
+ * - `eventType` - controls if hovering or clicking the button displays the popover
37
+ * - `idButton` - button id
38
+ * - `idPopover` - popover id
39
+ * - `id`
40
+ * - `position` - where the popover is displayed in relation to the button
41
+ *
42
+ * @slots
43
+ *
44
+ * | name | purpose | default value |
45
+ * | ---------- | ------------------------------- | ------------- |
46
+ * | `default` | default | Popover |
47
+ * | `button` | button contents | Open |
48
+ *
49
+ * @example
50
+ *
51
+ * ```svelte
52
+ * <script>
53
+ * import { Popover } from "drab";
54
+ * </script>
55
+ *
56
+ * <Popover>
57
+ * <span slot="button">Hover</span>
58
+ * <div>
59
+ * <div>Popover</div>
60
+ * <button>Button</button>
61
+ * <button>Button</button>
62
+ * <button>Button</button>
63
+ * </div>
64
+ * </Popover>
65
+ * ```
66
+ */
67
+ export default class Popover extends SvelteComponent<PopoverProps, PopoverEvents, PopoverSlots> {
68
+ }
69
+ export {};
@@ -7,10 +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
11
  - `class`
11
12
  - `id`
12
13
  - `text` - prefixed text in share message
13
- - `title` - title of share message and button attribute
14
+ - `title` - title of share message and button attribute, defaults to end of url
14
15
  - `url` - url to be shared
15
16
 
16
17
  @slots
@@ -35,12 +36,15 @@ Uses the navigator api to share or copy a url link depending on browser support.
35
36
  ```
36
37
  -->
37
38
 
38
- <script>let className = "";
39
+ <script>import { onMount } from "svelte";
40
+ let className = "";
39
41
  export { className as class };
40
42
  export let id = "";
41
43
  export let text = "";
42
44
  export let url;
43
45
  export let title = url.split("/").splice(-1)[0];
46
+ export let classNoscript = "";
47
+ let clientJs = false;
44
48
  let complete = false;
45
49
  const onClick = async () => {
46
50
  try {
@@ -55,12 +59,15 @@ const onClick = async () => {
55
59
  console.log(error);
56
60
  }
57
61
  };
62
+ onMount(() => clientJs = true);
58
63
  </script>
59
64
 
60
- <button on:click={onClick} class={className} {id} {title}>
65
+ <button disabled={!clientJs} on:click={onClick} class={className} {id} {title}>
61
66
  {#if complete}
62
67
  <slot name="complete">Copied</slot>
63
68
  {:else}
64
69
  <slot>Share</slot>
65
70
  {/if}
66
71
  </button>
72
+
73
+ <noscript><span class={classNoscript}>{url}</span></noscript>
@@ -5,7 +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 */ title?: string | undefined;
8
+ /** title of share message and button attribute, defaults to end of url */ title?: string | undefined;
9
+ /** noscript class */ classNoscript?: string | undefined;
9
10
  };
10
11
  events: {
11
12
  [evt: string]: CustomEvent<any>;
@@ -25,10 +26,11 @@ export type ShareButtonSlots = typeof __propDef.slots;
25
26
  *
26
27
  * @props
27
28
  *
29
+ * - `classNoscript` - noscript class
28
30
  * - `class`
29
31
  * - `id`
30
32
  * - `text` - prefixed text in share message
31
- * - `title` - title of share message and button attribute
33
+ * - `title` - title of share message and button attribute, defaults to end of url
32
34
  * - `url` - url to be shared
33
35
  *
34
36
  * @slots
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import Chord from "./components/Chord.svelte";
2
+ import type { ChordNote } from "./components/Chord.svelte";
2
3
  import ContextMenu from "./components/ContextMenu.svelte";
3
4
  import CopyButton from "./components/CopyButton.svelte";
4
5
  import DataTable from "./components/DataTable.svelte";
@@ -6,6 +7,7 @@ import type { DataTableRow } from "./components/DataTable.svelte";
6
7
  import Editor from "./components/Editor.svelte";
7
8
  import type { EditorContentElement } from "./components/Editor.svelte";
8
9
  import FullscreenButton from "./components/FullscreenButton.svelte";
10
+ import Popover from "./components/Popover.svelte";
9
11
  import ShareButton from "./components/ShareButton.svelte";
10
12
  import YouTube from "./components/YouTube.svelte";
11
- export { Chord, ContextMenu, CopyButton, DataTable, type DataTableRow, Editor, type EditorContentElement, FullscreenButton, ShareButton, YouTube, };
13
+ export { Chord, type ChordNote, ContextMenu, CopyButton, DataTable, type DataTableRow, Editor, type EditorContentElement, FullscreenButton, Popover, ShareButton, YouTube, };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import CopyButton from "./components/CopyButton.svelte";
4
4
  import DataTable from "./components/DataTable.svelte";
5
5
  import Editor from "./components/Editor.svelte";
6
6
  import FullscreenButton from "./components/FullscreenButton.svelte";
7
+ import Popover from "./components/Popover.svelte";
7
8
  import ShareButton from "./components/ShareButton.svelte";
8
9
  import YouTube from "./components/YouTube.svelte";
9
- export { Chord, ContextMenu, CopyButton, DataTable, Editor, FullscreenButton, ShareButton, YouTube, };
10
+ export { Chord, ContextMenu, CopyButton, DataTable, Editor, FullscreenButton, Popover, ShareButton, YouTube, };
@@ -0,0 +1 @@
1
+ export declare const messageNoScript = "JavaScript is disabled on your device. This feature requires JavaScript for full functionality.";
@@ -0,0 +1 @@
1
+ export const messageNoScript = "JavaScript is disabled on your device. This feature requires JavaScript for full functionality.";
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "drab",
3
- "version": "1.10.1",
3
+ "version": "2.1.0",
4
4
  "description": "An unstyled Svelte component library",
5
5
  "keywords": [
6
6
  "components",
7
7
  "Svelte",
8
8
  "SvelteKit",
9
9
  "Chord",
10
+ "ContextMenu",
10
11
  "Copy",
11
12
  "DataTable",
12
13
  "Editor",
13
14
  "Fullscreen",
15
+ "Popover",
14
16
  "Share",
15
17
  "YouTube"
16
18
  ],
@@ -48,8 +50,8 @@
48
50
  },
49
51
  "devDependencies": {
50
52
  "@sveltejs/adapter-vercel": "^3.0.3",
51
- "@sveltejs/kit": "^1.22.4",
52
- "@sveltejs/package": "^2.2.0",
53
+ "@sveltejs/kit": "^1.22.5",
54
+ "@sveltejs/package": "^2.2.1",
53
55
  "@tailwindcss/typography": "^0.5.9",
54
56
  "@types/node": "^20.4.9",
55
57
  "@typescript-eslint/eslint-plugin": "^6.3.0",
@@ -61,7 +63,7 @@
61
63
  "postcss": "^8.4.27",
62
64
  "prettier": "^3.0.1",
63
65
  "prettier-plugin-svelte": "^3.0.3",
64
- "prettier-plugin-tailwindcss": "^0.4.1",
66
+ "prettier-plugin-tailwindcss": "^0.5.1",
65
67
  "publint": "^0.2.0",
66
68
  "svelte-check": "^3.4.6",
67
69
  "tailwindcss": "^3.3.3",