@aquera/nile-elements 1.5.3 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/README.md +9 -0
  2. package/demo/index.css +9 -0
  3. package/dist/index.cjs.js +1 -1
  4. package/dist/index.esm.js +1 -1
  5. package/dist/index.js +418 -29
  6. package/dist/nile-badge/index.cjs.js +1 -1
  7. package/dist/nile-badge/index.esm.js +1 -1
  8. package/dist/nile-badge/nile-badge.cjs.js +1 -1
  9. package/dist/nile-badge/nile-badge.cjs.js.map +1 -1
  10. package/dist/nile-badge/nile-badge.esm.js +1 -1
  11. package/dist/nile-button/index.cjs.js +1 -1
  12. package/dist/nile-button/index.esm.js +1 -1
  13. package/dist/nile-button/nile-button.cjs.js +1 -1
  14. package/dist/nile-button/nile-button.cjs.js.map +1 -1
  15. package/dist/nile-button/nile-button.esm.js +1 -1
  16. package/dist/nile-carousel/index.cjs.js +1 -1
  17. package/dist/nile-carousel/index.esm.js +1 -1
  18. package/dist/nile-carousel/nile-carousel.cjs.js +1 -1
  19. package/dist/nile-carousel/nile-carousel.cjs.js.map +1 -1
  20. package/dist/nile-carousel/nile-carousel.esm.js +11 -11
  21. package/dist/nile-detail/index.cjs.js +2 -0
  22. package/dist/nile-detail/index.cjs.js.map +1 -0
  23. package/dist/nile-detail/index.esm.js +1 -0
  24. package/dist/nile-detail/nile-detail.cjs.js +2 -0
  25. package/dist/nile-detail/nile-detail.cjs.js.map +1 -0
  26. package/dist/nile-detail/nile-detail.css.cjs.js +2 -0
  27. package/dist/nile-detail/nile-detail.css.cjs.js.map +1 -0
  28. package/dist/nile-detail/nile-detail.css.esm.js +149 -0
  29. package/dist/nile-detail/nile-detail.esm.js +45 -0
  30. package/dist/nile-detail/nile-detail.utils.cjs.js +2 -0
  31. package/dist/nile-detail/nile-detail.utils.cjs.js.map +1 -0
  32. package/dist/nile-detail/nile-detail.utils.esm.js +1 -0
  33. package/dist/nile-dialog/index.cjs.js +1 -1
  34. package/dist/nile-dialog/index.esm.js +1 -1
  35. package/dist/nile-dialog/nile-dialog.cjs.js +1 -1
  36. package/dist/nile-dialog/nile-dialog.cjs.js.map +1 -1
  37. package/dist/nile-dialog/nile-dialog.esm.js +1 -1
  38. package/dist/nile-drawer/index.cjs.js +1 -1
  39. package/dist/nile-drawer/index.esm.js +1 -1
  40. package/dist/nile-drawer/nile-drawer.cjs.js +1 -1
  41. package/dist/nile-drawer/nile-drawer.cjs.js.map +1 -1
  42. package/dist/nile-drawer/nile-drawer.esm.js +1 -1
  43. package/dist/nile-icon/icons/svg/delete_history.cjs.js +2 -0
  44. package/dist/nile-icon/icons/svg/delete_history.cjs.js.map +1 -0
  45. package/dist/nile-icon/icons/svg/delete_history.esm.js +1 -0
  46. package/dist/nile-icon/icons/svg/index.cjs.js +1 -1
  47. package/dist/nile-icon/icons/svg/index.esm.js +1 -1
  48. package/dist/nile-icon/index.cjs.js +1 -1
  49. package/dist/nile-icon/index.cjs.js.map +1 -1
  50. package/dist/nile-icon/index.esm.js +1 -1
  51. package/dist/nile-icon-button/index.cjs.js +1 -1
  52. package/dist/nile-icon-button/index.esm.js +1 -1
  53. package/dist/nile-icon-button/nile-icon-button.cjs.js +1 -1
  54. package/dist/nile-icon-button/nile-icon-button.cjs.js.map +1 -1
  55. package/dist/nile-icon-button/nile-icon-button.esm.js +1 -1
  56. package/dist/nile-inline-sidebar/nile-inline-sidebar.cjs.js +1 -1
  57. package/dist/nile-inline-sidebar/nile-inline-sidebar.cjs.js.map +1 -1
  58. package/dist/nile-inline-sidebar/nile-inline-sidebar.css.cjs.js +1 -1
  59. package/dist/nile-inline-sidebar/nile-inline-sidebar.css.cjs.js.map +1 -1
  60. package/dist/nile-inline-sidebar/nile-inline-sidebar.css.esm.js +19 -0
  61. package/dist/nile-inline-sidebar/nile-inline-sidebar.esm.js +16 -14
  62. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.cjs.js +1 -1
  63. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.cjs.js.map +1 -1
  64. package/dist/nile-inline-sidebar-item/nile-inline-sidebar-item.esm.js +8 -3
  65. package/dist/nile-input/index.cjs.js +1 -1
  66. package/dist/nile-input/index.esm.js +1 -1
  67. package/dist/nile-input/nile-input.cjs.js +1 -1
  68. package/dist/nile-input/nile-input.cjs.js.map +1 -1
  69. package/dist/nile-input/nile-input.esm.js +1 -1
  70. package/dist/nile-menu-item/index.cjs.js +1 -1
  71. package/dist/nile-menu-item/index.esm.js +1 -1
  72. package/dist/nile-menu-item/nile-menu-item.cjs.js +1 -1
  73. package/dist/nile-menu-item/nile-menu-item.cjs.js.map +1 -1
  74. package/dist/nile-menu-item/nile-menu-item.esm.js +1 -1
  75. package/dist/nile-option/index.cjs.js +1 -1
  76. package/dist/nile-option/index.esm.js +1 -1
  77. package/dist/nile-option/nile-option.cjs.js +1 -1
  78. package/dist/nile-option/nile-option.cjs.js.map +1 -1
  79. package/dist/nile-option/nile-option.esm.js +1 -1
  80. package/dist/nile-pagination/nile-pagination.cjs.js +1 -1
  81. package/dist/nile-pagination/nile-pagination.cjs.js.map +1 -1
  82. package/dist/nile-pagination/nile-pagination.css.cjs.js +1 -1
  83. package/dist/nile-pagination/nile-pagination.css.cjs.js.map +1 -1
  84. package/dist/nile-pagination/nile-pagination.css.esm.js +109 -5
  85. package/dist/nile-pagination/nile-pagination.esm.js +70 -3
  86. package/dist/nile-select/index.cjs.js +1 -1
  87. package/dist/nile-select/index.esm.js +1 -1
  88. package/dist/nile-select/nile-select.cjs.js +1 -1
  89. package/dist/nile-select/nile-select.cjs.js.map +1 -1
  90. package/dist/nile-select/nile-select.esm.js +1 -1
  91. package/dist/nile-side-bar-action-menu-item/index.cjs.js +1 -1
  92. package/dist/nile-side-bar-action-menu-item/index.esm.js +1 -1
  93. package/dist/nile-side-bar-action-menu-item/nile-side-bar-action-menu-item.cjs.js +1 -1
  94. package/dist/nile-side-bar-action-menu-item/nile-side-bar-action-menu-item.cjs.js.map +1 -1
  95. package/dist/nile-side-bar-action-menu-item/nile-side-bar-action-menu-item.esm.js +1 -1
  96. package/dist/nile-tab/index.cjs.js +1 -1
  97. package/dist/nile-tab/index.esm.js +1 -1
  98. package/dist/nile-tab/nile-tab.cjs.js +1 -1
  99. package/dist/nile-tab/nile-tab.cjs.js.map +1 -1
  100. package/dist/nile-tab/nile-tab.esm.js +1 -1
  101. package/dist/nile-tab-group/index.cjs.js +1 -1
  102. package/dist/nile-tab-group/index.esm.js +1 -1
  103. package/dist/nile-tab-group/nile-tab-group.cjs.js +1 -1
  104. package/dist/nile-tab-group/nile-tab-group.cjs.js.map +1 -1
  105. package/dist/nile-tab-group/nile-tab-group.esm.js +1 -1
  106. package/dist/nile-tag/index.cjs.js +1 -1
  107. package/dist/nile-tag/index.esm.js +1 -1
  108. package/dist/nile-tag/nile-tag.cjs.js +1 -1
  109. package/dist/nile-tag/nile-tag.cjs.js.map +1 -1
  110. package/dist/nile-tag/nile-tag.esm.js +1 -1
  111. package/dist/nile-toast/index.cjs.js +1 -1
  112. package/dist/nile-toast/index.esm.js +1 -1
  113. package/dist/nile-toast/nile-toast.cjs.js +1 -1
  114. package/dist/nile-toast/nile-toast.cjs.js.map +1 -1
  115. package/dist/nile-toast/nile-toast.esm.js +1 -1
  116. package/dist/nile-tree/index.cjs.js +1 -1
  117. package/dist/nile-tree/index.esm.js +1 -1
  118. package/dist/nile-tree/nile-tree.cjs.js +1 -1
  119. package/dist/nile-tree/nile-tree.cjs.js.map +1 -1
  120. package/dist/nile-tree/nile-tree.esm.js +1 -1
  121. package/dist/nile-tree-item/index.cjs.js +1 -1
  122. package/dist/nile-tree-item/index.esm.js +1 -1
  123. package/dist/nile-tree-item/nile-tree-item.cjs.js +1 -1
  124. package/dist/nile-tree-item/nile-tree-item.cjs.js.map +1 -1
  125. package/dist/nile-tree-item/nile-tree-item.esm.js +1 -1
  126. package/dist/nile-virtual-select/index.cjs.js +1 -1
  127. package/dist/nile-virtual-select/index.esm.js +1 -1
  128. package/dist/nile-virtual-select/nile-virtual-select.cjs.js +2 -2
  129. package/dist/nile-virtual-select/nile-virtual-select.esm.js +1 -1
  130. package/dist/src/index.d.ts +1 -0
  131. package/dist/src/index.js +1 -0
  132. package/dist/src/index.js.map +1 -1
  133. package/dist/src/nile-detail/index.d.ts +1 -0
  134. package/dist/src/nile-detail/index.js +2 -0
  135. package/dist/src/nile-detail/index.js.map +1 -0
  136. package/dist/src/nile-detail/nile-detail.css.d.ts +3 -0
  137. package/dist/src/nile-detail/nile-detail.css.js +152 -0
  138. package/dist/src/nile-detail/nile-detail.css.js.map +1 -0
  139. package/dist/src/nile-detail/nile-detail.d.ts +29 -0
  140. package/dist/src/nile-detail/nile-detail.js +143 -0
  141. package/dist/src/nile-detail/nile-detail.js.map +1 -0
  142. package/dist/src/nile-detail/nile-detail.test.d.ts +1 -0
  143. package/dist/src/nile-detail/nile-detail.test.js +168 -0
  144. package/dist/src/nile-detail/nile-detail.test.js.map +1 -0
  145. package/dist/src/nile-detail/nile-detail.utils.d.ts +8 -0
  146. package/dist/src/nile-detail/nile-detail.utils.js +117 -0
  147. package/dist/src/nile-detail/nile-detail.utils.js.map +1 -0
  148. package/dist/src/nile-icon/icons/svg/delete_history.d.ts +5 -0
  149. package/dist/src/nile-icon/icons/svg/delete_history.js +5 -0
  150. package/dist/src/nile-icon/icons/svg/delete_history.js.map +1 -0
  151. package/dist/src/nile-icon/icons/svg/index.d.ts +1 -0
  152. package/dist/src/nile-icon/icons/svg/index.js +1 -0
  153. package/dist/src/nile-icon/icons/svg/index.js.map +1 -1
  154. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.css.js +19 -0
  155. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.css.js.map +1 -1
  156. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.d.ts +6 -0
  157. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.js +88 -4
  158. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.js.map +1 -1
  159. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.test.d.ts +3 -0
  160. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.test.js +110 -0
  161. package/dist/src/nile-inline-sidebar/nile-inline-sidebar.test.js.map +1 -0
  162. package/dist/src/nile-inline-sidebar-group/nile-inline-sidebar-group.test.d.ts +2 -0
  163. package/dist/src/nile-inline-sidebar-group/nile-inline-sidebar-group.test.js +109 -0
  164. package/dist/src/nile-inline-sidebar-group/nile-inline-sidebar-group.test.js.map +1 -0
  165. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.d.ts +4 -0
  166. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.js +30 -2
  167. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.js.map +1 -1
  168. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.test.d.ts +2 -0
  169. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.test.js +109 -0
  170. package/dist/src/nile-inline-sidebar-item/nile-inline-sidebar-item.test.js.map +1 -0
  171. package/dist/src/nile-pagination/nile-pagination.css.js +107 -3
  172. package/dist/src/nile-pagination/nile-pagination.css.js.map +1 -1
  173. package/dist/src/nile-pagination/nile-pagination.d.ts +5 -1
  174. package/dist/src/nile-pagination/nile-pagination.js +84 -1
  175. package/dist/src/nile-pagination/nile-pagination.js.map +1 -1
  176. package/dist/src/nile-pagination/nile-pagination.test.js +1187 -103
  177. package/dist/src/nile-pagination/nile-pagination.test.js.map +1 -1
  178. package/dist/src/version.js +2 -2
  179. package/dist/src/version.js.map +1 -1
  180. package/dist/tsconfig.tsbuildinfo +1 -1
  181. package/package.json +1 -1
  182. package/src/index.ts +2 -2
  183. package/src/nile-detail/index.ts +1 -0
  184. package/src/nile-detail/nile-detail.css.ts +153 -0
  185. package/src/nile-detail/nile-detail.test.ts +215 -0
  186. package/src/nile-detail/nile-detail.ts +140 -0
  187. package/src/nile-detail/nile-detail.utils.ts +133 -0
  188. package/src/nile-icon/icons/svg/delete_history.ts +5 -0
  189. package/src/nile-icon/icons/svg/index.ts +1 -0
  190. package/src/nile-inline-sidebar/nile-inline-sidebar.css.ts +19 -0
  191. package/src/nile-inline-sidebar/nile-inline-sidebar.test.ts +108 -0
  192. package/src/nile-inline-sidebar/nile-inline-sidebar.ts +108 -5
  193. package/src/nile-inline-sidebar-group/nile-inline-sidebar-group.test.ts +107 -0
  194. package/src/nile-inline-sidebar-item/nile-inline-sidebar-item.test.ts +107 -0
  195. package/src/nile-inline-sidebar-item/nile-inline-sidebar-item.ts +34 -3
  196. package/src/nile-pagination/nile-pagination.css.ts +107 -3
  197. package/src/nile-pagination/nile-pagination.test.ts +1388 -101
  198. package/src/nile-pagination/nile-pagination.ts +87 -2
  199. package/vscode-html-custom-data.json +55 -4
