@aquera/nile-elements 0.0.1-beta.3 → 0.0.1-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/index.d.ts +4 -0
  2. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/index.js +4 -0
  3. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/index.js.map +1 -1
  4. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/internal/tabbable.d.ts +8 -0
  5. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/internal/tabbable.js +65 -0
  6. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/internal/tabbable.js.map +1 -0
  7. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/index.d.ts +1 -0
  8. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/index.js +2 -0
  9. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/index.js.map +1 -0
  10. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.css.d.ts +12 -0
  11. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.css.js +23 -0
  12. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.css.js.map +1 -0
  13. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.d.ts +27 -0
  14. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.js +127 -0
  15. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-auto-complete/nile-auto-complete.js.map +1 -0
  16. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/index.d.ts +1 -0
  17. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/index.js +2 -0
  18. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/index.js.map +1 -0
  19. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.css.d.ts +12 -0
  20. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.css.js +146 -0
  21. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.css.js.map +1 -0
  22. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.d.ts +44 -0
  23. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.js +175 -0
  24. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-chip/nile-chip.js.map +1 -0
  25. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/index.d.ts +1 -0
  26. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/index.js +2 -0
  27. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/index.js.map +1 -0
  28. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.css.d.ts +12 -0
  29. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.css.js +60 -0
  30. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.css.js.map +1 -0
  31. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.d.ts +105 -0
  32. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.js +412 -0
  33. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-dropdown/nile-dropdown.js.map +1 -0
  34. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-input/nile-input.css.js +20 -0
  35. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-input/nile-input.css.js.map +1 -1
  36. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/index.d.ts +1 -41
  37. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/index.js +1 -119
  38. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/index.js.map +1 -1
  39. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.css.d.ts +12 -0
  40. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.css.js +28 -0
  41. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.css.js.map +1 -0
  42. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.d.ts +43 -0
  43. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.js +142 -0
  44. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu/nile-menu.js.map +1 -0
  45. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/index.d.ts +1 -0
  46. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/index.js +2 -0
  47. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/index.js.map +1 -0
  48. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.css.d.ts +12 -0
  49. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.css.js +121 -0
  50. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.css.js.map +1 -0
  51. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.d.ts +62 -0
  52. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.js +173 -0
  53. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/src/nile-menu-item/nile-menu-item.js.map +1 -0
  54. package/.rollup.cache/Users/ravisankar/aquera/nile/packages/nile-elements/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/index.cjs.js +1 -1
  56. package/dist/index.esm.js +1 -1
  57. package/dist/internal/slot.cjs.js +1 -1
  58. package/dist/internal/slot.cjs.js.map +1 -1
  59. package/dist/internal/slot.esm.js +1 -1
  60. package/dist/internal/tabbable.cjs.js +2 -0
  61. package/dist/internal/tabbable.cjs.js.map +1 -0
  62. package/dist/internal/tabbable.esm.js +1 -0
  63. package/dist/nile-auto-complete/index.cjs.js +2 -0
  64. package/dist/nile-auto-complete/index.cjs.js.map +1 -0
  65. package/dist/nile-auto-complete/index.esm.js +1 -0
  66. package/dist/nile-auto-complete/nile-auto-complete.cjs.js +2 -0
  67. package/dist/nile-auto-complete/nile-auto-complete.cjs.js.map +1 -0
  68. package/dist/nile-auto-complete/nile-auto-complete.css.cjs.js +2 -0
  69. package/dist/nile-auto-complete/nile-auto-complete.css.cjs.js.map +1 -0
  70. package/dist/nile-auto-complete/nile-auto-complete.css.esm.js +11 -0
  71. package/dist/nile-auto-complete/nile-auto-complete.esm.js +21 -0
  72. package/dist/nile-chip/index.cjs.js +2 -0
  73. package/dist/nile-chip/index.cjs.js.map +1 -0
  74. package/dist/nile-chip/index.esm.js +1 -0
  75. package/dist/nile-chip/nile-chip.cjs.js +2 -0
  76. package/dist/nile-chip/nile-chip.cjs.js.map +1 -0
  77. package/dist/nile-chip/nile-chip.css.cjs.js +2 -0
  78. package/dist/nile-chip/nile-chip.css.cjs.js.map +1 -0
  79. package/dist/nile-chip/nile-chip.css.esm.js +134 -0
  80. package/dist/nile-chip/nile-chip.esm.js +46 -0
  81. package/dist/nile-dropdown/index.cjs.js +2 -0
  82. package/dist/nile-dropdown/index.cjs.js.map +1 -0
  83. package/dist/nile-dropdown/index.esm.js +1 -0
  84. package/dist/nile-dropdown/nile-dropdown.cjs.js +2 -0
  85. package/dist/nile-dropdown/nile-dropdown.cjs.js.map +1 -0
  86. package/dist/nile-dropdown/nile-dropdown.css.cjs.js +2 -0
  87. package/dist/nile-dropdown/nile-dropdown.css.cjs.js.map +1 -0
  88. package/dist/nile-dropdown/nile-dropdown.css.esm.js +48 -0
  89. package/dist/nile-dropdown/nile-dropdown.esm.js +33 -0
  90. package/dist/nile-input/nile-input.css.cjs.js +1 -1
  91. package/dist/nile-input/nile-input.css.cjs.js.map +1 -1
  92. package/dist/nile-input/nile-input.css.esm.js +20 -0
  93. package/dist/nile-menu/index.cjs.js +1 -1
  94. package/dist/nile-menu/index.cjs.js.map +1 -1
  95. package/dist/nile-menu/index.esm.js +1 -53
  96. package/dist/nile-menu/nile-menu.cjs.js +2 -0
  97. package/dist/nile-menu/nile-menu.cjs.js.map +1 -0
  98. package/dist/nile-menu/nile-menu.css.cjs.js +2 -0
  99. package/dist/nile-menu/nile-menu.css.cjs.js.map +1 -0
  100. package/dist/nile-menu/nile-menu.css.esm.js +16 -0
  101. package/dist/nile-menu/nile-menu.esm.js +8 -0
  102. package/dist/nile-menu-item/index.cjs.js +2 -0
  103. package/dist/nile-menu-item/index.cjs.js.map +1 -0
  104. package/dist/nile-menu-item/index.esm.js +1 -0
  105. package/dist/nile-menu-item/nile-menu-item.cjs.js +2 -0
  106. package/dist/nile-menu-item/nile-menu-item.cjs.js.map +1 -0
  107. package/dist/nile-menu-item/nile-menu-item.css.cjs.js +2 -0
  108. package/dist/nile-menu-item/nile-menu-item.css.cjs.js.map +1 -0
  109. package/dist/nile-menu-item/nile-menu-item.css.esm.js +109 -0
  110. package/dist/nile-menu-item/nile-menu-item.esm.js +20 -0
  111. package/dist/src/index.d.ts +4 -0
  112. package/dist/src/index.js +4 -0
  113. package/dist/src/index.js.map +1 -1
  114. package/dist/src/internal/tabbable.d.ts +8 -0
  115. package/dist/src/internal/tabbable.js +65 -0
  116. package/dist/src/internal/tabbable.js.map +1 -0
  117. package/dist/src/nile-auto-complete/index.d.ts +1 -0
  118. package/dist/src/nile-auto-complete/index.js +2 -0
  119. package/dist/src/nile-auto-complete/index.js.map +1 -0
  120. package/dist/src/nile-auto-complete/nile-auto-complete.css.d.ts +12 -0
  121. package/dist/src/nile-auto-complete/nile-auto-complete.css.js +23 -0
  122. package/dist/src/nile-auto-complete/nile-auto-complete.css.js.map +1 -0
  123. package/dist/src/nile-auto-complete/nile-auto-complete.d.ts +27 -0
  124. package/dist/src/nile-auto-complete/nile-auto-complete.js +127 -0
  125. package/dist/src/nile-auto-complete/nile-auto-complete.js.map +1 -0
  126. package/dist/src/nile-chip/index.d.ts +1 -0
  127. package/dist/src/nile-chip/index.js +2 -0
  128. package/dist/src/nile-chip/index.js.map +1 -0
  129. package/dist/src/nile-chip/nile-chip.css.d.ts +12 -0
  130. package/dist/src/nile-chip/nile-chip.css.js +146 -0
  131. package/dist/src/nile-chip/nile-chip.css.js.map +1 -0
  132. package/dist/src/nile-chip/nile-chip.d.ts +44 -0
  133. package/dist/src/nile-chip/nile-chip.js +175 -0
  134. package/dist/src/nile-chip/nile-chip.js.map +1 -0
  135. package/dist/src/nile-dropdown/index.d.ts +1 -0
  136. package/dist/src/nile-dropdown/index.js +2 -0
  137. package/dist/src/nile-dropdown/index.js.map +1 -0
  138. package/dist/src/nile-dropdown/nile-dropdown.css.d.ts +12 -0
  139. package/dist/src/nile-dropdown/nile-dropdown.css.js +60 -0
  140. package/dist/src/nile-dropdown/nile-dropdown.css.js.map +1 -0
  141. package/dist/src/nile-dropdown/nile-dropdown.d.ts +105 -0
  142. package/dist/src/nile-dropdown/nile-dropdown.js +412 -0
  143. package/dist/src/nile-dropdown/nile-dropdown.js.map +1 -0
  144. package/dist/src/nile-input/nile-input.css.js +20 -0
  145. package/dist/src/nile-input/nile-input.css.js.map +1 -1
  146. package/dist/src/nile-menu/index.d.ts +1 -41
  147. package/dist/src/nile-menu/index.js +1 -119
  148. package/dist/src/nile-menu/index.js.map +1 -1
  149. package/dist/src/nile-menu/nile-menu.css.d.ts +12 -0
  150. package/dist/src/nile-menu/nile-menu.css.js +28 -0
  151. package/dist/src/nile-menu/nile-menu.css.js.map +1 -0
  152. package/dist/src/nile-menu/nile-menu.d.ts +43 -0
  153. package/dist/src/nile-menu/nile-menu.js +142 -0
  154. package/dist/src/nile-menu/nile-menu.js.map +1 -0
  155. package/dist/src/nile-menu-item/index.d.ts +1 -0
  156. package/dist/src/nile-menu-item/index.js +2 -0
  157. package/dist/src/nile-menu-item/index.js.map +1 -0
  158. package/dist/src/nile-menu-item/nile-menu-item.css.d.ts +12 -0
  159. package/dist/src/nile-menu-item/nile-menu-item.css.js +121 -0
  160. package/dist/src/nile-menu-item/nile-menu-item.css.js.map +1 -0
  161. package/dist/src/nile-menu-item/nile-menu-item.d.ts +62 -0
  162. package/dist/src/nile-menu-item/nile-menu-item.js +173 -0
  163. package/dist/src/nile-menu-item/nile-menu-item.js.map +1 -0
  164. package/dist/tsconfig.tsbuildinfo +1 -1
  165. package/dist/watch.cjs.js +1 -1
  166. package/dist/watch.cjs.js.map +1 -1
  167. package/dist/watch.esm.js +1 -1
  168. package/package.json +1 -1
  169. package/src/index.ts +4 -0
  170. package/src/internal/tabbable.ts +81 -0
  171. package/src/nile-auto-complete/index.ts +1 -0
  172. package/src/nile-auto-complete/nile-auto-complete.css.ts +25 -0
  173. package/src/nile-auto-complete/nile-auto-complete.ts +132 -0
  174. package/src/nile-chip/index.ts +1 -0
  175. package/src/nile-chip/nile-chip.css.ts +148 -0
  176. package/src/nile-chip/nile-chip.ts +183 -0
  177. package/src/nile-dropdown/index.ts +1 -0
  178. package/src/nile-dropdown/nile-dropdown.css.ts +62 -0
  179. package/src/nile-dropdown/nile-dropdown.ts +461 -0
  180. package/src/nile-input/nile-input.css.ts +20 -0
  181. package/src/nile-menu/index.ts +1 -116
  182. package/src/nile-menu/nile-menu.css.ts +30 -0
  183. package/src/nile-menu/nile-menu.ts +169 -0
  184. package/src/nile-menu-item/index.ts +1 -0
  185. package/src/nile-menu-item/nile-menu-item.css.ts +123 -0
  186. package/src/nile-menu-item/nile-menu-item.ts +171 -0
  187. package/src/nile-menu/nile-menu.scss +0 -0
