@bexis2/bexis2-core-ui 0.4.19 → 0.4.21

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.
Files changed (53) hide show
  1. package/README.md +18 -8
  2. package/dist/components/CodeEditor/CodeEditor.svelte +4 -0
  3. package/dist/components/Facets/Facets.svelte +23 -10
  4. package/dist/components/Facets/ShowMore.svelte +30 -17
  5. package/dist/components/Facets/ShowMore.svelte.d.ts +1 -1
  6. package/dist/components/File/FileUploader.svelte +1 -1
  7. package/dist/components/Table/ColumnsMenu.svelte +5 -0
  8. package/dist/components/Table/TableContent.svelte +13 -3
  9. package/dist/components/Table/TableFilter.svelte +12 -0
  10. package/dist/components/Table/TableFilterServer.svelte +13 -1
  11. package/dist/components/Table/TablePagination.svelte +10 -1
  12. package/dist/components/Table/TablePaginationServer.svelte +8 -0
  13. package/dist/components/form/Checkbox.svelte +1 -1
  14. package/dist/components/form/CheckboxKvPList.svelte +2 -1
  15. package/dist/components/form/CheckboxList.svelte +2 -2
  16. package/dist/components/form/DateInput.svelte +1 -1
  17. package/dist/components/form/DropdownKvP.svelte +1 -1
  18. package/dist/components/form/InputContainer.svelte +7 -1
  19. package/dist/components/form/MultiSelect.svelte +100 -106
  20. package/dist/components/form/NumberInput.svelte +1 -1
  21. package/dist/components/form/TextArea.svelte +1 -1
  22. package/dist/components/form/TextInput.svelte +1 -1
  23. package/dist/components/page/Alert.svelte +1 -1
  24. package/dist/components/page/BackToTop.svelte +1 -1
  25. package/dist/components/page/GoToTop.svelte +1 -0
  26. package/dist/components/page/HelpPopUp.svelte +1 -0
  27. package/dist/components/page/Page.svelte +5 -4
  28. package/package.json +1 -1
  29. package/src/lib/components/CodeEditor/CodeEditor.svelte +4 -0
  30. package/src/lib/components/Facets/Facets.svelte +28 -12
  31. package/src/lib/components/Facets/ShowMore.svelte +31 -17
  32. package/src/lib/components/File/FileUploader.svelte +1 -1
  33. package/src/lib/components/Table/ColumnsMenu.svelte +5 -0
  34. package/src/lib/components/Table/TableContent.svelte +13 -3
  35. package/src/lib/components/Table/TableFilter.svelte +12 -0
  36. package/src/lib/components/Table/TableFilterServer.svelte +13 -1
  37. package/src/lib/components/Table/TablePagination.svelte +10 -1
  38. package/src/lib/components/Table/TablePaginationServer.svelte +8 -0
  39. package/src/lib/components/form/Checkbox.svelte +1 -1
  40. package/src/lib/components/form/CheckboxKvPList.svelte +2 -1
  41. package/src/lib/components/form/CheckboxList.svelte +2 -2
  42. package/src/lib/components/form/DateInput.svelte +1 -1
  43. package/src/lib/components/form/DropdownKvP.svelte +1 -1
  44. package/src/lib/components/form/InputContainer.svelte +7 -1
  45. package/src/lib/components/form/MultiSelect.svelte +100 -106
  46. package/src/lib/components/form/NumberInput.svelte +1 -1
  47. package/src/lib/components/form/TextArea.svelte +1 -1
  48. package/src/lib/components/form/TextInput.svelte +1 -1
  49. package/src/lib/components/page/Alert.svelte +1 -1
  50. package/src/lib/components/page/BackToTop.svelte +1 -1
  51. package/src/lib/components/page/GoToTop.svelte +1 -0
  52. package/src/lib/components/page/HelpPopUp.svelte +1 -0
  53. package/src/lib/components/page/Page.svelte +5 -4
package/README.md CHANGED
@@ -1,13 +1,23 @@
1
1
  # bexis-core-ui