@@ -0,0 +1,133 @@
1
+ import { animateTo, shimKeyframesHeightAuto, stopAnimations } from '../internal/animate';
2
+ import { getAnimation, setDefaultAnimation } from '../utilities/animation-registry';
3
+ import { waitForEvent } from '../internal/event';
4
+ import type { NileDetail } from './nile-detail';
5
+
6
+ /*
7
+ Runs the show animation on the detail body.
8
+ Emits nile-show (cancelable) before and nile-after-show after the animation.
9
+ */
10
+ export async function animateShow(component: NileDetail): Promise<void> {
11
+ const nileShow = component.emit('nile-show', { cancelable: true });
12
+ if (nileShow.defaultPrevented) {
13
+ component.open = false;
14
+ return;
15
+ }
16
+
17
+ await stopAnimations(component.body);
18
+ component.body.hidden = false;
19
+
20
+ const { keyframes, options } = getAnimation(component, 'detail.show', { dir: 'ltr' });
21
+ await animateTo(component.body, shimKeyframesHeightAuto(keyframes, component.body.scrollHeight), options);
22
+ component.body.style.height = 'auto';
23
+
24
+ component.emit('nile-after-show');
25
+ }
26
+
27
+ /*
28
+ Runs the hide animation on the detail body.
29
+ Emits nile-hide (cancelable) before and nile-after-hide after the animation.
30
+ */
31
+ export async function animateHide(component: NileDetail): Promise<void> {
32
+ const nileHide = component.emit('nile-hide', { cancelable: true });
33
+ if (nileHide.defaultPrevented) {
34
+ component.open = true;
35
+ return;
36
+ }
37
+
38
+ await stopAnimations(component.body);
39
+
40
+ const { keyframes, options } = getAnimation(component, 'detail.hide', { dir: 'ltr' });
41
+ await animateTo(component.body, shimKeyframesHeightAuto(keyframes, component.body.scrollHeight), options);
42
+ component.body.hidden = true;
43
+ component.body.style.height = 'auto';
44
+
45
+ component.emit('nile-after-hide');
46
+ }
47
+
48
+ /*
49
+ Programmatically shows the detail if it is not already open or disabled.
50
+ Returns a promise that resolves after the show animation completes.
51
+ */
52
+ export async function showDetail(component: NileDetail): Promise<unknown> {
53
+ if (component.open || component.disabled) {
54
+ return undefined;
55
+ }
56
+ component.open = true;
57
+ return waitForEvent(component, 'nile-after-show');
58
+ }
59
+
60
+ /*
61
+ Programmatically hides the detail if it is not already closed or disabled.
62
+ Returns a promise that resolves after the hide animation completes.
63
+ */
64
+ export async function hideDetail(component: NileDetail): Promise<unknown> {
65
+ if (!component.open || component.disabled) {
66
+ return undefined;
67
+ }
68
+ component.open = false;
69
+ return waitForEvent(component, 'nile-after-hide');
70
+ }
71
+
72
+ /*
73
+ Handles click on the header summary row.
74
+ Toggles the detail open/close and focuses the header.
75
+ */
76
+ export function handleSummaryClick(component: NileDetail): void {
77
+ if (!component.disabled) {
78
+ if (component.open) {
79
+ hideDetail(component);
80
+ } else {
81
+ showDetail(component);
82
+ }
83
+ }
84
+ }
85
+
86
+ /*
87
+ Handles keyboard interaction on the header summary row.
88
+ Enter/Space toggles, ArrowUp/Left closes, ArrowDown/Right opens.
89
+ */
90
+ export function handleSummaryKeyDown(event: KeyboardEvent, component: NileDetail): void {
91
+ event.preventDefault();
92
+
93
+ if (event.key === 'Enter' || event.key === ' ') {
94
+ if (component.open) {
95
+ hideDetail(component);
96
+ } else {
97
+ showDetail(component);
98
+ }
99
+ }
100
+
101
+ if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
102
+ hideDetail(component);
103
+ }
104
+
105
+ if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
106
+ showDetail(component);
107
+ }
108
+ }
109
+
110
+ /*
111
+ Registers the default show and hide animations for the detail component.
112
+ Show: animates from height 0 / opacity 0 to auto / 1 over 300ms.
113
+ Hide: animates from auto / 1 to height 0 / opacity 0 over 300ms.
114
+ */
115
+ export function registerDefaultAnimations(): void {
116
+ setDefaultAnimation('detail.show', {
117
+ keyframes: [
118
+ { height: '0', opacity: '0' },
119
+ { height: 'auto', opacity: '1' }
120
+ ],
121
+ options: { duration: 300, easing: 'ease' }
122
+ });
123
+
124
+ setDefaultAnimation('detail.hide', {
125
+ keyframes: [
126
+ { height: 'auto', opacity: '1' },
127
+ { height: '0', opacity: '0' }
128
+ ],
129
+ options: { duration: 300, easing: 'ease' }
130
+ });
131
+ }
132
+
133
+ registerDefaultAnimations();
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Do not edit directly
3
+ */
4
+
5
+ export default "PHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOS4zNTQ1IDEyLjVMOC43ODgzMiAxMS45MzM4TDEwLjE0NzEgMTAuNTc1TDguNzg4MzIgOS4yMTYxOEw5LjM1NDUgOC42NUwxMC43MTMzIDEwLjAwODhMMTIuMDcyMSA4LjY1TDEyLjYzODMgOS4yMTYxOEwxMS4yOTU3IDEwLjU3NUwxMi42MzgzIDExLjkzMzhMMTIuMDcyMSAxMi41TDEwLjcxMzMgMTEuMTU3NEw5LjM1NDUgMTIuNVpNNi40NTQ3MSAxMi41QzQuOTk2NjcgMTIuNSAzLjc0MzEgMTIuMDAyMyAyLjY5NCAxMS4wMDY4QzEuNjQ0OSAxMC4wMTEzIDEuMDgwMjQgOC43ODQwNSAxIDcuMzI1MTVIMS44MTk2NkMxLjkwNzIzIDguNTUyMDggMi4zOTIzMSA5LjU4NTgxIDMuMjc0OSAxMC40MjYzQzQuMTU3MzggMTEuMjY2OCA1LjIxNzMxIDExLjY4NyA2LjQ1NDcxIDExLjY4N0M2LjY0MTkyIDExLjY4NyA2LjgyNDE4IDExLjY3NjMgNy4wMDE0NyAxMS42NTQ5QzcuMTc4NjYgMTEuNjMzNSA3LjM1Mzk2IDExLjU5OTUgNy41MjczNyAxMS41NTNWMTIuMzgyNkM3LjM1Mzk2IDEyLjQyMjQgNy4xNzc1MiAxMi40NTE5IDYuOTk4MDcgMTIuNDcxMkM2LjgxODYyIDEyLjQ5MDQgNi42Mzc1IDEyLjUgNi40NTQ3MSAxMi41Wk0xLjQ3NzM3IDQuODM4MThWMS44MDI4MkgyLjI5MDRWMy40MzIxMkMyLjgxOTkxIDIuODI4NDEgMy40NDU4MyAyLjM1NTQ3IDQuMTY4MTYgMi4wMTMyOEM0Ljg5MDM5IDEuNjcxMDkgNS42NTI1NyAxLjUgNi40NTQ3MSAxLjVDNy45ODgzNCAxLjUgOS4yOTI0NCAyLjAzMjE1IDEwLjM2NyAzLjA5NjQ2QzExLjQ0MTUgNC4xNjA4NyAxMS45Nzg4IDUuNDU2MjMgMTEuOTc4OCA2Ljk4MjUzVjcuMTQ4NUgxMS4xNjU4VjYuOTU4NTlDMTEuMTY1OCA1LjY2MDI2IDEwLjcwNyA0LjU2MTQgOS43ODkzMiAzLjY2MTk5QzguODcxNjkgMi43NjI2OCA3Ljc2MDE1IDIuMzEzMDMgNi40NTQ3MSAyLjMxMzAzQzUuNzU1MTMgMi4zMTMwMyA1LjA5Njc1IDIuNDY3MDggNC40Nzk1NiAyLjc3NTE5QzMuODYyMzcgMy4wODM0MSAzLjMyNDAyIDMuNTAwMDYgMi44NjQ1IDQuMDI1MTVINC41MTUzMVY0LjgzODE4SDEuNDc3MzdaTTcuNzU3MjQgOC43OTcyMUw2LjA5NzY5IDcuMTU1MTNWMy43NDA2SDYuOTEwNTZWNi44MjA3N0w4LjE4OTc5IDguMDc4NDlMNy43NTcyNCA4Ljc5NzIxWiIgZmlsbD0iYmxhY2siLz48L3N2Zz4=";
@@ -114,6 +114,7 @@ export { default as defaultcursor } from './default-cursor';
114
114
  export { default as default } from './default';