@@ -0,0 +1,169 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import { query } from 'lit/decorators.js';
5
+ import NileElement from '../internal/nile-element';
6
+ import type { CSSResultGroup } from 'lit';
7
+ import type NileMenuItem from '../nile-menu-item/nile-menu-item';
8
+ import {styles} from './nile-menu.css';
9
+
10
+ /**
11
+ * An nile-menu element.
12
+ * @summary Menus provide a list of options for the user to choose from.
13
+ *
14
+ * @slot - The menu's content, including menu items, menu labels, and dividers.
15
+ *
16
+ * @event nile-select - Emitted when a menu item is selected.
17
+ * @fires count-changed - Indicates when the count changes
18
+ * @slot - This element has a slot
19
+ * @csspart button - The button
20
+ */
21
+
22
+ @customElement('nile-menu')
23
+ export class NileMenu extends NileElement {
24
+ static styles: CSSResultGroup = styles;
25
+
26
+ @query('slot') defaultSlot: HTMLSlotElement;
27
+
28
+ connectedCallback() {
29
+ super.connectedCallback();
30
+ this.setAttribute('role', 'menu');
31
+ }
32
+
33
+ private handleClick(event: MouseEvent) {
34
+ const target = event.target as HTMLElement;
35
+ const item = target.closest('nile-menu-item');
36
+
37
+ // if (!item || item.disabled || item.inert) {
38
+ if (!item || item.disabled) {
39
+ return;
40
+ }
41
+
42
+ if (item.type === 'checkbox') {
43
+ item.checked = !item.checked;
44
+ }
45
+
46
+ this.emit('nile-select', { value :item.value });
47
+ }
48
+
49
+ private handleKeyDown(event: KeyboardEvent) {
50
+ // Make a selection when pressing enter
51
+ if (event.key === 'Enter') {
52
+ const item = this.getCurrentItem();
53
+ event.preventDefault();
54
+
55
+ // Simulate a click to support @click handlers on menu items that also work with the keyboard
56
+ item?.click();
57
+ }
58
+
59
+ // Prevent scrolling when space is pressed
60
+ if (event.key === ' ') {
61
+ event.preventDefault();
62
+ }
63
+
64
+ // Move the selection when pressing down or up
65
+ if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {
66
+ const items = this.getAllItems();
67
+ const activeItem = this.getCurrentItem();
68
+ let index = activeItem ? items.indexOf(activeItem) : 0;
69
+
70
+ if (items.length > 0) {
71
+ event.preventDefault();
72
+
73
+ if (event.key === 'ArrowDown') {
74
+ index++;
75
+ } else if (event.key === 'ArrowUp') {
76
+ index--;
77
+ } else if (event.key === 'Home') {
78
+ index = 0;
79
+ } else if (event.key === 'End') {
80
+ index = items.length - 1;
81
+ }
82
+
83
+ if (index < 0) {
84
+ index = items.length - 1;
85
+ }
86
+ if (index > items.length - 1) {
87
+ index = 0;
88
+ }
89
+
90
+ this.setCurrentItem(items[index]);
91
+ items[index].focus();
92
+ }
93
+ }
94
+ }
95
+
96
+ private handleMouseDown(event: MouseEvent) {
97
+ const target = event.target as HTMLElement;
98
+
99
+ if (this.isMenuItem(target)) {
100
+ this.setCurrentItem(target as NileMenuItem);
101
+ }
102
+ }
103
+
104
+ private handleSlotChange() {
105
+ const items = this.getAllItems();
106
+
107
+ // Reset the roving tab index when the slotted items change
108
+ if (items.length > 0) {
109
+ this.setCurrentItem(items[0]);
110
+ }
111
+ }
112
+
113
+ private isMenuItem(item: HTMLElement) {
114
+ return (
115
+ item.tagName.toLowerCase() === 'nile-menu-item' ||
116
+ ['menuitem', 'menuitemcheckbox', 'menuitemradio'].includes(item.getAttribute('role') ?? '')
117
+ );
118
+ }
119
+
120
+ /** @internal Gets all slotted menu items, ignoring dividers, headers, and other elements. */
121
+ getAllItems() {
122
+ return [...this.defaultSlot.assignedElements({ flatten: true })].filter((el: HTMLElement) => {
123
+ if ( !this.isMenuItem(el)) {
124
+ // if (el.inert || !this.isMenuItem(el)) {
125
+ return false;
126
+ }
127
+ return true;
128
+ }) as NileMenuItem[];
129
+ }
130
+
131
+ /**
132
+ * @internal Gets the current menu item, which is the menu item that has `tabindex="0"` within the roving tab index.
133
+ * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the "active" item.
134
+ */
135
+ getCurrentItem() {
136
+ return this.getAllItems().find(i => i.getAttribute('tabindex') === '0');
137
+ }
138
+
139
+ /**
140
+ * @internal Sets the current menu item to the specified element. This sets `tabindex="0"` on the target element and
141
+ * `tabindex="-1"` to all other items. This method must be called prior to setting focus on a menu item.
142
+ */
143
+ setCurrentItem(item: NileMenuItem) {
144
+ const items = this.getAllItems();
145
+
146
+ // Update tab indexes
147
+ items.forEach(i => {
148
+ i.setAttribute('tabindex', i === item ? '0' : '-1');
149
+ });
150
+ }
151
+
152
+ render() {
153
+ return html`
154
+ <slot
155
+ @slotchange=${this.handleSlotChange}
156
+ @click=${this.handleClick}
157
+ @keydown=${this.handleKeyDown}
158
+ @mousedown=${this.handleMouseDown}
159
+ ></slot>
160
+ `;
161
+ }
162
+ }
163
+ export default NileMenu;
164
+
165
+ declare global {
166
+ interface HTMLElementTagNameMap {
167
+ 'nile-menu': NileMenu;
168
+ }
169
+ }
@@ -0,0 +1 @@
1
+ export { NileMenuItem } from './nile-menu-item';
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { css } from 'lit-element';
9
+
10
+ /**
11
+ * MenuItem CSS
12
+ */
13
+ export const styles = css`
14
+ :host {
15
+ box-sizing: border-box;
16
+ }
17
+
18
+ :host *,
19
+ :host *::before,
20
+ :host *::after {
21
+ box-sizing: inherit;
22
+ }
23
+
24
+ [hidden] {
25
+ display: none !important;
26
+ }
27
+
28
+ :host {
29
+ display: block;
30
+ }
31
+
32
+ :host([inert]) {
33
+ display: none;
34
+ }
35
+
36
+ .menu-item {
37
+ position: relative;
38
+ display: flex;
39
+ align-items: stretch;
40
+ font-size: 1rem;
41
+ font-weight: 400;
42
+ line-height: 1.8;
43
+ letter-spacing: normal;
44
+ color: hsl(240 5.3% 26.1%);
45
+ padding: 0.25rem 0.25rem;
46
+ transition: 150ms fill;
47
+ user-select: none;
48
+ white-space: nowrap;
49
+ cursor: pointer;
50
+ }
51
+
52
+ .menu-item.menu-item--disabled {
53
+ outline: none;
54
+ opacity: 0.5;
55
+ cursor: not-allowed;
56
+ }
57
+
58
+ .menu-item .menu-item__label {
59
+ flex: 1 1 auto;
60
+ display: inline-block;
61
+ }
62
+
63
+ .menu-item .menu-item__prefix {
64
+ flex: 0 0 auto;
65
+ display: flex;
66
+ align-items: center;
67
+ }
68
+
69
+ .menu-item .menu-item__prefix::slotted(*) {
70
+ margin-inline-end: 0.5rem;
71
+ }
72
+
73
+ .menu-item .menu-item__suffix {
74
+ flex: 0 0 auto;
75
+ display: flex;
76
+ align-items: center;
77
+ }
78
+
79
+ .menu-item .menu-item__suffix::slotted(*) {
80
+ margin-inline-start: 0.5rem;
81
+ }
82
+
83
+ :host(:focus-visible) {
84
+ outline: none;
85
+ }
86
+
87
+ :host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item {
88
+ background-color: hsl(240 4.8% 95.9%);
89
+ color: hsl(0, 0%, 0%);
90
+ }
91
+
92
+ :host(:focus-visible) .menu-item {
93
+ outline: none;
94
+ background-color: hsl(200.4 98% 39.4%);
95
+ color: hsl(0, 0%, 100%);
96
+ opacity: 1;
97
+ }
98
+
99
+ .menu-item .menu-item__check,
100
+ .menu-item .menu-item__chevron {
101
+ flex: 0 0 auto;
102
+ display: flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ width: 1.5em;
106
+ visibility: hidden;
107
+ }
108
+
109
+ .menu-item--checked .menu-item__check,
110
+ .menu-item--has-submenu .menu-item__chevron {
111
+ visibility: visible;
112
+ }
113
+
114
+ @media (forced-colors: active) {
115
+ :host(:hover:not([aria-disabled='true'])) .menu-item,
116
+ :host(:focus-visible) .menu-item {
117
+ outline: dashed 1px SelectedItem;
118
+ outline-offset: -1px;
119
+ }
120
+ }
121
+ `;
122
+
123
+ export default [styles];
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import {LitElement, html, property, CSSResultArray, TemplateResult} from 'lit-element';
9
+ import { customElement } from 'lit/decorators.js';
10
+ import {styles} from './nile-menu-item.css';
11
+ import '../nile-icon';
12
+ import { classMap } from 'lit/directives/class-map.js';
13
+ import { query } from 'lit/decorators.js';
14
+ import { getTextContent } from '../internal/slot';
15
+ import { watch } from '../internal/watch';
16
+ import NileElement from '../internal/nile-element';
17
+ import type { CSSResultGroup } from 'lit';
18
+ /**
19
+ * Nile icon component.
20
+ *
21
+ * @tag nile-menu-item
22
+ *
23
+ * @summary Menu items provide options for the user to pick from in a menu.
24
+ * @status stable
25
+ * @since 2.0
26
+ *
27
+ * @dependency nile-icon
28
+ *
29
+ * @slot - The menu item's label.
30
+ * @slot prefix - Used to prepend an icon or similar element to the menu item.
31
+ * @slot suffix - Used to append an icon or similar element to the menu item.
32
+ *
33
+ * @csspart base - The component's base wrapper.
34
+ * @csspart checked-icon - The checked icon, which is only visible when the menu item is checked.
35
+ * @csspart prefix - The prefix container.
36
+ * @csspart label - The menu item label.
37
+ * @csspart suffix - The suffix container.
38
+ * @csspart submenu-icon - The submenu icon, visible only when the menu item has a submenu (not yet implemented).
39
+ */
40
+
41
+ @customElement('nile-menu-item')
42
+ export class NileMenuItem extends NileElement {
43
+ static styles: CSSResultGroup = styles;
44
+
45
+ private cachedTextLabel: string;
46
+
47
+ @query('slot:not([name])') defaultSlot: HTMLSlotElement;
48
+
49
+ @query('.menu-item') menuItem: HTMLElement;
50
+
51
+ /** The type of menu item to render. To use `checked`, this value must be set to `checkbox`. */
52
+ @property() type: 'normal' | 'checkbox' = 'normal';
53
+
54
+ /** Draws the item in a checked state. */
55
+ @property({ type: Boolean, reflect: true }) checked = false;
56
+
57
+ /** A unique value to store in the menu item. This can be used as a way to identify menu items when selected. */
58
+ @property() value = '';
59
+
60
+ /** Draws the menu item in a disabled state, preventing selection. */
61
+ @property({ type: Boolean, reflect: true }) disabled = false;
62
+
63
+ connectedCallback() {
64
+ super.connectedCallback();
65
+ this.handleHostClick = this.handleHostClick.bind(this);
66
+ this.addEventListener('click', this.handleHostClick);
67
+ }
68
+
69
+ disconnectedCallback() {
70
+ super.disconnectedCallback();
71
+ this.removeEventListener('click', this.handleHostClick);
72
+ }
73
+
74
+ private handleDefaultSlotChange() {
75
+ const textLabel = this.getTextLabel();
76
+
77
+ // Ignore the first time the label is set
78
+ if (typeof this.cachedTextLabel === 'undefined') {
79
+ this.cachedTextLabel = textLabel;
80
+ return;
81
+ }
82
+
83
+ // When the label changes, emit a slotchange event so parent controls see it
84
+ if (textLabel !== this.cachedTextLabel) {
85
+ this.cachedTextLabel = textLabel;
86
+ this.emit('slotchange', { bubbles: true, composed: false, cancelable: false });
87
+ }
88
+ }
89
+
90
+ private handleHostClick(event: MouseEvent) {
91
+ // Prevent the click event from being emitted when the button is disabled or loading
92
+ if (this.disabled) {
93
+ event.preventDefault();
94
+ event.stopImmediatePropagation();
95
+ }
96
+ }
97
+
98
+ @watch('checked')
99
+ handleCheckedChange() {
100
+ // For proper accessibility, users have to use type="checkbox" to use the checked attribute
101
+ if (this.checked && this.type !== 'checkbox') {
102
+ this.checked = false;
103
+ console.error('The checked attribute can only be used on menu items with type="checkbox"', this);
104
+ return;
105
+ }
106
+
107
+ // Only checkbox types can receive the aria-checked attribute
108
+ if (this.type === 'checkbox') {
109
+ this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
110
+ } else {
111
+ this.removeAttribute('aria-checked');
112
+ }
113
+ }
114
+
115
+ @watch('disabled')
116
+ handleDisabledChange() {
117
+ this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
118
+ }
119
+
120
+ @watch('type')
121
+ handleTypeChange() {
122
+ if (this.type === 'checkbox') {
123
+ this.setAttribute('role', 'menuitemcheckbox');
124
+ this.setAttribute('aria-checked', this.checked ? 'true' : 'false');
125
+ } else {
126
+ this.setAttribute('role', 'menuitem');
127
+ this.removeAttribute('aria-checked');
128
+ }
129
+ }
130
+
131
+ /** Returns a text label based on the contents of the menu item's default slot. */
132
+ getTextLabel() {
133
+ return getTextContent(this.defaultSlot);
134
+ }
135
+
136
+ render() {
137
+ return html`
138
+ <div
139
+ part="base"
140
+ class=${classMap({
141
+ 'menu-item': true,
142
+ 'menu-item--checked': this.checked,
143
+ 'menu-item--disabled': this.disabled,
144
+ 'menu-item--has-submenu': false // reserved for future use
145
+ })}
146
+ >
147
+ <span part="checked-icon" class="menu-item__check">
148
+ <nile-icon name="check" library="system" aria-hidden="true"></nile-icon>
149
+ </span>
150
+
151
+ <slot name="prefix" part="prefix" class="menu-item__prefix"></slot>
152
+
153
+ <slot part="label" class="menu-item__label" @slotchange=${this.handleDefaultSlotChange}></slot>
154
+
155
+ <slot name="suffix" part="suffix" class="menu-item__suffix"></slot>
156
+
157
+ <span part="submenu-icon" class="menu-item__chevron">
158
+ <nile-icon name="chevron-right" library="system" aria-hidden="true"></nile-icon>
159
+ </span>
160
+ </div>
161
+ `;
162
+ }
163
+ }
164
+
165
+ export default NileMenuItem;
166
+
167
+ declare global {
168
+ interface HTMLElementTagNameMap {
169
+ 'nile-menu-item': NileMenuItem;
170
+ }
171
+ }
File without changes