2
+
3
+ ## 0.4.21
4
+ - change footer position in page component
5
+
6
+ ## 0.4.20
7
+ - Add aria-label to Table and other components
8
+ - Facets
9
+ - Add aria-label to Facets component
10
+ - sort by count if exists, reorder more view, truncate long names,
11
+ - Search
12
+ - Add aria-label to Search component
13
+ - Table: add column
2
14
  ## 0.4.19
15
+
3
16
  ## 0.4.18
4
17
  - Updates indicator text for current page and possible number of pages in a Table
5
18
  - Fixes client-side search on Table
6
19
  - Adds "No rows available" text in Table if search or filter returns no rows.
7
20
 
8
- ## 0.4.17
9
- - Table
10
- - Fix client-side search
11
21
  ## 0.4.16
12
22
  - Facets
13
23
  - Replaces groups array with a writable store to re-render component on data manipulation.
@@ -19,9 +29,9 @@
19
29
  - Adds on:change action
20
30
 
21
31
  ## 0.4.14
22
- - Table
32
+ - Table
23
33
  - fixes rendering issues with Table filters and different components
24
-
34
+
25
35
  - Facets
26
36
  - Exports Facets component
27
37
 
@@ -45,7 +55,7 @@
45
55
  - Updates the structure of server-side configuration for Tables.
46
56
  - Adds new page size dropdown in Table for to fix contrast issues in the component.
47
57
  - Adds showing/hiding Table columns.
48
-
58
+
49
59
  - Facets:
50
60
  - Adds Facets component.
51
61
 
@@ -73,7 +83,7 @@
73
83
  - update libs
74
84
  - remove eslint-plugin-svelte3
75
85
  - update svelte, sveltekit, typescript, tailwind ...
76
-
86
+
77
87
  ## 0.4.3
78
88
  - table
79
89
  - Enable searching on server-side
@@ -104,7 +114,7 @@
104
114
 
105
115
  ## 0.3.11
106
116
  - add on:change passthrough to TextInput, TextArea, DateInput, NumberInput, CheckBox
107
-
117
+
108
118
  ## 0.3.10
109
119
  - multi select
110
120
  - update svelte-select libary
@@ -82,6 +82,7 @@ $: isValid = language === "json" ? isValidJSON(value) : language === "js" ? isVa
82
82
  <div class="flex gap-2">
83
83
  <button
84
84
  class="btn variant-filled-warning"
85
+ title="Reset"
85
86
  id="{id}-reset"
86
87
  on:click|preventDefault={() => modalStore.trigger(modal)}
87
88
  ><Fa icon={faArrowRotateLeft} /></button
@@ -90,6 +91,7 @@ $: isValid = language === "json" ? isValidJSON(value) : language === "js" ? isVa
90
91
  class="btn border"
91
92
  class:bg-slate-700={dark}
92
93
  class:bg-white={!dark}
94
+ title="Toggle dark mode"
93
95
  id="{id}-toggle"
94
96
  on:click|preventDefault={() => (dark = !dark)}
95
97
  >
@@ -106,11 +108,13 @@ $: isValid = language === "json" ? isValidJSON(value) : language === "js" ? isVa
106
108
  <div class="flex gap-2">
107
109
  <button
108
110
  class="btn variant-filled-warning"
111
+ title="Cancel"
109
112
  id="{id}-cancel"
110
113
  on:click|preventDefault={() => dispatch('cancel')}><Fa icon={faXmark} /></button
111
114
  >
112
115
  <button
113
116
  class="btn variant-filled-primary"
117
+ title="Save"
114
118
  id="{id}-save"
115
119
  disabled={!isValid}
116
120
  on:click|preventDefault={() => dispatch('save')}><Fa icon={faSave} /></button
@@ -18,7 +18,7 @@ export const showMore = (groupName) => {
18
18
  ref: ShowMore,
19
19
  props: {
20
20
  group,
21
- handleSave,
21
+ handleApply,
22
22
  handleCancel
23
23
  }
24
24
  }
@@ -29,7 +29,7 @@ let selectedItems = {};
29
29
  let selectedGroups = {};
30
30
  const dispatch = createEventDispatcher();
31
31
  const modalStore = getModalStore();