115
115
  export { default as delegate } from './delegate';
116
116
  export { default as delete } from './delete';
117
+ export { default as delete_history } from './delete_history';
117
118
  export { default as deligateduser } from './deligateduser';
118
119
  export { default as directory } from './directory';
119
120
  export { default as disabled } from './disabled';
@@ -103,4 +103,23 @@ export const styles = css`
103
103
  pointer-events: auto;
104
104
  transition-delay: 0ms;
105
105
  }
106
+
107
+ :host([placement='right']) .sidebar {
108
+ border-right: none;
109
+ border-left: 1px solid var(--nile-colors-neutral-400);
110
+ }
111
+
112
+ :host([placement='right']) .toggle-btn {
113
+ right: auto;
114
+ left: -14px;
115
+ }
116
+
117
+ :host([placement='right']) .sidebar-header {
118
+ justify-content: flex-start;
119
+ }
120
+
121
+ :host([placement='right']) .sidebar-nav {
122
+ padding-right: 0;
123
+ padding-left: var(--nile-spacing-xl);
124
+ }
106
125
  `;
@@ -0,0 +1,108 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import './nile-inline-sidebar';
3
+ import '../nile-inline-sidebar-item/nile-inline-sidebar-item';
4
+ import '../nile-inline-sidebar-group/nile-inline-sidebar-group';
5
+ import type { NileInlineSidebar } from './nile-inline-sidebar';
6
+
7
+ describe('NileInlineSidebar', () => {
8
+ it('1. renders', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el).to.exist; });
9
+ it('2. shadow root', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot).to.not.be.null; });
10
+ it('3. tag name', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.tagName.toLowerCase()).to.equal('nile-inline-sidebar'); });
11
+ it('4. collapsed defaults false', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.collapsed).to.be.false; });
12
+ it('5. fixed defaults false', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.fixed).to.be.false; });
13
+ it('6. showTooltip defaults false', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.showTooltip).to.be.false; });
14
+ it('7. placement defaults left', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.placement).to.equal('left'); });
15
+ it('8. set collapsed', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); expect(el.collapsed).to.be.true; });
16
+ it('9. set fixed', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar fixed></nile-inline-sidebar>`); expect(el.fixed).to.be.true; });
17
+ it('10. set showTooltip', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar showTooltip></nile-inline-sidebar>`); expect(el.showTooltip).to.be.true; });
18
+ it('11. set placement right', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right"></nile-inline-sidebar>`); expect(el.placement).to.equal('right'); });
19
+ it('12. set placement left', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="left"></nile-inline-sidebar>`); expect(el.placement).to.equal('left'); });
20
+ it('13. collapsed reflects', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); expect(el.hasAttribute('collapsed')).to.be.true; });
21
+ it('14. fixed reflects', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar fixed></nile-inline-sidebar>`); expect(el.hasAttribute('fixed')).to.be.true; });
22
+ it('15. placement reflects', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right"></nile-inline-sidebar>`); expect(el.getAttribute('placement')).to.equal('right'); });
23
+ it('16. sidebar class', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('.sidebar')).to.exist; });
24
+ it('17. base part', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('[part="base"]')).to.exist; });
25
+ it('18. header part', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('[part="header"]')).to.exist; });
26
+ it('19. nav-items part', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('[part="nav-items"]')).to.exist; });
27
+ it('20. sidebar-header class', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('.sidebar-header')).to.exist; });
28
+ it('21. sidebar-nav class', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('.sidebar-nav')).to.exist; });
29
+ it('22. nav element', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('nav')).to.exist; });
30
+ it('23. default slot', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('slot')).to.exist; });
31
+ it('24. toggle-btn when expanded', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('.toggle-btn')).to.exist; });
32
+ it('25. no toggle-btn when fixed', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar fixed></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('.toggle-btn')).to.be.null; });
33
+ it('26. collapsed nav hidden', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); const nav = el.shadowRoot!.querySelector('.sidebar-nav') as HTMLElement; expect(nav.style.display).to.equal('none'); });
34
+ it('27. expanded nav visible', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); const nav = el.shadowRoot!.querySelector('.sidebar-nav') as HTMLElement; expect(nav.style.display).to.not.equal('none'); });
35
+ it('28. collapsed shows side-bar-action', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('nile-side-bar-action')).to.exist; });
36
+ it('29. expanded hides side-bar-action', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('nile-side-bar-action')).to.be.null; });
37
+ it('30. collapsed shows action-menu', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('nile-side-bar-action-menu')).to.exist; });
38
+ it('31. left expanded icon menu_open', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="left"></nile-inline-sidebar>`); const icon = el.shadowRoot!.querySelector('nile-icon'); expect(icon?.getAttribute('name')).to.equal('menu_open'); });
39
+ it('32. right expanded icon menu_close', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right"></nile-inline-sidebar>`); const icon = el.shadowRoot!.querySelector('nile-icon'); expect(icon?.getAttribute('name')).to.equal('menu_close'); });
40
+ it('33. left collapsed icon menu_close', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="left" collapsed></nile-inline-sidebar>`); const icon = el.shadowRoot!.querySelector('nile-icon'); expect(icon?.getAttribute('name')).to.equal('menu_close'); });
41
+ it('34. right collapsed icon menu_open', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right" collapsed></nile-inline-sidebar>`); const icon = el.shadowRoot!.querySelector('nile-icon'); expect(icon?.getAttribute('name')).to.equal('menu_open'); });
42
+ it('35. left action placement bottom-start', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="left" collapsed></nile-inline-sidebar>`); const action = el.shadowRoot!.querySelector('nile-side-bar-action'); expect(action?.getAttribute('placement')).to.equal('bottom-start'); });
43
+ it('36. right action placement bottom-end', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right" collapsed></nile-inline-sidebar>`); const action = el.shadowRoot!.querySelector('nile-side-bar-action'); expect(action?.getAttribute('placement')).to.equal('bottom-end'); });
44
+ it('37. fixed forces collapsed false', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar fixed></nile-inline-sidebar>`); expect(el.collapsed).to.be.false; });
45
+ it('38. dynamic collapsed on', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.collapsed = true; await el.updateComplete; expect(el.hasAttribute('collapsed')).to.be.true; });
46
+ it('39. dynamic collapsed off', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); el.collapsed = false; await el.updateComplete; expect(el.hasAttribute('collapsed')).to.be.false; });
47
+ it('40. dynamic placement to right', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.placement = 'right'; await el.updateComplete; expect(el.getAttribute('placement')).to.equal('right'); });
48
+ it('41. dynamic placement to left', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right"></nile-inline-sidebar>`); el.placement = 'left'; await el.updateComplete; expect(el.getAttribute('placement')).to.equal('left'); });
49
+ it('42. dynamic fixed', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.fixed = true; await el.updateComplete; expect(el.hasAttribute('fixed')).to.be.true; });
50
+ it('43. slotted item', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar><nile-inline-sidebar-item>A</nile-inline-sidebar-item></nile-inline-sidebar>`); expect(el.querySelector('nile-inline-sidebar-item')).to.exist; });
51
+ it('44. slotted group', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar><nile-inline-sidebar-group label="G"><nile-inline-sidebar-item>A</nile-inline-sidebar-item></nile-inline-sidebar-group></nile-inline-sidebar>`); expect(el.querySelector('nile-inline-sidebar-group')).to.exist; });
52
+ it('45. multiple items', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar><nile-inline-sidebar-item>A</nile-inline-sidebar-item><nile-inline-sidebar-item>B</nile-inline-sidebar-item><nile-inline-sidebar-item>C</nile-inline-sidebar-item></nile-inline-sidebar>`); expect(el.querySelectorAll('nile-inline-sidebar-item').length).to.equal(3); });
53
+ it('46. emits nile-toggle on collapse', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); let detail: any; el.addEventListener('nile-toggle', ((e: CustomEvent) => { detail = e.detail; }) as EventListener); const btn = el.shadowRoot!.querySelector('.toggle-btn') as HTMLElement; btn.click(); expect(detail).to.exist; expect(detail.collapsed).to.be.true; });
54
+ it('47. emits nile-toggle on expand', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar collapsed></nile-inline-sidebar>`); let detail: any; el.addEventListener('nile-toggle', ((e: CustomEvent) => { detail = e.detail; }) as EventListener); const btn = el.shadowRoot!.querySelector('.toggle-btn') as HTMLElement; btn.click(); expect(detail).to.exist; expect(detail.collapsed).to.be.false; });
55
+ it('48. has styles', async () => { expect((await import('./nile-inline-sidebar')).NileInlineSidebar.styles).to.exist; });
56
+ it('49. is defined', async () => { expect(customElements.get('nile-inline-sidebar')).to.exist; });
57
+ it('50. shadow mode', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.mode).to.equal('open'); });
58
+ it('51. isConnected', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.isConnected).to.be.true; });
59
+ it('52. removal', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.remove(); expect(el.isConnected).to.be.false; });
60
+ it('53. outerHTML', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.outerHTML).to.contain('nile-inline-sidebar'); });
61
+ it('54. matches', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar class="x"></nile-inline-sidebar>`); expect(el.matches('.x')).to.be.true; });
62
+ it('55. closest', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.closest('nile-inline-sidebar')).to.equal(el); });
63
+ it('56. cloneNode', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect((el.cloneNode(true) as Element).tagName.toLowerCase()).to.equal('nile-inline-sidebar'); });
64
+ it('57. dispatchEvent', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); let f = false; el.addEventListener('c', () => (f = true)); el.dispatchEvent(new Event('c')); expect(f).to.be.true; });
65
+ it('58. updateComplete', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); const r = await el.updateComplete; expect(r).to.not.be.undefined; });
66
+ it('59. render method', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.render).to.be.a('function'); });
67
+ it('60. shadowRoot host', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.host).to.equal(el); });
68
+ it('61. class attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar class="s"></nile-inline-sidebar>`); expect(el.classList.contains('s')).to.be.true; });
69
+ it('62. id attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar id="s1"></nile-inline-sidebar>`); expect(el.id).to.equal('s1'); });
70
+ it('63. hidden', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar hidden></nile-inline-sidebar>`); expect(el.hidden).to.be.true; });
71
+ it('64. nodeType', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.nodeType).to.equal(1); });
72
+ it('65. localName', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.localName).to.equal('nile-inline-sidebar'); });
73
+ it('66. namespaceURI', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.namespaceURI).to.equal('http://www.w3.org/1999/xhtml'); });
74
+ it('67. ownerDocument', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.ownerDocument).to.equal(document); });
75
+ it('68. multiple instances', async () => { const c = await fixture(html`<div><nile-inline-sidebar></nile-inline-sidebar><nile-inline-sidebar></nile-inline-sidebar></div>`); expect(c.querySelectorAll('nile-inline-sidebar').length).to.equal(2); });
76
+ it('69. parent-child', async () => { const c = await fixture(html`<div><nile-inline-sidebar></nile-inline-sidebar></div>`); expect(c.querySelector('nile-inline-sidebar')!.parentElement).to.equal(c); });
77
+ it('70. createElement', async () => { const el = document.createElement('nile-inline-sidebar') as NileInlineSidebar; document.body.appendChild(el); await el.updateComplete; expect(el.shadowRoot).to.not.be.null; document.body.removeChild(el); });
78
+ it('71. dataset', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar data-idx="0"></nile-inline-sidebar>`); expect(el.dataset.idx).to.equal('0'); });
79
+ it('72. classList add', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.classList.add('z'); expect(el.classList.contains('z')).to.be.true; });
80
+ it('73. getBoundingClientRect', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.getBoundingClientRect()).to.exist; });
81
+ it('74. no form', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('form')).to.be.null; });
82
+ it('75. no input', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('input')).to.be.null; });
83
+ it('76. no anchor', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('a')).to.be.null; });
84
+ it('77. no img', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('img')).to.be.null; });
85
+ it('78. no svg', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('svg')).to.be.null; });
86
+ it('79. style attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar style="color:red"></nile-inline-sidebar>`); expect(el.style.color).to.equal('red'); });
87
+ it('80. data attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar data-x="1"></nile-inline-sidebar>`); expect(el.getAttribute('data-x')).to.equal('1'); });
88
+ it('81. aria-label', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar aria-label="Sidebar"></nile-inline-sidebar>`); expect(el.getAttribute('aria-label')).to.equal('Sidebar'); });
89
+ it('82. role', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar role="navigation"></nile-inline-sidebar>`); expect(el.getAttribute('role')).to.equal('navigation'); });
90
+ it('83. dir', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar dir="rtl"></nile-inline-sidebar>`); expect(el.dir).to.equal('rtl'); });
91
+ it('84. title attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar title="S"></nile-inline-sidebar>`); expect(el.title).to.equal('S'); });
92
+ it('85. lang attr', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar lang="en"></nile-inline-sidebar>`); expect(el.lang).to.equal('en'); });
93
+ it('86. tabindex', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar tabindex="0"></nile-inline-sidebar>`); expect(el.getAttribute('tabindex')).to.equal('0'); });
94
+ it('87. requestUpdate', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.requestUpdate(); await el.updateComplete; expect(el.shadowRoot).to.not.be.null; });
95
+ it('88. shadow childNodes', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.childNodes.length).to.be.greaterThan(0); });
96
+ it('89. scrollIntoView', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.scrollIntoView).to.be.a('function'); });
97
+ it('90. focus method', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.focus).to.be.a('function'); });
98
+ it('91. blur method', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.blur).to.be.a('function'); });
99
+ it('92. class toggle', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.classList.toggle('a'); expect(el.classList.contains('a')).to.be.true; });
100
+ it('93. toggle hidden', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.hidden = true; expect(el.hidden).to.be.true; });
101
+ it('94. dispatchCustomEvent', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); let d: any; el.addEventListener('t', ((e: CustomEvent) => { d = e.detail; }) as EventListener); el.dispatchEvent(new CustomEvent('t', { detail: 'x' })); expect(d).to.equal('x'); });
102
+ it('95. nested in div', async () => { const c = await fixture(html`<div><nile-inline-sidebar></nile-inline-sidebar></div>`); expect(c.querySelector('nile-inline-sidebar')).to.exist; });
103
+ it('96. no table', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('table')).to.be.null; });
104
+ it('97. no canvas', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); expect(el.shadowRoot!.querySelector('canvas')).to.be.null; });
105
+ it('98. setAttribute data', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); el.setAttribute('data-test', '1'); expect(el.dataset.test).to.equal('1'); });
106
+ it('99. multiple re-renders', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar></nile-inline-sidebar>`); for (let i = 0; i < 3; i++) { el.requestUpdate(); await el.updateComplete; } expect(el.shadowRoot).to.not.be.null; });
107
+ it('100. full integration', async () => { const el = await fixture<NileInlineSidebar>(html`<nile-inline-sidebar placement="right" class="s" id="s1" aria-label="Nav"><nile-inline-sidebar-group label="Main"><nile-inline-sidebar-item active>Dashboard</nile-inline-sidebar-item><nile-inline-sidebar-item>Analytics</nile-inline-sidebar-item><nile-inline-sidebar-item disabled>Admin</nile-inline-sidebar-item></nile-inline-sidebar-group></nile-inline-sidebar>`); expect(el.placement).to.equal('right'); expect(el.id).to.equal('s1'); expect(el.getAttribute('aria-label')).to.equal('Nav'); expect(el.querySelectorAll('nile-inline-sidebar-item').length).to.equal(3); expect(el.shadowRoot!.querySelector('.sidebar')).to.exist; expect(el.shadowRoot!.querySelector('nav')).to.exist; });
108
+ });
@@ -23,6 +23,9 @@ export class NileInlineSidebar extends NileElement {
23
23
 
24
24
  @property({ type: Boolean, reflect: true }) showTooltip = false;
25
25
 
26
+ /** The side on which the sidebar is placed. */
27
+ @property({ type: String, reflect: true }) placement: 'left' | 'right' = 'left';
28
+
26
29
  @state() private activeIndex: number = -1;
27
30
 
28
31
  @query('slot') private defaultSlot!: HTMLSlotElement;
@@ -47,6 +50,7 @@ export class NileInlineSidebar extends NileElement {
47
50
  connectedCallback() {
48
51
  super.connectedCallback();
49
52
  this.addEventListener('nile-click', this.handleItemSelect);
53
+ this.addEventListener('keydown', this.handleKeyDown);
50
54
  this.mutationObserver = new MutationObserver(() =>
51
55
  this.syncActiveFromItems()
52
56
  );
@@ -56,6 +60,7 @@ export class NileInlineSidebar extends NileElement {
56
60
  super.disconnectedCallback();
57
61
  this.mutationObserver?.disconnect();
58
62
  this.removeEventListener('nile-click', this.handleItemSelect);
63
+ this.removeEventListener('keydown', this.handleKeyDown);
59
64
  }
60
65
 
61
66
  firstUpdated() {
@@ -86,8 +91,96 @@ export class NileInlineSidebar extends NileElement {
86
91
  this.activeIndex = activeIndex;
87
92
  this.requestUpdate();
88
93
  }
94
+ this.updateTabIndices();
95
+ }
96
+
97
+
98
+ private get focusableItems(): HTMLElement[] {
99
+ return this.sidebarItems.filter(
100
+ item => !item.hasAttribute('disabled')
101
+ );
89
102
  }
90
103
 
104
+ private updateTabIndices() {
105
+ const items = this.sidebarItems;
106
+ if (!items.length) return;
107
+
108
+ const focusTarget =
109
+ this.activeIndex >= 0 ? items[this.activeIndex] : null;
110
+
111
+ items.forEach(item => {
112
+ if (item.hasAttribute('disabled')) {
113
+ item.setAttribute('tabindex', '-1');
114
+ } else if (item === focusTarget) {
115
+ item.setAttribute('tabindex', '0');
116
+ } else if (!focusTarget && item === this.focusableItems[0]) {
117
+ item.setAttribute('tabindex', '0');
118
+ } else {
119
+ item.setAttribute('tabindex', '-1');
120
+ }
121
+ });
122
+ }
123
+
124
+ private focusItem(item: HTMLElement) {
125
+ const items = this.sidebarItems;
126
+ items.forEach(el => el.setAttribute('tabindex', '-1'));
127
+ item.setAttribute('tabindex', '0');
128
+ item.focus();
129
+ }
130
+
131
+ private handleKeyDown = (event: KeyboardEvent) => {
132
+ if (this.collapsed) return;
133
+
134
+ const focusable = this.focusableItems;
135
+ if (!focusable.length) return;
136
+
137
+ const currentFocus = this.sidebarItems.find(
138
+ item =>
139
+ item === document.activeElement ||
140
+ item === this.shadowRoot?.activeElement ||
141
+ item.matches(':focus-within')
142
+ );
143
+
144
+ const currentIndex = currentFocus
145
+ ? focusable.indexOf(currentFocus)
146
+ : -1;
147
+
148
+ let nextIndex: number | null = null;
149
+
150
+ switch (event.key) {
151
+ case 'ArrowDown':
152
+ nextIndex =
153
+ currentIndex < focusable.length - 1 ? currentIndex + 1 : 0;
154
+ break;
155
+
156
+ case 'ArrowUp':
157
+ nextIndex =
158
+ currentIndex > 0 ? currentIndex - 1 : focusable.length - 1;
159
+ break;
160
+
161
+ case 'Home':
162
+ nextIndex = 0;
163
+ break;
164
+
165
+ case 'End':
166
+ nextIndex = focusable.length - 1;
167
+ break;
168
+
169
+ case 'Enter':
170
+ case ' ':
171
+ return;
172
+
173
+ default:
174
+ return;
175
+ }
176
+
177
+ event.preventDefault();
178
+
179
+ if (nextIndex !== null && focusable[nextIndex]) {
180
+ this.focusItem(focusable[nextIndex]);
181
+ }
182
+ };
183
+
91
184
  private handleItemSelect = (event: CustomEvent) => {
92
185
  const selectedItem = event.detail.item as HTMLElement;
93
186
  const index = this.sidebarItems.indexOf(selectedItem);
@@ -96,6 +189,7 @@ export class NileInlineSidebar extends NileElement {
96
189
  (item, i) => ((item as any).active = i === index)
97
190
  );
98
191
  this.activeIndex = index;
192
+ this.updateTabIndices();
99
193
 
100
194
  this.dispatchEvent(
101
195
  new CustomEvent('nile-change', {
@@ -146,7 +240,9 @@ export class NileInlineSidebar extends NileElement {
146
240
 
147
241
  private get menuItemsTemplate() {
148
242
  if (!this.sidebarItems?.length) return null;
149
-
243
+
244
+ const tooltipPlacement = this.placement === 'right' ? 'left' : 'right';
245
+
150
246
  return this.sidebarItems.map((item, index) => {
151
247
  const shouldShowTooltip = (item as any).tooltip;
152
248
  const isTruncated =
@@ -167,7 +263,7 @@ export class NileInlineSidebar extends NileElement {
167
263
  <nile-tooltip
168
264
  content=${item.textContent?.trim() || ''}
169
265
  hoist
170
- placement="right"
266
+ placement=${tooltipPlacement}
171
267
  >
172
268
  ${content}
173
269
  </nile-tooltip>
@@ -180,6 +276,11 @@ export class NileInlineSidebar extends NileElement {
180
276
 
181
277
 
182
278
  public render(): TemplateResult {
279
+ const isRight = this.placement === 'right';
280
+ const collapsedIcon = isRight ? 'menu_open' : 'menu_close';
281
+ const expandedIcon = isRight ? 'menu_close' : 'menu_open';
282
+ const actionPlacement = isRight ? 'bottom-end' : 'bottom-start';
283
+
183
284
  return html`
184
285
  <div class="sidebar" part="base">
185
286
  <div class="sidebar-header" part="header">
@@ -188,7 +289,7 @@ export class NileInlineSidebar extends NileElement {
188
289
  ? html`
189
290
  <nile-side-bar-action
190
291
  class="toggle-action"
191
- placement="bottom-start"
292
+ placement=${actionPlacement}
192
293
  hoist
193
294
  open
194
295
  triggerDropdown="hover"
@@ -199,7 +300,7 @@ export class NileInlineSidebar extends NileElement {
199
300
  variant="tertiary"
200
301
  @click=${this.toggleCollapse}
201
302
  >
202
- <nile-icon name="menu_close"></nile-icon>
303
+ <nile-icon name=${collapsedIcon}></nile-icon>
203
304
  </nile-button>
204
305
  <nile-side-bar-action-menu>
205
306
  ${this.menuItemsTemplate}
@@ -212,7 +313,7 @@ export class NileInlineSidebar extends NileElement {
212
313
  variant="tertiary"
213
314
  @click=${this.toggleCollapse}
214
315
  >
215
- <nile-icon name="menu_open"></nile-icon>
316
+ <nile-icon name=${expandedIcon}></nile-icon>
216
317
  </nile-button>
217
318
  `
218
319
  : null}
@@ -220,6 +321,8 @@ export class NileInlineSidebar extends NileElement {
220
321
 
221
322
  <nav
222
323
  class="sidebar-nav"
324
+ role="navigation"
325
+ aria-label="Sidebar"
223
326
  style=${this.collapsed ? 'display:none;' : ''}
224
327
  part="nav-items"
225
328
  >