vira 32.4.0 → 33.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/directives/index.d.ts +2 -0
  2. package/dist/directives/index.js +2 -0
  3. package/dist/directives/popover.directive.d.ts +29 -0
  4. package/dist/directives/popover.directive.js +45 -0
  5. package/dist/directives/tooltip.directive.d.ts +60 -0
  6. package/dist/directives/tooltip.directive.js +99 -0
  7. package/dist/elements/color/vira-color-picker.element.d.ts +1 -1
  8. package/dist/elements/color/vira-color-picker.element.js +17 -15
  9. package/dist/elements/index.d.ts +5 -5
  10. package/dist/elements/index.js +5 -5
  11. package/dist/elements/{pop-up → popover}/vira-menu-item.element.d.ts +4 -4
  12. package/dist/elements/{pop-up → popover}/vira-menu-item.element.js +12 -3
  13. package/dist/elements/popover/vira-menu-trigger.element.d.ts +56 -0
  14. package/dist/elements/{pop-up → popover}/vira-menu-trigger.element.js +19 -30
  15. package/dist/elements/popover/vira-menu.element.d.ts +35 -0
  16. package/dist/elements/popover/vira-menu.element.js +262 -0
  17. package/dist/elements/popover/vira-popover-trigger.element.d.ts +50 -0
  18. package/dist/elements/popover/vira-popover-trigger.element.js +307 -0
  19. package/dist/elements/popover/vira-tooltip.element.d.ts +10 -0
  20. package/dist/elements/popover/vira-tooltip.element.js +176 -0
  21. package/dist/elements/vira-drawer.element.js +1 -1
  22. package/dist/elements/vira-dropdown.element.d.ts +40 -13
  23. package/dist/elements/vira-dropdown.element.js +375 -69
  24. package/dist/elements/vira-form.element.js +10 -16
  25. package/dist/elements/vira-json-form.element.js +40 -36
  26. package/dist/elements/vira-modal.element.js +1 -1
  27. package/dist/elements/vira-tabs.element.d.ts +3 -9
  28. package/dist/elements/vira-tabs.element.js +5 -6
  29. package/dist/elements/vira-theme-switcher.element.js +3 -3
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/util/anchored-popover.d.ts +40 -0
  33. package/dist/util/anchored-popover.js +70 -0
  34. package/dist/util/fuzzy-match.d.ts +16 -0
  35. package/dist/util/fuzzy-match.js +24 -0
  36. package/dist/util/index.d.ts +5 -3
  37. package/dist/util/index.js +5 -3
  38. package/dist/util/{pop-up-helpers.d.ts → menu-helpers.d.ts} +8 -19
  39. package/dist/util/{pop-up-helpers.js → menu-helpers.js} +12 -19
  40. package/dist/util/popover-manager.d.ts +123 -0
  41. package/dist/util/popover-manager.js +414 -0
  42. package/dist/util/vira-dropdown-option.d.ts +30 -0
  43. package/dist/util/vira-dropdown-option.js +8 -0
  44. package/dist/util/vira-form-fields.d.ts +2 -2
  45. package/dist/util/vira-theme-client.d.ts +1 -1
  46. package/dist/util/vira-theme-client.js +3 -3
  47. package/package.json +2 -1
  48. package/dist/elements/pop-up/vira-menu-trigger.element.d.ts +0 -45
  49. package/dist/elements/pop-up/vira-menu.element.d.ts +0 -36
  50. package/dist/elements/pop-up/vira-menu.element.js +0 -88
  51. package/dist/elements/pop-up/vira-pop-up-trigger.element.d.ts +0 -109
  52. package/dist/elements/pop-up/vira-pop-up-trigger.element.js +0 -408
  53. package/dist/elements/vira-select.element.d.ts +0 -44
  54. package/dist/elements/vira-select.element.js +0 -418
  55. package/dist/util/pop-up-manager.d.ts +0 -200
  56. package/dist/util/pop-up-manager.js +0 -258
  57. package/dist/util/vira-select-option.d.ts +0 -31
  58. package/dist/util/vira-select-option.js +0 -8