32
- const handleSave = (group) => {
32
+ const handleApply = (group) => {
33
33
  const { name: groupName, children } = group;
34
34
  dispatch("showMoreOpenChange", {
35
35
  group: groupName,
@@ -90,11 +90,14 @@ const sortOptions = () => {
90
90
  if (a.count != void 0 && b.count != void 0) {
91
91
  return b.count - a.count;
92
92
  }
93
- return a.displayName.localeCompare(b.displayName);
93
+ return 0;
94
+ }).map((item) => item.name);
95
+ const unchecked = Object.keys(selected[group].children).filter((item) => !checked.includes(item)).map((item) => selected[group].children[item]).sort((a, b) => {
96
+ if (a.count != void 0 && b.count != void 0) {
97
+ return b.count - a.count;
98
+ }
99
+ return 0;
94
100
  }).map((item) => item.name);
95
- const unchecked = Object.keys(selected[group].children).filter(
96
- (item) => !checked.includes(item)
97
- );
98
101
  const groupIndex = displayedGroups.findIndex((g) => g.name === group);
99
102
  displayedGroups[groupIndex].children = [
100
103
  ...checked.map(
@@ -131,7 +134,7 @@ groups.subscribe((data) => {
131
134
  });
132
135
  });
133
136
  $: displayedGroups = structuredClone($groups);
134
- $: selectedItems, mapSelected("items");
137
+ $: selectedItems, mapSelected("items"), sortOptions();
135
138
  $: selectedGroups, mapSelected("groups");
136
139
  </script>
137
140
 
@@ -145,7 +148,7 @@ $: selectedGroups, mapSelected("groups");
145
148
  bind:checked={selectedGroups[group.name]}
146
149
  bind:group={selectedGroups}
147
150
  >
148
- <p class="font-semibold">
151
+ <p class="font-semibold whitespace-nowrap">
149
152
  {group.displayName}{group.count !== undefined ? ` (${group.count})` : ''}
150
153
  </p>
151
154
 
@@ -163,7 +166,12 @@ $: selectedGroups, mapSelected("groups");
163
166
  selection
164
167
  multiple
165
168
  >
166
- <p>{item.displayName} ({item.count})</p>
169
+ <div class="flex gap-2">
170
+ <p class="w-max grow truncate">
171
+ <span title={item.displayName}>{item.displayName}</span>
172
+ </p>
173
+ <span>({item.count})</span>
174
+ </div>
167
175
  </TreeViewItem>
168
176
  {/each}
169
177
  <!-- Trigger for the Modal to view all options -->
@@ -185,7 +193,12 @@ $: selectedGroups, mapSelected("groups");
185
193
  selection
186
194
  multiple
187
195
  >
188
- <p>{item.displayName} ({item.count})</p>
196
+ <div class="flex gap-2">
197
+ <p class="w-max grow truncate">
198
+ <span title={item.displayName}>{item.displayName}</span>
199
+ </p>
200
+ <span>({item.count})</span>
201
+ </div>
189
202
  </TreeViewItem>
190
203
  {/each}
191
204
  {/if}
@@ -1,5 +1,5 @@
1
1
  <script>export let group;
2
- export let handleSave;
2
+ export let handleApply;
3
3
  export let handleCancel;
4
4
  let selected = structuredClone(group.children);
5
5
  const selectAll = () => {
@@ -8,8 +8,8 @@ const selectAll = () => {
8
8
  const selectNone = () => {
9
9
  Object.keys(selected).forEach((key) => selected[key].selected = false);
10
10
  };
11
- const onSave = () => {
12
- handleSave({
11
+ const onApply = () => {
12
+ handleApply({
13
13
  ...group,
14
14
  children: selected
15
15
  });
@@ -20,31 +20,44 @@ const onCancel = () => {
20
20
  handleCancel(group.name);
21
21
  };
22
22
  const gridClass = (items) => {
23
- if (items.length >= 50) {
24
- return "grid-cols-5";
25
- } else if (items.length >= 30) {
26
- return "grid-cols-4";
27
- } else if (items.length >= 20) {
28
- return "grid-cols-3";
29
- }
30
- return "grid-cols-2";
23
+ const ceil = Math.ceil(Math.sqrt(items.length));
24
+ const max = Math.max(ceil, Math.floor(items.length / 3));
25
+ const classes = [
26
+ "grid-rows-1",
27
+ "grid-rows-2",
28
+ "grid-rows-3",
29
+ "grid-rows-4",
30
+ "grid-rows-5",
31
+ "grid-rows-6",
32
+ "grid-rows-7",
33
+ "grid-rows-8",
34
+ "grid-rows-9",
35
+ "grid-rows-10",
36
+ "grid-rows-11",
37
+ "grid-rows-12"
38
+ ];
39
+ if (max > 12) {
40
+ return "grid-rows-12";
41
+ } else return classes[max - 1 || 1];
31
42
  };
32
43
  </script>
33
44
 
34
- <div class="p-5 rounded-md bg-surface-50 dark:bg-surface-800 border-primary-500 border-2">
45
+ <div class="p-5 rounded-md max-w-6xl bg-surface-50 dark:bg-surface-800 border-primary-500 border-2">
35
46
  <!-- Header -->
36
47
  <h2 class="text-xl font-semibold">{group.displayName}</h2>
37
48
 
38
49
  <!-- Items -->
39
50
  <div
40
- class="grid {gridClass(
51
+ class="{gridClass(
41
52
  Object.keys(selected)
42
- )} !gap-x-20 gap-y-2 py-10 px-2 max-h-[1000px] overflow-x-auto max-w-6xl"
53
+ )} grid grid-flow-col gap-x-10 gap-y-2 py-10 px-2 h-full overflow-x-auto"
43
54
  >
44
55
  {#each Object.keys(selected) as key}
45
- <label class="flex gap-3 items-center">
56
+ <label class="flex gap-3 items-center w-48">
46
57
  <input type="checkbox" class="checkbox" bind:checked={selected[key].selected} />
47
- <span class="whitespace-nowrap break-before-avoid break-after-avoid"
58
+ <span
59
+ title={selected[key].displayName}
60
+ class="whitespace-nowrap break-before-avoid break-after-avoid truncate"
48
61
  >{selected[key].displayName}</span
49
62
  >
50
63
  </label>
@@ -58,7 +71,7 @@ const gridClass = (items) => {
58
71
  <button class="btn btn-sm variant-filled-tertiary" on:click={selectAll}>All</button>
59
72
  </div>
60
73
  <div class="flex gap-3">
61
- <button class="btn btn-sm variant-filled-primary" on:click={onSave}>Save</button>
74
+ <button class="btn btn-sm variant-filled-primary" on:click={onApply}>Apply</button>
62
75
  <button class="btn btn-sm variant-filled-secondary" on:click={onCancel}>Cancel</button>
63
76
  </div>
64
77
  </div>
@@ -3,7 +3,7 @@ import type { SelectedFacetGroup } from '../../models/Models';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  group: SelectedFacetGroup;
6
- handleSave: (group: SelectedFacetGroup) => {};
6
+ handleApply: (group: SelectedFacetGroup) => {};
7
7
  handleCancel: (groupName: string) => {};
8
8
  };
9
9
  events: {
@@ -121,7 +121,7 @@ async function handleSubmit() {
121
121
  {/if}
122
122
  </div>
123
123
 
124
- <button id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
124
+ <button title="Submit" id={submitBt} color="primary" style="display:none"><Fa icon={faSave} /></button>
125
125
  {:else}
126
126
  <!-- while data is not loaded show a loading information -->
127
127
 
@@ -10,7 +10,9 @@ const popupCombobox = {
10
10
 
11
11
  <button
12
12
  type="button"
13
+ title="Hide or show columns"
13
14
  class="btn btn-sm variant-filled-primary rounded-full order-last"
15
+ aria-label="Open menu to hide/show columns"
14
16
  use:popup={popupCombobox}>Columns</button
15
17
  >
16
18
 
@@ -20,8 +22,11 @@ const popupCombobox = {
20
22
  >
21
23
  {#each columns as column}
22
24
  <div class="flex gap-3 items-center">
25
+ <label for={column.id} class="cursor-pointer" title={column.label}></label>
23
26
  <input
27
+ aria-label="Toggle column visibility for column {column.label}"
24
28
  type="checkbox"
29
+ id = {column.id}
25
30
  bind:checked={column.visible}
26
31
  disabled={columns.filter((c) => c.visible).length === 1 && column.visible}
27
32
  />
@@ -143,8 +143,8 @@ const tableColumns = [
143
143
  header: header ?? key,
144
144
  accessor,
145
145
  // Render the cell with the provided component, or use the toStringFn if provided, or just use the value
146
- cell: ({ value, row }) => {
147
- return renderComponent ? createRender(renderComponent, { value, row, dispatchFn: actionDispatcher }) : toStringFn ? toStringFn(value) : value;
146
+ cell: ({ value, row, column }) => {
147
+ return renderComponent ? createRender(renderComponent, { value, row, column, dispatchFn: actionDispatcher }) : toStringFn ? toStringFn(value) : value;
148
148
  },
149
149
  plugins: {
150
150
  // Sorting config
@@ -326,7 +326,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
326
326
  } else {
327
327
  sendModel.q = searchValue;
328
328
  }
329
-
329
+
330
330
  $filterValue = searchValue;
331
331
  }}
332
332
  >
@@ -334,13 +334,16 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
334
334
  <input
335
335
  class="input p-2 border border-primary-500"
336
336
  type="text"
337
+ title="Search within all table rows"
337
338
  bind:value={searchValue}
338
339
  placeholder="Search rows..."
339
340
  id="{tableId}-search"
340
341
  /><button
341
342
  type="reset"
343
+ title="Clear search"
342
344
  id="{tableId}-searchReset"
343
345
  class="absolute right-3 items-center"
346
+ aria-label="Clear search"
344
347
  on:click|preventDefault={() => {
345
348
  if (serverSide && !sendModel) {
346
349
  throw new Error('Server-side configuration is missing');
@@ -355,6 +358,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
355
358
  </div>
356
359
  <button
357
360
  type="submit"
361
+ title="Search"
358
362
  id="{tableId}-searchSubmit"
359
363
  class="btn variant-filled-primary"
360
364
  on:click|preventDefault={() => {
@@ -380,6 +384,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
380
384
  {#if toggle}
381
385
  <SlideToggle
382
386
  name="slider-label"
387
+ label="Fit to screen"
383
388
  active="bg-primary-500"
384
389
  size="sm"
385
390
  checked={fitToScreen}
@@ -393,6 +398,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
393
398
  {#if resizable !== 'none'}
394
399
  <button
395
400
  type="button"
401
+ title="Reset column and row sizing"
396
402
  class="btn btn-sm variant-filled-primary rounded-full order-last"
397
403
  on:click|preventDefault={() =>
398
404
  resetResize($headerRows, $pageRows, tableId, columns, resizable)}
@@ -402,6 +408,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
402
408
  {#if exportable}
403
409
  <button
404
410
  type="button"
411
+ title="Export table data as CSV"
405
412
  class="btn btn-sm variant-filled-primary rounded-full order-last"
406
413
  on:click|preventDefault={() => exportAsCsv(tableId, $exportedData)}
407
414
  >Export as CSV</button
@@ -418,6 +425,7 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
418
425
  {...$tableAttrs}
419
426
  class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
420
427
  id="{tableId}-table"
428
+ title="Table"
421
429
  >
422
430
  <!-- If table height is provided, making the top row sticky -->
423
431
  <thead class={height != null && $pageRows.length > 0 ? `sticky top-0` : ''}>
@@ -443,6 +451,8 @@ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => co
443
451
  <div class="flex gap-1 whitespace-pre-wrap">
444
452
  <!-- Adding sorting config and styling -->
445
453
  <span
454
+ role="button"
455
+ tabindex="0"
446
456
  class:underline={props.sort.order}
447
457
  class:normal-case={cell.id !== cell.label}
448
458
  class:cursor-pointer={!props.sort.disabled}
@@ -201,6 +201,7 @@ onMount(() => {
201
201
  type="button"
202
202
  use:popup={popupFeatured}
203
203
  id="{popupId}-button"
204
+ aria-label="Open filter menu for column {id}"
204
205
  >
205
206
  <Fa icon={faFilter} size="12" />
206
207
  </button>
@@ -210,6 +211,7 @@ onMount(() => {
210
211
  <button
211
212
  class="btn variant-filled-primary btn-sm"
212
213
  type="button"
214
+ aria-label="Clear Filters"
213
215
  on:click|preventDefault={() => {
214
216
  // Set the defaults when cleared
215
217
  clearFilters();
@@ -234,6 +236,7 @@ onMount(() => {
234
236
  {#each options[type] as option (option)}
235
237
  <option
236
238
  value={option.value}
239
+ aria-label={option.label}
237
240
  selected={dropdown.option === option.value}
238
241
  disabled={Object.keys($filters[id]).includes(option.value) &&
239
242
  dropdown.option !== option.value}>{option.label}</option
@@ -242,7 +245,10 @@ onMount(() => {
242
245
  </select>
243
246
  {#if dropdowns.length > 1}
244
247
  <div
248
+ role="button"
249
+ tabindex="0"
245
250
  class="btn variant-filled-warning btn-sm h-full"
251
+ aria-label="Remove filter"
246
252
  on:click|preventDefault={() => removeFilter(dropdown.option)}
247
253
  on:keydown|preventDefault={() => removeFilter(dropdown.option)}
248
254
  >
@@ -257,6 +263,7 @@ onMount(() => {
257
263
  class="input p-1 border border-primary-500"
258
264
  on:input={(e) => valueChangeHandler(e, index)}
259
265
  bind:value={dropdown.value}
266
+ aria-label="Filter value"
260
267
  />
261
268
  {:else}
262
269
  <input
@@ -264,6 +271,7 @@ onMount(() => {
264
271
  class="input p-1 border border-primary-500"
265
272
  on:input={(e) => valueChangeHandler(e, index)}
266
273
  bind:value={dropdown.formValue}
274
+ aria-label="Filter value"
267
275
  />
268
276
  {/if}
269
277
  </div>
@@ -276,12 +284,15 @@ onMount(() => {
276
284
  {#if remainingFilters.length}
277
285
  <div
278
286
  class="btn variant-filled-secondary btn-sm cursor-pointer"
287
+ role="button"
288
+ tabindex="0"
279
289
  on:click|stopPropagation={() => {
280
290
  addFilter(remainingFilters[0].value, undefined);
281
291
  }}
282
292
  on:keydown|stopPropagation={() => {
283
293
  addFilter(remainingFilters[0].value, undefined);
284
294
  }}
295
+ aria-label="Add filter"
285
296
  >
286
297
  <div class="flex gap-1 items-center"><Fa icon={faPlus} />Add Filter</div>
287
298
  </div>
@@ -289,6 +300,7 @@ onMount(() => {
289
300
  <button
290
301
  class="btn variant-filled-primary btn-sm"
291
302
  type="button"
303
+ aria-label="Apply filters"
292
304
  on:click|preventDefault={() => {
293
305
  $pageIndex = 0;
294
306
  $filterValue = $filters[id];
@@ -190,6 +190,7 @@ $: console.log($filters);
190
190
  type="button"
191
191
  use:popup={popupFeatured}
192
192
  id="{popupId}-button"
193
+ aria-label="Open filter menu for column {id}"
193
194
  >
194
195
  <Fa icon={faFilter} size="12" />
195
196
  </button>
@@ -199,6 +200,7 @@ $: console.log($filters);
199
200
  <button
200
201
  class="btn variant-filled-primary btn-sm"
201
202
  type="button"
203
+ aria-label="Clear Filters"
202
204
  on:click|preventDefault={() => {
203
205
  // Set the defaults when cleared
204
206
  clearFilters();
@@ -221,6 +223,7 @@ $: console.log($filters);
221
223
  {#each options[type] as option (option)}
222
224
  <option
223
225
  value={option.value}
226
+ aria-label={option.label}
224
227
  selected={dropdown.option === option.value}
225
228
  disabled={Object.keys($filters[id]).includes(option.value) &&
226
229
  dropdown.option !== option.value}>{option.label}</option
@@ -229,10 +232,13 @@ $: console.log($filters);
229
232
  </select>
230
233
  {#if dropdowns.length > 1}
231
234
  <div
235
+ role="button"
236
+ tabindex="0"
232
237
  class="btn variant-filled-warning btn-sm h-full"
233
238
  on:click|preventDefault={() => removeFilter(dropdown.option)}
234
239
  on:keydown|preventDefault={() => removeFilter(dropdown.option)}
235
- >
240
+ aria-label="Remove filter"
241
+ >
236
242
  <Fa icon={faXmark} />
237
243
  </div>
238
244
  {/if}
@@ -251,6 +257,7 @@ $: console.log($filters);
251
257
  class="input p-1 border border-primary-500"
252
258
  on:input={(e) => valueChangeHandler(e, index)}
253
259
  bind:value={dropdown.value}
260
+ aria-label="Filter value"
254
261
  />
255
262
  {:else}
256
263
  <input
@@ -258,6 +265,7 @@ $: console.log($filters);
258
265
  class="input p-1 border border-primary-500"
259
266
  on:input={(e) => valueChangeHandler(e, index)}
260
267
  bind:value={dropdown.value}
268
+ aria-label="Filter value"
261
269
  />
262
270
  {/if}
263
271
  </div>
@@ -270,6 +278,9 @@ $: console.log($filters);
270
278
  {#if remainingFilters.length}
271
279
  <div
272
280
  class="btn variant-filled-secondary btn-sm cursor-pointer"
281
+ aria-label="Add filter"
282
+ role="button"
283
+ tabindex="0"
273
284
  on:click|stopPropagation={() => {
274
285
  addFilter(remainingFilters[0].value, undefined);
275
286
  }}
@@ -283,6 +294,7 @@ $: console.log($filters);
283
294
  <button
284
295
  class="btn variant-filled-primary btn-sm"
285
296
  type="button"
297
+ aria-label="Apply filters"
286
298
  on:click|preventDefault={applyFilters}>Apply</button
287
299
  >
288
300
  </div>
@@ -52,7 +52,11 @@ $: $pageSize = pageSizeDropdownValue;
52
52
  {/each}
53
53
  </select> -->
54
54
 
55
- <button class="btn variant-filled-primary w-20 justify-between" use:popup={pageSizePopup}>
55
+ <button
56
+ aria-label="Open menu to select number of items per page"
57
+ class="btn variant-filled-primary w-20 justify-between"
58
+ use:popup={pageSizePopup}
59
+ >
56
60
  <span class="capitalize font-semibold">{pageSizeDropdownValue}</span>
57
61
  <Fa icon={faChevronDown} size="xs" />
58
62
  </button>
@@ -72,6 +76,7 @@ $: $pageSize = pageSizeDropdownValue;
72
76
  <button
73
77
  class="btn btn-sm variant-filled-primary"
74
78
  on:click|preventDefault={goToFirstPage}
79
+ aria-label="Go to first page"
75
80
  disabled={goToFirstPageDisabled}
76
81
  id="{id}-first"
77
82
  >
@@ -80,6 +85,7 @@ $: $pageSize = pageSizeDropdownValue;
80
85
  <button
81
86
  class="btn btn-sm variant-filled-primary"
82
87
  id="{id}-previous"
88
+ aria-label="Go to previous page"
83
89
  on:click|preventDefault={goToPreviousPage}
84
90
  disabled={goToPreviousPageDisabled}><Fa icon={faAngleLeft} /></button
85
91
  >
@@ -88,17 +94,20 @@ $: $pageSize = pageSizeDropdownValue;
88
94
  class="input border border-primary-500 rounded flex w-24"
89
95
  value={$pageIndex + 1}
90
96
  max={$pageCount}
97
+ aria-label="Current page"
91
98
  min={1}
92
99
  on:change={handleChange}
93
100
  />
94
101
  <button
95
102
  class="btn btn-sm variant-filled-primary"
96
103
  id="{id}-next"
104
+ aria-label="Go to next page"
97
105
  on:click|preventDefault={goToNextPage}
98
106
  disabled={goToNextPageDisabled}><Fa icon={faAngleRight} /></button
99
107
  >
100
108
  <button
101
109
  class="btn btn-sm variant-filled-primary"
110
+ aria-label="Go to last page"
102
111
  id="{id}-last"
103
112
  on:click|preventDefault={goToLastPage}
104
113
  disabled={goToLastPageDisabled}><Fa icon={faAnglesRight} /></button
@@ -59,6 +59,7 @@ updateTable();
59
59
  <select
60
60
  name="pageSize"
61
61
  id="{id}-pageSize"
62
+ aria-label="Open menu to select number of items per page"
62
63
  class="select variant-filled-primary w-min font-bold"
63
64
  bind:value={$pageSize}
64
65
  >
@@ -70,21 +71,26 @@ updateTable();
70
71
  <div class="flex justify-center gap-1">
71
72
  <button
72
73
  class="btn btn-sm variant-filled-primary"
74
+ title="Go to first page"
73
75
  on:click|preventDefault={() => goTo('first')}
74
76
  disabled={goToFirstPageDisabled}
77
+ aria-label="Go to first page"
75
78
  id="{id}-first"
76
79
  >
77
80
  <Fa icon={faAnglesLeft} /></button
78
81
  >
79
82
  <button
80
83
  class="btn btn-sm variant-filled-primary"
84
+ title="Go to previous page"
81
85
  id="{id}-previous"
86
+ aria-label="Go to previous page"
82
87
  on:click|preventDefault={() => goTo('previous')}
83
88
  disabled={goToPreviousPageDisabled}><Fa icon={faAngleLeft} /></button
84
89
  >
85
90
  <input
86
91
  type="number"
87
92
  class="input border border-primary-500 rounded flex w-24"
93
+ aria-label="Current page"
88
94
  value={$pageIndex + 1}
89
95
  max={pageCount}
90
96
  min={1}
@@ -94,11 +100,13 @@ updateTable();
94
100
  class="btn btn-sm variant-filled-primary"
95
101
  id="{id}-next"
96
102
  on:click|preventDefault={() => goTo('next')}
103
+ aria-label="Go to next page"
97
104
  disabled={goToNextPageDisabled}><Fa icon={faAngleRight} /></button
98
105
  >
99
106
  <button
100
107
  class="btn btn-sm variant-filled-primary"
101
108
  id="{id}-last"
109
+ aria-label="Go to last page"
102
110
  on:click|preventDefault={() => goTo('last')}
103
111
  disabled={goToLastPageDisabled}><Fa icon={faAnglesRight} /></button
104
112
  >
@@ -11,7 +11,7 @@ export let feedback;
11
11
  <InputContainer {label} {feedback} {required}>
12
12
  <input
13
13
  {id}
14
- class="input variant-form-material"
14
+ class="input variant-form-material bg-zinc-50 dark:bg-zinc-50"
15
15
  type="checkbox"
16
16
  class:input-success={valid}
17
17
  class:input-error={invalid}
@@ -12,13 +12,14 @@ let feedback;
12
12
 
13
13
  <InputContainer {id} label={title} {feedback} {required} {help}>
14
14
  {#each source as item}
15
- <label class="flex items-center space-x-2" for={key}>
15
+ <label class="flex items-center space-x-2" for={item.key}>
16
16
  <input
17
17
  class="checkbox"
18
18
  type="checkbox"
19
19
  bind:group={target}
20
20
  checked={item.key}
21
21
  value={item.key}
22
+ id={item.key}
22
23
  />
23
24
  <p>{item.value}</p>
24
25
  </label>
@@ -10,8 +10,8 @@ let feedback;
10
10
 
11
11
  <InputContainer label={title} {feedback} {required}>
12
12
  {#each source as item}
13
- <label class="flex items-center space-x-2" for={key}>
14
- <input class="checkbox" type="checkbox" bind:group={target} value={item} />
13
+ <label class="flex items-center space-x-2" for={item}>
14
+ <input class="checkbox" type="checkbox" bind:group={target} value={item} id={item}/>
15
15
  <p>{item}</p>
16
16
  </label>
17
17
  {/each}
@@ -13,7 +13,7 @@ export let disabled = false;
13
13
  <InputContainer {id} {label} {feedback} {required} {help}>
14
14
  <input
15
15
  {id}
16
- class="input variant-form-material"
16
+ class="input variant-form-material bg-zinc-50 dark:bg-zinc-700 placeholder:text-gray-400"
17
17
  type="date"
18
18
  class:input-success={valid}
19
19
  class:input-error={invalid}