@primer/view-components 0.0.92 → 0.0.93
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.
- package/README.md +2 -2
- package/app/assets/javascripts/primer_view_components.js +1 -1
- package/app/assets/javascripts/primer_view_components.js.map +1 -1
- package/app/assets/styles/primer_view_components.css +1 -0
- package/app/assets/styles/primer_view_components.css.map +1 -1
- package/app/components/primer/alpha/modal-dialog-element.d.ts +1 -1
- package/app/components/primer/alpha/modal-dialog-element.js +2 -3
- package/app/components/primer/alpha/toggle-switch-element.js +2 -0
- package/app/components/primer/experimental/action-bar-element.d.ts +14 -0
- package/app/components/primer/experimental/action-bar-element.js +139 -0
- package/app/components/primer/experimental/action-menu-element.d.ts +31 -0
- package/app/components/primer/experimental/action-menu-element.js +334 -0
- package/app/components/primer/experimental/overflow-menu-element.d.ts +13 -0
- package/app/components/primer/experimental/overflow-menu-element.js +113 -0
- package/app/components/primer/primer.d.ts +1 -0
- package/app/components/primer/primer.js +1 -0
- package/package.json +5 -2
- package/app/components/primer/alpha/segmented-control-element.d.ts +0 -8
- package/app/components/primer/alpha/segmented-control-element.js +0 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--primer-duration-fast:80ms;--primer-easing-easeInOut:cubic-bezier(0.65,0,0.35,1)}.Button{align-items:center;background-color:transparent;border:1px solid;border:var(--primer-borderWidth-thin,1px) solid;border-color:transparent;border-radius:6px;border-radius:var(--primer-borderRadius-medium,6px);color:var(--color-btn-text);cursor:pointer;display:flex;flex-direction:row;font-size:14px;font-size:var(--primer-text-body-size-medium,14px);font-weight:500;font-weight:var(--base-text-weight-medium,500);gap:8px;gap:var(--primer-control-medium-gap,8px);height:32px;height:var(--primer-control-medium-size,32px);justify-content:space-between;padding:0 12px;padding:0 var(--primer-control-medium-paddingInline-normal,12px);position:relative;text-align:center;transition:80ms cubic-bezier(.65,0,.35,1);transition:var(--primer-duration-fast) var(--primer-easing-easeInOut);transition-property:color,fill,background-color,border-color;-webkit-user-select:none;-moz-user-select:none;user-select:none}@media (pointer:course){.Button:before{content:"";height:100%;left:50%;min-height:48px;min-width:48px;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}}.Button:hover{transition-duration:80ms;transition-duration:var(--primer-duration-fast)}.Button.Button--active,.Button:active{transition:none}.Button.Button--disabled,.Button:disabled,.Button[aria-disabled=true]{box-shadow:none;cursor:not-allowed}.Button-withTooltip{display:inline-block;position:relative}a.Button,summary.Button{display:inline-flex}a.Button:hover,summary.Button:hover{text-decoration:none}.Button-content{align-items:center;display:grid;flex:1 0 auto;grid-template-areas:"leadingVisual text trailingVisual";grid-template-columns:-webkit-min-content minmax(0,auto) -webkit-min-content;grid-template-columns:min-content minmax(0,auto) min-content;place-content:center}.Button-content>:not(:last-child){margin-right:8px;margin-right:var(--primer-control-medium-gap,8px)}.Button-content--alignStart{justify-content:start}.Button-visual{display:flex;pointer-events:none}.Button-label{grid-area:text;line-height:1.42857;line-height:var(--primer-text-body-lineHeight-medium,1.42857);white-space:nowrap}.Button-leadingVisual{grid-area:leadingVisual}.Button-trailingVisual{grid-area:trailingVisual}.Button-trailingAction{margin-right:-4px;margin-right:calc(var(--base-size-4, 4px)*-1)}.Button--small{font-size:12px;font-size:var(--primer-text-body-size-small,12px);gap:4px;gap:var(--primer-control-small-gap,4px);height:28px;height:var(--primer-control-small-size,28px);padding:0 12px;padding:0 var(--primer-control-small-paddingInline-normal,12px);.Button-label{line-height:1.66667;line-height:var(--primer-text-body-lineHeight-small,1.66667)}.Button-content>:not(:last-child){margin-right:4px;margin-right:var(--primer-control-small-gap,4px)}}.Button--large{gap:8px;gap:var(--primer-control-large-gap,8px);height:40px;height:var(--primer-control-large-size,40px);padding:0 12px;padding:0 var(--primer-control-large-paddingInline-normal,12px);.Button-label{line-height:1.5;line-height:var(--primer-text-body-lineHeight-large,1.5)}.Button-content>:not(:last-child){margin-right:8px;margin-right:var(--primer-control-large-gap,8px)}}.Button--fullWidth{width:100%}.Button--primary{fill:var(--color-btn-primary-icon);background-color:var(--color-btn-primary-bg);border-color:var(--color-btn-primary-border);box-shadow:var(--color-btn-primary-shadow),var(--color-btn-primary-inset-shadow);color:var(--color-btn-primary-text)}.Button--primary:hover{background-color:var(--color-btn-primary-hover-bg);border-color:var(--color-btn-primary-hover-border)}.Button--primary:focus{box-shadow:inset 0 0 0 3px var(--color-fg-on-emphasis);outline:2px solid var(--color-accent-fg);outline-offset:-2px}.Button--primary:focus:not(:focus-visible){box-shadow:none;outline:1px solid transparent}.Button--primary:focus-visible{box-shadow:inset 0 0 0 3px var(--color-fg-on-emphasis);outline:2px solid var(--color-accent-fg);outline-offset:-2px}.Button--primary.Button--pressed,.Button--primary:active,.Button--primary[aria-pressed=true]{background-color:var(--color-btn-primary-selected-bg);box-shadow:var(--color-btn-primary-selected-shadow)}.Button--primary.Button--disabled,.Button--primary:disabled,.Button--primary[aria-disabled=true]{fill:var(--color-btn-primary-disabled-text);background-color:var(--color-btn-primary-disabled-bg);border-color:var(--color-btn-primary-disabled-border);color:var(--color-btn-primary-disabled-text)}.Button--secondary{fill:var(--color-fg-muted);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);box-shadow:var(--color-btn-shadow),var(--color-btn-inset-shadow);color:var(--color-btn-text)}.Button--secondary:hover{background-color:var(--color-btn-hover-bg);border-color:var(--color-btn-hover-border)}.Button--secondary.Button--active,.Button--secondary:active{background-color:var(--color-btn-active-bg);border-color:var(--color-btn-active-border)}.Button--secondary.Button--pressed,.Button--secondary[aria-pressed=true]{background-color:var(--color-btn-selected-bg);box-shadow:var(--color-primer-shadow-inset)}.Button--secondary.Button--disabled,.Button--secondary:disabled,.Button--secondary[aria-disabled=true]{fill:var(--color-primer-fg-disabled);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);color:var(--color-primer-fg-disabled)}.Button--invisible{fill:var(--color-fg-default);border:none;color:var(--color-fg-default)}.Button--invisible:hover{background-color:var(--color-action-list-item-default-hover-bg)}.Button--invisible.Button--active,.Button--invisible.Button--pressed,.Button--invisible:active,.Button--invisible[aria-pressed=true]{background-color:var(--color-action-list-item-default-active-bg)}.Button--invisible.Button--disabled,.Button--invisible:disabled,.Button--invisible[aria-disabled=true]{fill:var(--color-primer-fg-disabled);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);color:var(--color-primer-fg-disabled)}.Button--invisible{.Button-label:not(:only-child){color:var(--color-btn-text)}.Button-content:not(:only-child){.Button-label{color:var(--color-btn-text)}}}.Button--danger{fill:var(--color-btn-danger-icon);background-color:var(--color-btn-bg);border-color:var(--color-btn-border);box-shadow:var(--color-btn-shadow),var(--color-btn-inset-shadow);color:var(--color-btn-danger-text)}.Button--danger:hover{fill:var(--color-btn-danger-hover-text);background-color:var(--color-btn-danger-hover-bg);border-color:var(--color-btn-danger-hover-border);box-shadow:var(--color-btn-danger-hover-shadow),var(--color-btn-danger-hover-inset-shadow);color:var(--color-btn-danger-hover-text)}.Button--danger.Button--pressed,.Button--danger:active,.Button--danger[aria-pressed=true]{fill:var(--color-btn-danger-selected-text);background-color:var(--color-btn-danger-selected-bg);border-color:var(--color-btn-danger-selected-border);box-shadow:var(--color-btn-danger-selected-shadow);color:var(--color-btn-danger-selected-text)}.Button--danger.disabled,.Button--danger:disabled,.Button--danger[aria-disabled=true]{fill:var(--color-btn-danger-disabled-text);background-color:var(--color-btn-danger-disabled-bg);border-color:var(--color-btn-border);color:var(--color-btn-danger-disabled-text)}.Button--iconOnly{display:grid;padding:initial;place-content:center;width:32px;width:var(--primer-control-medium-size,32px)}.Button--iconOnly.Button--small{width:28px;width:var(--primer-control-small-size,28px)}.Button--iconOnly.Button--large{width:40px;width:var(--primer-control-large-size,40px)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"primer_view_components.css"}
|
|
1
|
+
{"version":3,"sources":["../../components/primer/beta/button.pcss","<no source>","../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"primer_view_components.css","sourcesContent":["/* CSS for Button */\n/* temporary, pre primitives release */\n:root {\n --primer-duration-fast: 80ms;\n --primer-easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n font-size: var(--primer-text-body-size-medium, 14px);\n font-weight: var(--base-text-weight-medium, 500);\n cursor: pointer;\n user-select: none;\n background-color: transparent;\n border: var(--primer-borderWidth-thin, 1px) solid;\n border-color: transparent;\n border-radius: var(--primer-borderRadius-medium, 6px);\n color: var(--color-btn-text);\n transition: var(--primer-duration-fast) var(--primer-easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n text-align: center;\n height: var(--primer-control-medium-size, 32px);\n padding: 0 var(--primer-control-medium-paddingInline-normal, 12px);\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--primer-control-medium-gap, 8px);\n\n /* mobile friendly sizing */\n @media (pointer: course) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--primer-duration-fast);\n }\n\n &:active,\n &.Button--active {\n transition: none;\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n\n /* &:focus {\n @mixin focusOutline;\n } */\n}\n\n.Button-withTooltip {\n position: relative;\n display: inline-block;\n}\n\na.Button,\nsummary.Button {\n display: inline-flex;\n\n &:hover {\n text-decoration: none;\n }\n}\n\n/* wrap grid content to allow trailingAction to lock-right */\n.Button-content {\n flex: 1 0 auto;\n display: grid;\n grid-template-areas: 'leadingVisual text trailingVisual';\n grid-template-columns: min-content minmax(0, auto) min-content;\n align-items: center;\n place-content: center;\n /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--primer-control-medium-gap, 8px);\n }\n}\n\n/* center child elements for fullWidth */\n.Button-content--alignStart {\n justify-content: start;\n}\n\n/* button child elements */\n\n/* align svg */\n.Button-visual {\n display: flex;\n pointer-events: none; /* allow click handler to work, avoiding visuals */\n}\n\n.Button-label {\n grid-area: text;\n white-space: nowrap;\n line-height: var(--primer-text-body-lineHeight-medium, calc(20/14));\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4, 4px) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n font-size: var(--primer-text-body-size-small, 12px);\n height: var(--primer-control-small-size, 28px);\n padding: 0 var(--primer-control-small-paddingInline-normal, 12px);\n gap: var(--primer-control-small-gap, 4px);\n\n .Button-label {\n line-height: var(--primer-text-body-lineHeight-small, calc(20/12));\n }\n\n .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-small-gap, 4px);\n }\n }\n}\n\n.Button--large {\n height: var(--primer-control-large-size, 40px);\n padding: 0 var(--primer-control-large-paddingInline-normal, 12px);\n gap: var(--primer-control-large-gap, 8px);\n\n .Button-label {\n line-height: var(--primer-text-body-lineHeight-large, calc(48/32));\n }\n\n .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-large-gap, 8px);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--color-btn-primary-text);\n fill: var(--color-btn-primary-icon);\n background-color: var(--color-btn-primary-bg);\n border-color: var(--color-btn-primary-border);\n box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow);\n\n &:hover {\n background-color: var(--color-btn-primary-hover-bg);\n border-color: var(--color-btn-primary-hover-border);\n }\n\n /* fallback :focus state */\n &:focus {\n @mixin focusOutlineOnEmphasis;\n\n /* remove fallback :focus if :focus-visible is supported */\n &:not(:focus-visible) {\n outline: solid 1px transparent;\n box-shadow: none;\n }\n }\n\n /* default focus state */\n &:focus-visible {\n @mixin focusOutlineOnEmphasis;\n }\n\n &:active,\n &[aria-pressed='true'],\n &.Button--pressed {\n background-color: var(--color-btn-primary-selected-bg);\n box-shadow: var(--color-btn-primary-selected-shadow);\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-primary-disabled-text);\n background-color: var(--color-btn-primary-disabled-bg);\n border-color: var(--color-btn-primary-disabled-border);\n fill: var(--color-btn-primary-disabled-text);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--color-btn-text);\n fill: var(--color-fg-muted); /* help this */\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover {\n background-color: var(--color-btn-hover-bg);\n border-color: var(--color-btn-hover-border);\n }\n\n &:active,\n &.Button--active {\n background-color: var(--color-btn-active-bg);\n border-color: var(--color-btn-active-border);\n }\n\n &[aria-pressed='true'],\n &.Button--pressed {\n background-color: var(--color-btn-selected-bg);\n box-shadow: var(--color-primer-shadow-inset);\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n/* link color without svg */\n.Button--invisible {\n color: var(--color-fg-default);\n fill: var(--color-fg-default);\n border: none;\n\n &:hover {\n background-color: var(--color-action-list-item-default-hover-bg);\n }\n\n &[aria-pressed='true'],\n &:active,\n &.Button--active,\n &.Button--pressed {\n background-color: var(--color-action-list-item-default-active-bg);\n /* box-shadow: var(--color-primer-shadow-inset); */\n }\n\n &:disabled,\n &.Button--disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n\n /* if visual is present, muted label color */\n .Button-label:not(:only-child) {\n color: var(--color-btn-text);\n }\n\n /* if trailingAction is present, muted label color */\n .Button-content:not(:only-child) {\n .Button-label {\n color: var(--color-btn-text);\n }\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--color-btn-danger-text);\n fill: var(--color-btn-danger-icon);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover {\n color: var(--color-btn-danger-hover-text);\n fill: var(--color-btn-danger-hover-text);\n background-color: var(--color-btn-danger-hover-bg);\n border-color: var(--color-btn-danger-hover-border);\n box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow);\n }\n\n &:active,\n &[aria-pressed='true'],\n &.Button--pressed {\n color: var(--color-btn-danger-selected-text);\n fill: var(--color-btn-danger-selected-text);\n background-color: var(--color-btn-danger-selected-bg);\n border-color: var(--color-btn-danger-selected-border);\n box-shadow: var(--color-btn-danger-selected-shadow);\n }\n\n &:disabled,\n &.disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-danger-disabled-text);\n fill: var(--color-btn-danger-disabled-text);\n background-color: var(--color-btn-danger-disabled-bg);\n border-color: var(--color-btn-border);\n }\n}\n\n.Button--iconOnly {\n display: grid;\n place-content: center;\n padding: unset;\n width: var(--primer-control-medium-size, 32px);\n\n &.Button--small {\n width: var(--primer-control-small-size, 28px);\n }\n\n &.Button--large {\n width: var(--primer-control-large-size, 40px);\n }\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--color-accent-fg) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);\n}\n"]}
|
|
@@ -92,7 +92,6 @@ export class ModalDialogElement extends HTMLElement {
|
|
|
92
92
|
}
|
|
93
93
|
dialogId = button.getAttribute('data-show-dialog-id');
|
|
94
94
|
if (dialogId === this.id) {
|
|
95
|
-
//TODO: see if I can remove this
|
|
96
95
|
event.stopPropagation();
|
|
97
96
|
__classPrivateFieldSet(this, _ModalDialogElement_openButton, button, "f");
|
|
98
97
|
this.show();
|
|
@@ -107,10 +106,10 @@ export class ModalDialogElement extends HTMLElement {
|
|
|
107
106
|
show() {
|
|
108
107
|
this.open = true;
|
|
109
108
|
}
|
|
110
|
-
close(
|
|
109
|
+
close(closedNotCancelled = false) {
|
|
111
110
|
if (this.open === false)
|
|
112
111
|
return;
|
|
113
|
-
const eventType =
|
|
112
|
+
const eventType = closedNotCancelled ? 'close' : 'cancel';
|
|
114
113
|
const dialogEvent = new Event(eventType);
|
|
115
114
|
this.dispatchEvent(dialogEvent);
|
|
116
115
|
this.open = false;
|
|
@@ -99,6 +99,8 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
|
|
|
99
99
|
}
|
|
100
100
|
body.append('value', this.isOn() ? '1' : '0');
|
|
101
101
|
try {
|
|
102
|
+
if (!this.src)
|
|
103
|
+
throw new Error('invalid src');
|
|
102
104
|
const response = await fetch(this.src, {
|
|
103
105
|
credentials: 'same-origin',
|
|
104
106
|
method: 'POST',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ActionMenuElement } from './action-menu-element';
|
|
2
|
+
export declare class ActionBarElement extends HTMLElement {
|
|
3
|
+
#private;
|
|
4
|
+
items: HTMLElement[];
|
|
5
|
+
menuItems: HTMLElement[];
|
|
6
|
+
moreMenu: ActionMenuElement;
|
|
7
|
+
connectedCallback(): void;
|
|
8
|
+
disconnectedCallback(): void;
|
|
9
|
+
}
|
|
10
|
+
declare global {
|
|
11
|
+
interface Window {
|
|
12
|
+
ActionBarElement: typeof ActionBarElement;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
|
2
|
+
/* eslint-disable custom-elements/define-tag-after-class-definition */
|
|
3
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
+
};
|
|
9
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
10
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
11
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
12
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
13
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
14
|
+
};
|
|
15
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
16
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
17
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
18
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
19
|
+
};
|
|
20
|
+
var _ActionBarElement_instances, _ActionBarElement_observer, _ActionBarElement_initialBarWidth, _ActionBarElement_itemGap, _ActionBarElement_focusController, _ActionBarElement_focusSettings, _ActionBarElement_availableSpace, _ActionBarElement_calculateVisibleItems, _ActionBarElement_nextItemWidth, _ActionBarElement_hideItem, _ActionBarElement_showItem, _ActionBarElement_hiddenItems, _ActionBarElement_visibleItems, _ActionBarElement_hiddenMenuItems, _ActionBarElement_visibleMenuItems;
|
|
21
|
+
import { controller, targets, target } from '@github/catalyst';
|
|
22
|
+
import { positionedOffset, focusZone, FocusKeys } from '@primer/behaviors';
|
|
23
|
+
let ActionBarElement = class ActionBarElement extends HTMLElement {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
_ActionBarElement_instances.add(this);
|
|
27
|
+
_ActionBarElement_observer.set(this, void 0);
|
|
28
|
+
_ActionBarElement_initialBarWidth.set(this, void 0);
|
|
29
|
+
_ActionBarElement_itemGap.set(this, void 0);
|
|
30
|
+
_ActionBarElement_focusController.set(this, void 0);
|
|
31
|
+
_ActionBarElement_focusSettings.set(this, {
|
|
32
|
+
bindKeys: FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
connectedCallback() {
|
|
36
|
+
var _a, _b, _c;
|
|
37
|
+
__classPrivateFieldSet(this, _ActionBarElement_initialBarWidth, this.offsetWidth, "f");
|
|
38
|
+
__classPrivateFieldSet(this, _ActionBarElement_itemGap, parseInt((_a = window.getComputedStyle(this)) === null || _a === void 0 ? void 0 : _a.columnGap, 10) || 0, "f");
|
|
39
|
+
// Calculate the width of all the items before hiding anything
|
|
40
|
+
for (const item of this.items) {
|
|
41
|
+
const width = item.getBoundingClientRect().width;
|
|
42
|
+
const marginLeft = parseInt((_b = window.getComputedStyle(item)) === null || _b === void 0 ? void 0 : _b.marginLeft, 10);
|
|
43
|
+
const marginRight = parseInt((_c = window.getComputedStyle(item)) === null || _c === void 0 ? void 0 : _c.marginRight, 10);
|
|
44
|
+
item.setAttribute('data-offset-width', `${width + marginLeft + marginRight}`);
|
|
45
|
+
}
|
|
46
|
+
__classPrivateFieldSet(this, _ActionBarElement_focusController, focusZone(this, __classPrivateFieldGet(this, _ActionBarElement_focusSettings, "f")), "f");
|
|
47
|
+
// Calculate visible items on page load until there is enough space
|
|
48
|
+
// to show all items or the first item is hidden
|
|
49
|
+
while (__classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_availableSpace).call(this) < 0 && !this.items[0].hidden) {
|
|
50
|
+
__classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_calculateVisibleItems).call(this);
|
|
51
|
+
}
|
|
52
|
+
__classPrivateFieldSet(this, _ActionBarElement_observer, new ResizeObserver(entries => {
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
// Only recalculate if the bar width changed
|
|
55
|
+
if (__classPrivateFieldGet(this, _ActionBarElement_initialBarWidth, "f") !== entry.contentRect.width) {
|
|
56
|
+
__classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_calculateVisibleItems).call(this);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}), "f");
|
|
60
|
+
__classPrivateFieldGet(this, _ActionBarElement_observer, "f").observe(this);
|
|
61
|
+
}
|
|
62
|
+
disconnectedCallback() {
|
|
63
|
+
var _a;
|
|
64
|
+
(_a = __classPrivateFieldGet(this, _ActionBarElement_focusController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
65
|
+
__classPrivateFieldGet(this, _ActionBarElement_observer, "f").unobserve(this);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
_ActionBarElement_observer = new WeakMap(), _ActionBarElement_initialBarWidth = new WeakMap(), _ActionBarElement_itemGap = new WeakMap(), _ActionBarElement_focusController = new WeakMap(), _ActionBarElement_focusSettings = new WeakMap(), _ActionBarElement_instances = new WeakSet(), _ActionBarElement_availableSpace = function _ActionBarElement_availableSpace() {
|
|
69
|
+
// Get the offset of the first item from the container edge
|
|
70
|
+
const offset = positionedOffset(this.items[0], this);
|
|
71
|
+
if (!offset) {
|
|
72
|
+
return this.clientWidth - this.moreMenu.clientWidth;
|
|
73
|
+
}
|
|
74
|
+
return offset.left;
|
|
75
|
+
}, _ActionBarElement_calculateVisibleItems = function _ActionBarElement_calculateVisibleItems() {
|
|
76
|
+
const space = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_availableSpace).call(this);
|
|
77
|
+
if (space < 0) {
|
|
78
|
+
__classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_hideItem).call(this);
|
|
79
|
+
}
|
|
80
|
+
else if (space > __classPrivateFieldGet(this, _ActionBarElement_itemGap, "f") + __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_nextItemWidth).call(this)) {
|
|
81
|
+
__classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_showItem).call(this);
|
|
82
|
+
}
|
|
83
|
+
}, _ActionBarElement_nextItemWidth = function _ActionBarElement_nextItemWidth() {
|
|
84
|
+
const nextItem = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_hiddenItems).call(this)[0] || this.items[0];
|
|
85
|
+
return Number(nextItem.getAttribute('data-offset-width') || '0');
|
|
86
|
+
}, _ActionBarElement_hideItem = function _ActionBarElement_hideItem() {
|
|
87
|
+
var _a;
|
|
88
|
+
const visibleItems = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_visibleItems).call(this);
|
|
89
|
+
const hiddenMenuItems = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_hiddenMenuItems).call(this);
|
|
90
|
+
if (visibleItems.length === 0) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
visibleItems[visibleItems.length - 1].hidden = true;
|
|
94
|
+
hiddenMenuItems[hiddenMenuItems.length - 1].hidden = false;
|
|
95
|
+
if (this.moreMenu.hidden) {
|
|
96
|
+
this.moreMenu.hidden = false;
|
|
97
|
+
}
|
|
98
|
+
// Reset focus controller
|
|
99
|
+
(_a = __classPrivateFieldGet(this, _ActionBarElement_focusController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
100
|
+
__classPrivateFieldSet(this, _ActionBarElement_focusController, focusZone(this, __classPrivateFieldGet(this, _ActionBarElement_focusSettings, "f")), "f");
|
|
101
|
+
}, _ActionBarElement_showItem = function _ActionBarElement_showItem() {
|
|
102
|
+
var _a;
|
|
103
|
+
const hiddenItems = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_hiddenItems).call(this);
|
|
104
|
+
const visibleMenuItems = __classPrivateFieldGet(this, _ActionBarElement_instances, "m", _ActionBarElement_visibleMenuItems).call(this);
|
|
105
|
+
if (hiddenItems.length === 0) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
hiddenItems[0].hidden = false;
|
|
109
|
+
visibleMenuItems[0].hidden = true;
|
|
110
|
+
// If there was only one item left, hide the more menu
|
|
111
|
+
if (hiddenItems.length === 1) {
|
|
112
|
+
this.moreMenu.hidden = true;
|
|
113
|
+
this.moreMenu.open = false;
|
|
114
|
+
}
|
|
115
|
+
// Reset focus controller
|
|
116
|
+
(_a = __classPrivateFieldGet(this, _ActionBarElement_focusController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
117
|
+
__classPrivateFieldSet(this, _ActionBarElement_focusController, focusZone(this, __classPrivateFieldGet(this, _ActionBarElement_focusSettings, "f")), "f");
|
|
118
|
+
}, _ActionBarElement_hiddenItems = function _ActionBarElement_hiddenItems() {
|
|
119
|
+
return this.items.filter(item => item.hidden);
|
|
120
|
+
}, _ActionBarElement_visibleItems = function _ActionBarElement_visibleItems() {
|
|
121
|
+
return this.items.filter(item => !item.hidden);
|
|
122
|
+
}, _ActionBarElement_hiddenMenuItems = function _ActionBarElement_hiddenMenuItems() {
|
|
123
|
+
return this.menuItems.filter(item => item.hidden);
|
|
124
|
+
}, _ActionBarElement_visibleMenuItems = function _ActionBarElement_visibleMenuItems() {
|
|
125
|
+
return this.menuItems.filter(item => !item.hidden);
|
|
126
|
+
};
|
|
127
|
+
__decorate([
|
|
128
|
+
targets
|
|
129
|
+
], ActionBarElement.prototype, "items", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
targets
|
|
132
|
+
], ActionBarElement.prototype, "menuItems", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
target
|
|
135
|
+
], ActionBarElement.prototype, "moreMenu", void 0);
|
|
136
|
+
ActionBarElement = __decorate([
|
|
137
|
+
controller
|
|
138
|
+
], ActionBarElement);
|
|
139
|
+
export { ActionBarElement };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AnchorAlignment, AnchorSide } from '@primer/behaviors';
|
|
2
|
+
export declare class ActionMenuElement extends HTMLElement {
|
|
3
|
+
#private;
|
|
4
|
+
get anchorAlign(): AnchorAlignment;
|
|
5
|
+
get anchorSide(): AnchorSide;
|
|
6
|
+
get menu(): HTMLUListElement | null;
|
|
7
|
+
get trigger(): HTMLButtonElement | null;
|
|
8
|
+
get overlay(): HTMLDivElement | null;
|
|
9
|
+
get menuItems(): HTMLElement[] | null;
|
|
10
|
+
get open(): boolean;
|
|
11
|
+
set open(value: boolean);
|
|
12
|
+
connectedCallback(): void;
|
|
13
|
+
disconnectedCallback(): void;
|
|
14
|
+
show(): void;
|
|
15
|
+
hide(): void;
|
|
16
|
+
setFocusToMenuItem(newMenuItem: HTMLElement): void;
|
|
17
|
+
setFocusToPreviousMenuItem(currentMenuItem: HTMLElement): HTMLElement | undefined;
|
|
18
|
+
setFocusToNextMenuItem(currentMenuItem: HTMLElement): HTMLElement | undefined;
|
|
19
|
+
setFocusByFirstCharacter(currentMenuItem: HTMLElement, character: string): void;
|
|
20
|
+
buttonKeydown(event: KeyboardEvent): void;
|
|
21
|
+
buttonClick(event: MouseEvent): void;
|
|
22
|
+
menuItemKeydown(event: KeyboardEvent): void;
|
|
23
|
+
menuItemClick(): void;
|
|
24
|
+
menuItemMouseover(event: MouseEvent): void;
|
|
25
|
+
backgroundMousedown(event: MouseEvent): void;
|
|
26
|
+
}
|
|
27
|
+
declare global {
|
|
28
|
+
interface Window {
|
|
29
|
+
ActionMenuElement: typeof ActionMenuElement;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_firstCharactersOfItems, _ActionMenuElement_firstMenuItem, _ActionMenuElement_lastMenuItem, _ActionMenuElement_addEvents, _ActionMenuElement_updatePosition;
|
|
13
|
+
import { getAnchoredPosition } from '@primer/behaviors';
|
|
14
|
+
export class ActionMenuElement extends HTMLElement {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
_ActionMenuElement_instances.add(this);
|
|
18
|
+
_ActionMenuElement_abortController.set(this, void 0);
|
|
19
|
+
_ActionMenuElement_firstCharactersOfItems.set(this, void 0);
|
|
20
|
+
_ActionMenuElement_firstMenuItem.set(this, void 0);
|
|
21
|
+
_ActionMenuElement_lastMenuItem.set(this, void 0);
|
|
22
|
+
}
|
|
23
|
+
get anchorAlign() {
|
|
24
|
+
return (this.getAttribute('data-anchor-align') || 'start');
|
|
25
|
+
}
|
|
26
|
+
get anchorSide() {
|
|
27
|
+
return (this.getAttribute('data-anchor-side') || 'outside-bottom');
|
|
28
|
+
}
|
|
29
|
+
get menu() {
|
|
30
|
+
return this.querySelector('[role="menu"]');
|
|
31
|
+
}
|
|
32
|
+
get trigger() {
|
|
33
|
+
return this.querySelector('button');
|
|
34
|
+
}
|
|
35
|
+
get overlay() {
|
|
36
|
+
return this.querySelector('.Overlay');
|
|
37
|
+
}
|
|
38
|
+
get menuItems() {
|
|
39
|
+
if (!this.menu)
|
|
40
|
+
return null;
|
|
41
|
+
return Array.from(this.menu.querySelectorAll('[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'));
|
|
42
|
+
}
|
|
43
|
+
get open() {
|
|
44
|
+
return this.hasAttribute('open');
|
|
45
|
+
}
|
|
46
|
+
set open(value) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
const initialBodyWidth = document.body.clientWidth;
|
|
49
|
+
const observer = new ResizeObserver(entries => {
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
if (initialBodyWidth !== entry.contentRect.width && this.open) {
|
|
52
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updatePosition).call(this);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
if (value) {
|
|
57
|
+
if (this.open)
|
|
58
|
+
return;
|
|
59
|
+
if (!this.trigger || !this.menu)
|
|
60
|
+
return;
|
|
61
|
+
this.setAttribute('open', '');
|
|
62
|
+
this.trigger.setAttribute('aria-expanded', 'true');
|
|
63
|
+
(_a = this.overlay) === null || _a === void 0 ? void 0 : _a.removeAttribute('hidden');
|
|
64
|
+
this.menu.style.visibility = 'hidden';
|
|
65
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updatePosition).call(this);
|
|
66
|
+
// If the window width is changed when the menu is open,
|
|
67
|
+
// this keeps the menu aligned to the button
|
|
68
|
+
observer.observe(document.body);
|
|
69
|
+
this.menu.style.visibility = 'visible';
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
if (!this.open)
|
|
73
|
+
return;
|
|
74
|
+
this.removeAttribute('open');
|
|
75
|
+
(_b = this.trigger) === null || _b === void 0 ? void 0 : _b.setAttribute('aria-expanded', 'false');
|
|
76
|
+
this.overlay && this.overlay.setAttribute('hidden', 'true');
|
|
77
|
+
observer.unobserve(document.body);
|
|
78
|
+
// TODO: Do this without a setTimeout
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
var _a;
|
|
81
|
+
// There are some actions that may move focus to another part of the page intentionally.
|
|
82
|
+
// For example: "Quote Reply" in the comment options moves focus to the comment box.
|
|
83
|
+
// This only moves focus to the trigger if it's not managed in another way.
|
|
84
|
+
if (document.activeElement === document.body)
|
|
85
|
+
(_a = this.trigger) === null || _a === void 0 ? void 0 : _a.focus();
|
|
86
|
+
}, 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
connectedCallback() {
|
|
90
|
+
if (!this.trigger)
|
|
91
|
+
return;
|
|
92
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_addEvents).call(this);
|
|
93
|
+
}
|
|
94
|
+
disconnectedCallback() {
|
|
95
|
+
__classPrivateFieldGet(this, _ActionMenuElement_abortController, "f").abort();
|
|
96
|
+
}
|
|
97
|
+
show() {
|
|
98
|
+
this.open = true;
|
|
99
|
+
}
|
|
100
|
+
hide() {
|
|
101
|
+
this.open = false;
|
|
102
|
+
}
|
|
103
|
+
setFocusToMenuItem(newMenuItem) {
|
|
104
|
+
if (!this.menuItems)
|
|
105
|
+
return;
|
|
106
|
+
for (const item of this.menuItems) {
|
|
107
|
+
if (item === newMenuItem) {
|
|
108
|
+
item.tabIndex = 0;
|
|
109
|
+
newMenuItem.focus();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
item.tabIndex = -1;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
setFocusToPreviousMenuItem(currentMenuItem) {
|
|
117
|
+
if (!this.menuItems)
|
|
118
|
+
return;
|
|
119
|
+
let newMenuItem = null;
|
|
120
|
+
let index = null;
|
|
121
|
+
if (currentMenuItem === __classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f")) {
|
|
122
|
+
newMenuItem = __classPrivateFieldGet(this, _ActionMenuElement_lastMenuItem, "f");
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
index = this.menuItems.indexOf(currentMenuItem);
|
|
126
|
+
newMenuItem = this.menuItems[index - 1];
|
|
127
|
+
}
|
|
128
|
+
this.setFocusToMenuItem(newMenuItem);
|
|
129
|
+
return newMenuItem;
|
|
130
|
+
}
|
|
131
|
+
setFocusToNextMenuItem(currentMenuItem) {
|
|
132
|
+
if (!this.menuItems)
|
|
133
|
+
return;
|
|
134
|
+
let newMenuItem = null;
|
|
135
|
+
let index = null;
|
|
136
|
+
if (currentMenuItem === __classPrivateFieldGet(this, _ActionMenuElement_lastMenuItem, "f")) {
|
|
137
|
+
newMenuItem = __classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
index = this.menuItems.indexOf(currentMenuItem);
|
|
141
|
+
newMenuItem = this.menuItems[index + 1];
|
|
142
|
+
}
|
|
143
|
+
this.setFocusToMenuItem(newMenuItem);
|
|
144
|
+
return newMenuItem;
|
|
145
|
+
}
|
|
146
|
+
setFocusByFirstCharacter(currentMenuItem, character) {
|
|
147
|
+
if (!this.menuItems)
|
|
148
|
+
return;
|
|
149
|
+
let start = null;
|
|
150
|
+
let index = null;
|
|
151
|
+
if (character.length > 1) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
character = character.toLowerCase();
|
|
155
|
+
// Get start index for search based on position of currentMenuItem
|
|
156
|
+
start = this.menuItems.indexOf(currentMenuItem) + 1;
|
|
157
|
+
if (start >= this.menuItems.length) {
|
|
158
|
+
start = 0;
|
|
159
|
+
}
|
|
160
|
+
// Check remaining slots in the menu
|
|
161
|
+
index = __classPrivateFieldGet(this, _ActionMenuElement_firstCharactersOfItems, "f").indexOf(character, start);
|
|
162
|
+
// If character is not found in remaining slots, check from beginning
|
|
163
|
+
if (index === -1) {
|
|
164
|
+
index = __classPrivateFieldGet(this, _ActionMenuElement_firstCharactersOfItems, "f").indexOf(character, 0);
|
|
165
|
+
}
|
|
166
|
+
// If match is found
|
|
167
|
+
if (index > -1) {
|
|
168
|
+
this.setFocusToMenuItem(this.menuItems[index]);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Menu event handlers
|
|
172
|
+
buttonKeydown(event) {
|
|
173
|
+
// TODO: use data-hotkey
|
|
174
|
+
const key = event.key;
|
|
175
|
+
let flag = false;
|
|
176
|
+
switch (key) {
|
|
177
|
+
case ' ':
|
|
178
|
+
case 'Enter':
|
|
179
|
+
case 'ArrowDown':
|
|
180
|
+
case 'Down':
|
|
181
|
+
this.show();
|
|
182
|
+
this.setFocusToMenuItem(__classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f"));
|
|
183
|
+
flag = true;
|
|
184
|
+
break;
|
|
185
|
+
case 'Esc':
|
|
186
|
+
case 'Escape':
|
|
187
|
+
this.hide();
|
|
188
|
+
flag = true;
|
|
189
|
+
break;
|
|
190
|
+
case 'Up':
|
|
191
|
+
case 'ArrowUp':
|
|
192
|
+
this.show();
|
|
193
|
+
this.setFocusToMenuItem(__classPrivateFieldGet(this, _ActionMenuElement_lastMenuItem, "f"));
|
|
194
|
+
flag = true;
|
|
195
|
+
break;
|
|
196
|
+
default:
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
if (flag) {
|
|
200
|
+
event.stopPropagation();
|
|
201
|
+
event.preventDefault();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
buttonClick(event) {
|
|
205
|
+
if (this.open) {
|
|
206
|
+
this.hide();
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
this.show();
|
|
210
|
+
this.setFocusToMenuItem(__classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f"));
|
|
211
|
+
}
|
|
212
|
+
event.stopPropagation();
|
|
213
|
+
event.preventDefault();
|
|
214
|
+
}
|
|
215
|
+
menuItemKeydown(event) {
|
|
216
|
+
var _a;
|
|
217
|
+
const currentTarget = event.currentTarget;
|
|
218
|
+
const key = event.key;
|
|
219
|
+
let flag = false;
|
|
220
|
+
function isPrintableCharacter(str) {
|
|
221
|
+
return str.length === 1 && str.match(/\S/);
|
|
222
|
+
}
|
|
223
|
+
if (event.ctrlKey || event.altKey || event.metaKey) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (event.shiftKey) {
|
|
227
|
+
if (isPrintableCharacter(key)) {
|
|
228
|
+
this.setFocusByFirstCharacter(currentTarget, key);
|
|
229
|
+
flag = true;
|
|
230
|
+
}
|
|
231
|
+
if (event.key === 'Tab') {
|
|
232
|
+
(_a = this.trigger) === null || _a === void 0 ? void 0 : _a.focus();
|
|
233
|
+
this.hide();
|
|
234
|
+
flag = true;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
switch (key) {
|
|
239
|
+
case 'Enter':
|
|
240
|
+
this.hide();
|
|
241
|
+
break;
|
|
242
|
+
case 'Esc':
|
|
243
|
+
case 'Escape':
|
|
244
|
+
this.hide();
|
|
245
|
+
flag = true;
|
|
246
|
+
break;
|
|
247
|
+
case 'Up':
|
|
248
|
+
case 'ArrowUp':
|
|
249
|
+
this.setFocusToPreviousMenuItem(currentTarget);
|
|
250
|
+
flag = true;
|
|
251
|
+
break;
|
|
252
|
+
case 'ArrowDown':
|
|
253
|
+
case 'Down':
|
|
254
|
+
this.setFocusToNextMenuItem(currentTarget);
|
|
255
|
+
flag = true;
|
|
256
|
+
break;
|
|
257
|
+
case 'Home':
|
|
258
|
+
case 'PageUp':
|
|
259
|
+
this.setFocusToMenuItem(__classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f"));
|
|
260
|
+
flag = true;
|
|
261
|
+
break;
|
|
262
|
+
case 'End':
|
|
263
|
+
case 'PageDown':
|
|
264
|
+
this.setFocusToMenuItem(__classPrivateFieldGet(this, _ActionMenuElement_lastMenuItem, "f"));
|
|
265
|
+
flag = true;
|
|
266
|
+
break;
|
|
267
|
+
case 'Tab':
|
|
268
|
+
this.hide();
|
|
269
|
+
break;
|
|
270
|
+
default:
|
|
271
|
+
if (isPrintableCharacter(key)) {
|
|
272
|
+
this.setFocusByFirstCharacter(currentTarget, key);
|
|
273
|
+
flag = true;
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (flag) {
|
|
279
|
+
event.stopPropagation();
|
|
280
|
+
event.preventDefault();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
menuItemClick() {
|
|
284
|
+
this.hide();
|
|
285
|
+
}
|
|
286
|
+
menuItemMouseover(event) {
|
|
287
|
+
event.currentTarget.focus();
|
|
288
|
+
}
|
|
289
|
+
backgroundMousedown(event) {
|
|
290
|
+
if (!this)
|
|
291
|
+
return;
|
|
292
|
+
if (!this.contains(event.target)) {
|
|
293
|
+
if (this.open) {
|
|
294
|
+
this.hide();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
_ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_firstCharactersOfItems = new WeakMap(), _ActionMenuElement_firstMenuItem = new WeakMap(), _ActionMenuElement_lastMenuItem = new WeakMap(), _ActionMenuElement_instances = new WeakSet(), _ActionMenuElement_addEvents = function _ActionMenuElement_addEvents() {
|
|
300
|
+
__classPrivateFieldSet(this, _ActionMenuElement_abortController, new AbortController(), "f");
|
|
301
|
+
const { signal } = __classPrivateFieldGet(this, _ActionMenuElement_abortController, "f");
|
|
302
|
+
if (!this.trigger || !this.menu)
|
|
303
|
+
return;
|
|
304
|
+
this.trigger.addEventListener('keydown', this.buttonKeydown.bind(this), { signal });
|
|
305
|
+
this.trigger.addEventListener('click', this.buttonClick.bind(this), { signal });
|
|
306
|
+
__classPrivateFieldSet(this, _ActionMenuElement_firstCharactersOfItems, [], "f");
|
|
307
|
+
if (this.menuItems) {
|
|
308
|
+
for (const menuItem of this.menuItems) {
|
|
309
|
+
if (menuItem.textContent) {
|
|
310
|
+
__classPrivateFieldGet(this, _ActionMenuElement_firstCharactersOfItems, "f").push(menuItem.textContent.trim()[0].toLowerCase());
|
|
311
|
+
}
|
|
312
|
+
menuItem.addEventListener('keydown', this.menuItemKeydown.bind(this), { signal });
|
|
313
|
+
menuItem.addEventListener('click', this.menuItemClick.bind(this), { signal });
|
|
314
|
+
menuItem.addEventListener('mouseover', this.menuItemMouseover.bind(this), { signal });
|
|
315
|
+
if (!__classPrivateFieldGet(this, _ActionMenuElement_firstMenuItem, "f")) {
|
|
316
|
+
__classPrivateFieldSet(this, _ActionMenuElement_firstMenuItem, menuItem, "f");
|
|
317
|
+
}
|
|
318
|
+
__classPrivateFieldSet(this, _ActionMenuElement_lastMenuItem, menuItem, "f");
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
window.addEventListener('mousedown', this.backgroundMousedown.bind(this), true);
|
|
322
|
+
}, _ActionMenuElement_updatePosition = function _ActionMenuElement_updatePosition() {
|
|
323
|
+
if (!this.trigger || !this.menu)
|
|
324
|
+
return;
|
|
325
|
+
const float = this.querySelector('[data-menu-overlay]') || this.menu;
|
|
326
|
+
const anchor = this.trigger;
|
|
327
|
+
const { top, left } = getAnchoredPosition(float, anchor, { side: this.anchorSide, align: this.anchorAlign });
|
|
328
|
+
float.style.top = `${top}px`;
|
|
329
|
+
float.style.left = `${left}px`;
|
|
330
|
+
};
|
|
331
|
+
if (!window.customElements.get('action-menu')) {
|
|
332
|
+
window.ActionMenuElement = ActionMenuElement;
|
|
333
|
+
window.customElements.define('action-menu', ActionMenuElement);
|
|
334
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class ActionBarElement extends HTMLElement {
|
|
2
|
+
#private;
|
|
3
|
+
items: HTMLElement[];
|
|
4
|
+
menuItems: HTMLElement[];
|
|
5
|
+
moreMenu: HTMLElement;
|
|
6
|
+
connectedCallback(): void;
|
|
7
|
+
disconnectedCallback(): void;
|
|
8
|
+
}
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
ActionBarElement: typeof ActionBarElement;
|
|
12
|
+
}
|
|
13
|
+
}
|