@@ -0,0 +1,2 @@
1
+ export * from './popover.directive.js';
2
+ export * from './tooltip.directive.js';
@@ -0,0 +1,2 @@
1
+ export * from './popover.directive.js';
2
+ export * from './tooltip.directive.js';
@@ -0,0 +1,29 @@
1
+ import { AsyncDirective, type PartInfo } from 'element-vir';
2
+ import { type PopoverManager, type PopoverOptions } from '../util/popover-manager.js';
3
+ /**
4
+ * The directive class behind {@link popover}.
5
+ *
6
+ * @category Internal
7
+ */
8
+ export declare class PopoverDirective extends AsyncDirective {
9
+ protected popoverManager: PopoverManager | undefined;
10
+ constructor(partInfo: PartInfo);
11
+ /** Applies the latest directive arguments. */
12
+ update(partInfo: PartInfo, [popoverManager, options,]: [
13
+ PopoverManager,
14
+ Readonly<PopoverOptions>
15
+ ]): undefined;
16
+ /** Renders nothing, this directive only attaches behavior to its element. */
17
+ render(popoverManager: PopoverManager, options: Readonly<PopoverOptions>): undefined;
18
+ protected disconnected(): void;
19
+ /** Re-opens a popover that `trigger` forces open. */
20
+ protected reconnected(): void;
21
+ }
22
+ /**
23
+ * Connects a {@link PopoverManager} to the element that this directive is attached to, so that the
24
+ * manager's popover opens anchored to that element.
25
+ *
26
+ * @category Popover
27
+ * @category Directives
28
+ */
29
+ export declare const popover: (popoverManager: PopoverManager, options: Readonly<PopoverOptions>) => import("element-vir").DirectiveResult<typeof PopoverDirective>;
@@ -0,0 +1,45 @@
1
+ import { assertWrap } from '@augment-vir/assert';
2
+ import { assertIsElementPartInfo, AsyncDirective, directive } from 'element-vir';
3
+ const directiveName = 'popover';
4
+ /**
5
+ * The directive class behind {@link popover}.
6
+ *
7
+ * @category Internal
8
+ */
9
+ export class PopoverDirective extends AsyncDirective {
10
+ popoverManager;
11
+ constructor(partInfo) {
12
+ super(partInfo);
13
+ assertIsElementPartInfo(partInfo, directiveName);
14
+ }
15
+ /** Applies the latest directive arguments. */
16
+ update(partInfo, [popoverManager, options,]) {
17
+ assertIsElementPartInfo(partInfo, directiveName);
18
+ if (popoverManager !== this.popoverManager) {
19
+ this.popoverManager?.destroy();
20
+ this.popoverManager = popoverManager;
21
+ }
22
+ popoverManager.update(assertWrap.instanceOf(partInfo.element, HTMLElement), options);
23
+ return this.render(popoverManager, options);
24
+ }
25
+ /** Renders nothing, this directive only attaches behavior to its element. */
26
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
+ render(popoverManager, options) {
28
+ return undefined;
29
+ }
30
+ disconnected() {
31
+ this.popoverManager?.close();
32
+ }
33
+ /** Re-opens a popover that `trigger` forces open. */
34
+ reconnected() {
35
+ this.popoverManager?.applyForcedState();
36
+ }
37
+ }
38
+ /**
39
+ * Connects a {@link PopoverManager} to the element that this directive is attached to, so that the
40
+ * manager's popover opens anchored to that element.
41
+ *
42
+ * @category Popover
43
+ * @category Directives
44
+ */
45
+ export const popover = directive(PopoverDirective);
@@ -0,0 +1,60 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
+ import { AsyncDirective, type HtmlInterpolation, type PartInfo } from 'element-vir';
3
+ import { ViraTooltip } from '../elements/popover/vira-tooltip.element.js';
4
+ import { PopoverManager, type PopoverOptions, PopoverTrigger } from '../util/popover-manager.js';
5
+ /**
6
+ * Options for {@link tooltip}.
7
+ *
8
+ * @category Popover
9
+ */
10
+ export type TooltipOptions = PartialWithUndefined<{
11
+ /** Defaults to {@link PopoverTrigger.Hover}. `true` or `false` force the tooltip open or closed. */
12
+ trigger: boolean | PopoverTrigger;
13
+ }> & Pick<PopoverOptions, 'delay' | 'timeout'>;
14
+ /**
15
+ * The directive class behind {@link tooltip}.
16
+ *
17
+ * @category Internal
18
+ */
19
+ export declare class TooltipDirective extends AsyncDirective {
20
+ content: HtmlInterpolation;
21
+ /** Only exists while the tooltip is shown. */
22
+ tooltipElement: (typeof ViraTooltip)['InstanceType'] | undefined;
23
+ readonly popoverManager: PopoverManager;
24
+ constructor(partInfo: PartInfo);
25
+ /** Applies the latest directive arguments. */
26
+ update(partInfo: PartInfo, [content, options,]: [
27
+ HtmlInterpolation,
28
+ TooltipOptions?
29
+ ]): undefined;
30
+ /** Creates a new {@link ViraTooltip} after `anchor`, replacing any previous one. */
31
+ protected createTooltipElement(anchor: HTMLElement): import("element-vir").DeclarativeElementHost<"vira-tooltip", {
32
+ anchor: HTMLElement;
33
+ }, {}, {}, "vira-tooltip-", "vira-tooltip-", readonly [], readonly []>;
34
+ /** Renders nothing, this directive only attaches behavior to its element. */
35
+ render(content: HtmlInterpolation, options?: TooltipOptions): undefined;
36
+ protected disconnected(): void;
37
+ /** Re-opens a popover that `trigger` forces open. */
38
+ protected reconnected(): void;
39
+ }
40
+ /**
41
+ * Shows a {@link ViraTooltip} with the given contents while the element that this directive is
42
+ * attached to is hovered or focused, or as `options.trigger` describes. The tooltip is centered
43
+ * above the element when it fits, otherwise it is aligned to the element's left or right edge, and
44
+ * it flips below the element when there's no room above. The tooltip is inserted right after the
45
+ * element, so styles from the element's shadow root apply to template contents.
46
+ *
47
+ * @category Popover
48
+ * @category Directives
49
+ * @example
50
+ *
51
+ * ```ts
52
+ * import {html} from 'element-vir';
53
+ * import {tooltip} from 'vira';
54
+ *
55
+ * html`
56
+ * <button ${tooltip('Mark as resolved')}>Resolve</button>
57
+ * `;
58
+ * ```
59
+ */
60
+ export declare const tooltip: (content: HtmlInterpolation, options?: TooltipOptions | undefined) => import("element-vir").DirectiveResult<typeof TooltipDirective>;
@@ -0,0 +1,99 @@
1
+ import { assertWrap } from '@augment-vir/assert';
2
+ import { assertIsElementPartInfo, AsyncDirective, directive, } from 'element-vir';
3
+ import { render } from 'lit';
4
+ import { listenTo } from 'typed-event-target';
5
+ import { ViraTooltip } from '../elements/popover/vira-tooltip.element.js';
6
+ import { PopoverManager, PopoverTrigger } from '../util/popover-manager.js';
7
+ const directiveName = 'tooltip';
8
+ /**
9
+ * The directive class behind {@link tooltip}.
10
+ *
11
+ * @category Internal
12
+ */
13
+ export class TooltipDirective extends AsyncDirective {
14
+ content;
15
+ /** Only exists while the tooltip is shown. */
16
+ tooltipElement;
17
+ popoverManager = new PopoverManager();
18
+ constructor(partInfo) {
19
+ super(partInfo);
20
+ assertIsElementPartInfo(partInfo, directiveName);
21
+ }
22
+ /** Applies the latest directive arguments. */
23
+ update(partInfo, [content, options,]) {
24
+ assertIsElementPartInfo(partInfo, directiveName);
25
+ const anchor = assertWrap.instanceOf(partInfo.element, HTMLElement);
26
+ this.content = content;
27
+ if (this.tooltipElement) {
28
+ render(content, this.tooltipElement);
29
+ }
30
+ this.popoverManager.update(anchor, {
31
+ trigger: options?.trigger ?? PopoverTrigger.Hover,
32
+ delay: options?.delay,
33
+ timeout: options?.timeout,
34
+ getPopover: () => this.createTooltipElement(anchor),
35
+ });
36
+ return this.render(content, options);
37
+ }
38
+ /** Creates a new {@link ViraTooltip} after `anchor`, replacing any previous one. */
39
+ createTooltipElement(anchor) {
40
+ this.tooltipElement?.remove();
41
+ const tooltipElement = assertWrap.instanceOf(document.createElement(ViraTooltip.tagName), ViraTooltip);
42
+ this.tooltipElement = tooltipElement;
43
+ listenTo(tooltipElement, 'toggle', () => {
44
+ if (!tooltipElement.matches(':popover-open')) {
45
+ tooltipElement.remove();
46
+ if (this.tooltipElement === tooltipElement) {
47
+ this.tooltipElement = undefined;
48
+ }
49
+ }
50
+ });
51
+ this.tooltipElement.assignInputs({
52
+ anchor,
53
+ });
54
+ this.tooltipElement.popover = 'manual';
55
+ this.tooltipElement.role = 'tooltip';
56
+ /**
57
+ * Keeps the tooltip rendered when the anchor is slotted into a named slot, where an
58
+ * unassigned sibling would not be rendered at all.
59
+ */
60
+ this.tooltipElement.slot = anchor.slot;
61
+ /** Rendered into light DOM so that the anchor's shadow root styles the contents. */
62
+ render(this.content, this.tooltipElement);
63
+ anchor.after(this.tooltipElement);
64
+ return this.tooltipElement;
65
+ }
66
+ /** Renders nothing, this directive only attaches behavior to its element. */
67
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
68
+ render(content, options) {
69
+ return undefined;
70
+ }
71
+ disconnected() {
72
+ this.popoverManager.close();
73
+ }
74
+ /** Re-opens a popover that `trigger` forces open. */
75
+ reconnected() {
76
+ this.popoverManager.applyForcedState();
77
+ }
78
+ }
79
+ /**
80
+ * Shows a {@link ViraTooltip} with the given contents while the element that this directive is
81
+ * attached to is hovered or focused, or as `options.trigger` describes. The tooltip is centered
82
+ * above the element when it fits, otherwise it is aligned to the element's left or right edge, and
83
+ * it flips below the element when there's no room above. The tooltip is inserted right after the
84
+ * element, so styles from the element's shadow root apply to template contents.
85
+ *
86
+ * @category Popover
87
+ * @category Directives
88
+ * @example
89
+ *
90
+ * ```ts
91
+ * import {html} from 'element-vir';
92
+ * import {tooltip} from 'vira';
93
+ *
94
+ * html`
95
+ * <button ${tooltip('Mark as resolved')}>Resolve</button>
96
+ * `;
97
+ * ```
98
+ */
99
+ export const tooltip = directive(TooltipDirective);
@@ -1,7 +1,7 @@
1
1
  import { type PartialWithUndefined } from '@augment-vir/common';
2
2
  import { Color } from '@electrovir/color/dist/data/color-class/color.js';
3
3
  /**
4
- * A color picker element with a swatch that opens a popup with color format sliders.
4
+ * A color picker element with a swatch that opens a popover with color format sliders.
5
5
  *
6
6
  * Set the width and height of the swatch using the provided CSS variables.
7
7
  *
@@ -11,10 +11,10 @@ import { viraFormCssVars } from '../../styles/form-styles.js';
11
11
  import { noNativeFormStyles } from '../../styles/native-styles.js';
12
12
  import { viraShadows } from '../../styles/shadows.js';
13
13
  import { colorLocalStorageClient } from '../../util/color-local-storage.client.js';
14
- import { ViraPopUpTrigger } from '../pop-up/vira-pop-up-trigger.element.js';
14
+ import { ViraPopoverTrigger } from '../popover/vira-popover-trigger.element.js';
15
+ import { ViraDropdown } from '../vira-dropdown.element.js';
15
16
  import { ViraIcon } from '../vira-icon.element.js';
16
17
  import { ViraInput } from '../vira-input.element.js';
17
- import { ViraSelect } from '../vira-select.element.js';
18
18
  import { ViraColorFormatSliders } from './vira-color-format-sliders.element.js';
19
19
  import { ViraColorSwatch } from './vira-color-swatch.element.js';
20
20
  const colorFormatOptions = getObjectTypedValues(ColorFormatName).map((formatName) => {
@@ -24,7 +24,7 @@ const colorFormatOptions = getObjectTypedValues(ColorFormatName).map((formatName
24
24
  };
25
25
  });
26
26
  /**
27
- * A color picker element with a swatch that opens a popup with color format sliders.
27
+ * A color picker element with a swatch that opens a popover with color format sliders.
28
28
  *
29
29
  * Set the width and height of the swatch using the provided CSS variables.
30
30
  *
@@ -71,7 +71,7 @@ export const ViraColorPicker = defineElement()({
71
71
  display: flex;
72
72
  }
73
73
 
74
- ${ViraPopUpTrigger} {
74
+ ${ViraPopoverTrigger} {
75
75
  width: 100%;
76
76
  height: 100%;
77
77
  box-sizing: border-box;
@@ -123,7 +123,7 @@ export const ViraColorPicker = defineElement()({
123
123
  border-radius: 8px;
124
124
  }
125
125
 
126
- .pop-up .picker {
126
+ .popover .picker {
127
127
  ${viraShadows.menuShadow}
128
128
  }
129
129
 
@@ -210,12 +210,14 @@ export const ViraColorPicker = defineElement()({
210
210
  `;
211
211
  const pickerTemplate = html `
212
212
  <div class="picker">
213
- <${ViraSelect.assign({
213
+ <${ViraDropdown.assign({
214
214
  options: colorFormatOptions,
215
- value: state.selectedFormatName,
215
+ selected: [
216
+ state.selectedFormatName,
217
+ ],
216
218
  })}
217
- ${listen(ViraSelect.events.valueChange, (event) => {
218
- const selectedFormat = checkWrap.isEnumValue(event.detail, ColorFormatName);
219
+ ${listen(ViraDropdown.events.selectedValuesChange, (event) => {
220
+ const selectedFormat = checkWrap.isEnumValue(event.detail[0], ColorFormatName);
219
221
  if (selectedFormat) {
220
222
  updateState({
221
223
  selectedFormatName: selectedFormat,
@@ -223,7 +225,7 @@ export const ViraColorPicker = defineElement()({
223
225
  colorLocalStorageClient.set.lastFormat(selectedFormat);
224
226
  }
225
227
  })}
226
- ></${ViraSelect}>
228
+ ></${ViraDropdown}>
227
229
  ${rawInputTemplate}
228
230
  <${ViraColorFormatSliders.assign({
229
231
  color,
@@ -248,12 +250,12 @@ export const ViraColorPicker = defineElement()({
248
250
  }
249
251
  else {
250
252
  return html `
251
- <${ViraPopUpTrigger.assign({
253
+ <${ViraPopoverTrigger.assign({
252
254
  keepOpenAfterInteraction: true,
253
255
  })}>
254
256
  <button
255
257
  class="trigger"
256
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-trigger']}
258
+ slot=${ViraPopoverTrigger.slotNames['vira-popover-trigger-trigger']}
257
259
  ${listen('mousedown', () => {
258
260
  const storedFormat = colorLocalStorageClient.get.lastFormat();
259
261
  if (storedFormat) {
@@ -266,12 +268,12 @@ export const ViraColorPicker = defineElement()({
266
268
  ${swatchTemplate}
267
269
  </button>
268
270
  <div
269
- class="pop-up"
270
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-pop-up']}
271
+ class="popover"
272
+ slot=${ViraPopoverTrigger.slotNames['vira-popover-trigger-popover']}
271
273
  >
272
274
  ${pickerTemplate}
273
275
  </div>
274
- </${ViraPopUpTrigger}>
276
+ </${ViraPopoverTrigger}>
275
277
  `;
276
278
  }
277
279
  },
@@ -8,10 +8,11 @@ export * from './color/vira-color-picker.element.js';
8
8
  export * from './color/vira-color-slider.element.js';
9
9
  export * from './color/vira-color-swatch.element.js';
10
10
  export * from './color/vira-contrast-indicator.element.js';
11
- export * from './pop-up/vira-menu-item.element.js';
12
- export * from './pop-up/vira-menu-trigger.element.js';
13
- export * from './pop-up/vira-menu.element.js';
14
- export * from './pop-up/vira-pop-up-trigger.element.js';
11
+ export * from './popover/vira-menu-item.element.js';
12
+ export * from './popover/vira-menu-trigger.element.js';
13
+ export * from './popover/vira-menu.element.js';
14
+ export * from './popover/vira-popover-trigger.element.js';
15
+ export * from './popover/vira-tooltip.element.js';
15
16
  export * from './vira-absolute-time.element.js';
16
17
  export * from './vira-bold-text.element.js';
17
18
  export * from './vira-button.element.js';
@@ -32,7 +33,6 @@ export * from './vira-link.element.js';
32
33
  export * from './vira-modal.element.js';
33
34
  export * from './vira-progress.element.js';
34
35
  export * from './vira-relative-time.element.js';
35
- export * from './vira-select.element.js';
36
36
  export * from './vira-tabs.element.js';
37
37
  export * from './vira-tag.element.js';
38
38
  export * from './vira-text-area.element.js';
@@ -8,10 +8,11 @@ export * from './color/vira-color-picker.element.js';
8
8
  export * from './color/vira-color-slider.element.js';
9
9
  export * from './color/vira-color-swatch.element.js';
10
10
  export * from './color/vira-contrast-indicator.element.js';
11
- export * from './pop-up/vira-menu-item.element.js';
12
- export * from './pop-up/vira-menu-trigger.element.js';
13
- export * from './pop-up/vira-menu.element.js';
14
- export * from './pop-up/vira-pop-up-trigger.element.js';
11
+ export * from './popover/vira-menu-item.element.js';
12
+ export * from './popover/vira-menu-trigger.element.js';
13
+ export * from './popover/vira-menu.element.js';
14
+ export * from './popover/vira-popover-trigger.element.js';
15
+ export * from './popover/vira-tooltip.element.js';
15
16
  export * from './vira-absolute-time.element.js';
16
17
  export * from './vira-bold-text.element.js';
17
18
  export * from './vira-button.element.js';
@@ -32,7 +33,6 @@ export * from './vira-link.element.js';
32
33
  export * from './vira-modal.element.js';
33
34
  export * from './vira-progress.element.js';
34
35
  export * from './vira-relative-time.element.js';
35
- export * from './vira-select.element.js';
36
36
  export * from './vira-tabs.element.js';
37
37
  export * from './vira-tag.element.js';
38
38
  export * from './vira-text-area.element.js';
@@ -3,7 +3,7 @@ import { type ViraIconSvg } from '../../icons/icon-svg.js';
3
3
  /**
4
4
  * An element for an individual menu item.
5
5
  *
6
- * @category PopUp
6
+ * @category Popover
7
7
  * @category Elements
8
8
  */
9
9
  export declare const ViraMenuItem: import("element-vir").DeclarativeElementDefinition<"vira-menu-item", PartialWithUndefined<{
@@ -20,7 +20,7 @@ export declare const ViraMenuItem: import("element-vir").DeclarativeElementDefin
20
20
  */
21
21
  iconOverride: ViraIconSvg;
22
22
  /**
23
- * When `true`, activating this item will _not_ close the containing pop-up.
23
+ * When `true`, activating this item will _not_ close the containing popover.
24
24
  *
25
25
  * @default false
26
26
  */
@@ -30,8 +30,8 @@ export declare const ViraMenuItem: import("element-vir").DeclarativeElementDefin
30
30
  cleanupListeners: undefined | (() => void);
31
31
  }, {
32
32
  /**
33
- * Fired when this menu item is activated by the user (a non-disabled click). Pop-up
34
- * containers (e.g. `ViraPopUpTrigger`) listen to this to close the pop-up on selection,
33
+ * Fired when this menu item is activated by the user (a non-disabled click). Popover
34
+ * containers (e.g. `ViraPopoverTrigger`) listen to this to close the popover on selection,
35
35
  * gated by `keepOpenAfterInteraction`.
36
36
  */
37
37
  activate: import("element-vir").DefineElementEvent<undefined>;
@@ -11,7 +11,7 @@ const selectedCheckIcon = createSizedIcon(lucideIcons.Check, 16);
11
11
  /**
12
12
  * An element for an individual menu item.
13
13
  *
14
- * @category PopUp
14
+ * @category Popover
15
15
  * @category Elements
16
16
  */
17
17
  export const ViraMenuItem = defineViraElement()({
@@ -24,8 +24,8 @@ export const ViraMenuItem = defineViraElement()({
24
24
  },
25
25
  events: {
26
26
  /**
27
- * Fired when this menu item is activated by the user (a non-disabled click). Pop-up
28
- * containers (e.g. `ViraPopUpTrigger`) listen to this to close the pop-up on selection,
27
+ * Fired when this menu item is activated by the user (a non-disabled click). Popover
28
+ * containers (e.g. `ViraPopoverTrigger`) listen to this to close the popover on selection,
29
29
  * gated by `keepOpenAfterInteraction`.
30
30
  */
31
31
  activate: defineElementEvent(),
@@ -207,6 +207,15 @@ export const ViraMenuItem = defineViraElement()({
207
207
  }, {
208
208
  capture: true,
209
209
  }),
210
+ listenTo(host, 'keydown', (event) => {
211
+ if (event instanceof KeyboardEvent &&
212
+ event.target === host &&
213
+ (event.key === 'Enter' || event.key === ' ')) {
214
+ /** Prevents Space from scrolling the menu. */
215
+ event.preventDefault();
216
+ host.click();
217
+ }
218
+ }),
210
219
  listenTo(host, 'mouseenter', () => {
211
220
  if (!inputs.disabled) {
212
221
  host.focus();
@@ -0,0 +1,56 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
+ import { type NavController } from 'device-navigation';
3
+ import { type PopoverTrigger } from '../../util/popover-manager.js';
4
+ import { ViraMenuCornerStyle } from './vira-menu.element.js';
5
+ import { type PopoverOffset } from './vira-popover-trigger.element.js';
6
+ /**
7
+ * Test ids for {@link ViraMenuTrigger}.
8
+ *
9
+ * @category Internal
10
+ */
11
+ export declare const viraMenuTriggerTestIds: {
12
+ menu: string;
13
+ };
14
+ /**
15
+ * A more specific wrapper of `ViraPopoverTrigger` that always opens a menu.
16
+ *
17
+ * @category Popover
18
+ * @category Elements
19
+ */
20
+ export declare const ViraMenuTrigger: import("element-vir").DeclarativeElementDefinition<`vira-${string}`, PartialWithUndefined<{
21
+ isDisabled: boolean;
22
+ /**
23
+ * Defaults to {@link PopoverTrigger.Mousedown}. `true` or `false` force the popover open or
24
+ * closed.
25
+ */
26
+ trigger: boolean | PopoverTrigger;
27
+ popoverOffset: PopoverOffset;
28
+ keepOpenAfterInteraction: boolean;
29
+ /** @default ViraMenuCornerStyle.Round */
30
+ menuCornerStyle: ViraMenuCornerStyle;
31
+ /**
32
+ * Passed to {@link ViraMenu}'s `hoverScrollSpeed` input. How many menu items per second
33
+ * hovering a scroll arrow scrolls through.
34
+ *
35
+ * @default 24
36
+ */
37
+ menuHoverScrollSpeed: number;
38
+ /**
39
+ * If true, the focus outline is moved inside the element.
40
+ *
41
+ * @default false
42
+ */
43
+ useInsideFocus: boolean;
44
+ /**
45
+ * When `true`, the trigger will focus itself when the popover closes.
46
+ *
47
+ * @default false
48
+ */
49
+ focusOnClose: boolean;
50
+ }>, {
51
+ navController: undefined | NavController;
52
+ isOpen: boolean;
53
+ }, {
54
+ /** `true` when the popover just opened, `false` when it just closed. */
55
+ openChange: import("element-vir").DefineElementEvent<boolean>;
56
+ }, `vira-${string}-`, `vira-${string}-`, readonly ["vira-menu-trigger-trigger"], readonly []>;
@@ -1,7 +1,7 @@
1
1
  import { classMap, css, defineElementEvent, html, listen, nothing } from 'element-vir';
2
2
  import { defineViraElement } from '../../util/define-vira-element.js';
3
- import { ViraMenu, ViraMenuPopUpDirection } from './vira-menu.element.js';
4
- import { HorizontalAnchor, ViraPopUpTrigger, } from './vira-pop-up-trigger.element.js';
3
+ import { ViraMenu, ViraMenuCornerStyle } from './vira-menu.element.js';
4
+ import { ViraPopoverTrigger } from './vira-popover-trigger.element.js';
5
5
  /**
6
6
  * Test ids for {@link ViraMenuTrigger}.
7
7
  *
@@ -11,9 +11,9 @@ export const viraMenuTriggerTestIds = {
11
11
  menu: 'menu-trigger-menu',
12
12
  };
13
13
  /**
14
- * A more specific wrapper of `ViraPopUpTrigger` that always opens a menu.
14
+ * A more specific wrapper of `ViraPopoverTrigger` that always opens a menu.
15
15
  *
16
- * @category PopUp
16
+ * @category Popover
17
17
  * @category Elements
18
18
  */
19
19
  export const ViraMenuTrigger = defineViraElement()({
@@ -29,72 +29,61 @@ export const ViraMenuTrigger = defineViraElement()({
29
29
  max-width: 100%;
30
30
  }
31
31
 
32
- ${ViraPopUpTrigger} {
33
- width: 100%;
34
- }
35
-
36
- .full-width-menu {
32
+ ${ViraPopoverTrigger} {
37
33
  width: 100%;
38
34
  }
39
35
  `,
40
36
  events: {
37
+ /** `true` when the popover just opened, `false` when it just closed. */
41
38
  openChange: defineElementEvent(),
42
39
  },
43
40
  state() {
44
41
  return {
45
42
  navController: undefined,
46
- popUpManager: undefined,
47
- /** `undefined` means the pop up is not currently showing. */
48
- showPopUpResult: undefined,
43
+ isOpen: false,
49
44
  };
50
45
  },
51
46
  render({ inputs, state, updateState, dispatch, events, slotNames }) {
52
47
  return html `
53
- <${ViraPopUpTrigger.assign({
48
+ <${ViraPopoverTrigger.assign({
54
49
  ...inputs,
55
50
  })}
56
51
  class=${classMap({
57
- open: !!state.showPopUpResult,
52
+ open: state.isOpen,
58
53
  })}
59
- ${listen(ViraPopUpTrigger.events.init, (event) => {
54
+ ${listen(ViraPopoverTrigger.events.init, (event) => {
60
55
  updateState({
61
56
  navController: event.detail.navController,
62
- popUpManager: event.detail.popUpManager,
63
57
  });
64
58
  })}
65
- ${listen(ViraPopUpTrigger.events.openChange, (event) => {
66
- if (!!state.showPopUpResult !== !!event.detail) {
59
+ ${listen(ViraPopoverTrigger.events.openChange, (event) => {
60
+ if (state.isOpen !== event.detail) {
67
61
  dispatch(new events.openChange({
68
62
  detail: event.detail,
69
63
  }));
70
64
  }
71
65
  updateState({
72
- showPopUpResult: event.detail,
66
+ isOpen: event.detail,
73
67
  });
74
68
  })}
75
69
  >
76
70
  <slot
77
71
  name=${slotNames['vira-menu-trigger-trigger']}
78
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-trigger']}
72
+ slot=${ViraPopoverTrigger.slotNames['vira-popover-trigger-trigger']}
79
73
  ></slot>
80
- ${state.navController && state.showPopUpResult
74
+ ${state.navController && state.isOpen
81
75
  ? html `
82
76
  <${ViraMenu.assign({
83
- direction: state.showPopUpResult.popDown
84
- ? ViraMenuPopUpDirection.Downwards
85
- : ViraMenuPopUpDirection.Upwards,
86
- cornerStyle: inputs.menuCornerStyle,
87
- })}
88
- slot=${ViraPopUpTrigger.slotNames['vira-pop-up-trigger-pop-up']}
89
- class=${classMap({
90
- 'full-width-menu': inputs.horizontalAnchor === HorizontalAnchor.Both,
77
+ cornerStyle: inputs.menuCornerStyle || ViraMenuCornerStyle.Round,
78
+ hoverScrollSpeed: inputs.menuHoverScrollSpeed,
91
79
  })}
80
+ slot=${ViraPopoverTrigger.slotNames['vira-popover-trigger-popover']}
92
81
  >
93
82
  <slot></slot>
94
83
  </${ViraMenu}>
95
84
  `
96
85
  : nothing}
97
- </${ViraPopUpTrigger}>
86
+ </${ViraPopoverTrigger}>
98
87
  `;
99
88
  },
100
89
  });