@inboxsdk/core 0.2.29-alpha.3 → 0.2.29-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/inboxsdk.js +34 -33
  2. package/inboxsdk.js.map +1 -1
  3. package/package.json +2 -1
  4. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-app-menu-item.d.ts.map +1 -1
  5. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-app-menu-item.js +3 -4
  6. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-collapsible-panel.d.ts +1 -1
  7. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-collapsible-panel.d.ts.map +1 -1
  8. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/add-collapsible-panel.js +14 -4
  9. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-gmail-styles.d.ts +5 -1
  10. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-gmail-styles.d.ts.map +1 -1
  11. package/src/platform-implementation-js/dom-driver/gmail/gmail-driver/track-gmail-styles.js +32 -20
  12. package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter.d.ts +2 -0
  13. package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter.d.ts.map +1 -1
  14. package/src/platform-implementation-js/dom-driver/gmail/gmail-element-getter.js +17 -12
  15. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-menu-item-view.d.ts +4 -12
  16. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-menu-item-view.d.ts.map +1 -1
  17. package/src/platform-implementation-js/dom-driver/gmail/views/gmail-app-menu-item-view.js +30 -18
  18. package/src/platform-implementation-js/namespaces/app-menu.d.ts +15 -4
  19. package/src/platform-implementation-js/namespaces/app-menu.d.ts.map +1 -1
  20. package/src/platform-implementation-js/views/app-menu-item-view.d.ts.map +1 -1
  21. package/src/platform-implementation-js/views/app-menu-item-view.js +81 -27
  22. package/src/platform-implementation-js/views/collapsible-panel-view.d.ts +8 -7
  23. package/src/platform-implementation-js/views/collapsible-panel-view.d.ts.map +1 -1
  24. package/src/platform-implementation-js/views/collapsible-panel-view.js +104 -52
@@ -23,16 +23,17 @@ export declare class CollapsiblePanelView extends CollapsiblePanelView_base {
23
23
  /** A hover popover has both ACTIVE _and_ HOVER */
24
24
  readonly HOVER: "aJu";
25
25
  readonly COLLAPSED_HOVER: "bym";
26
+ readonly PANEL_LESS: "a3W";
26
27
  };
27
- get element(): HTMLElement | undefined;
28
+ get loading(): boolean;
29
+ setLoading(loading: boolean): void;
30
+ get panelDescriptor(): AppMenuItemPanelDescriptor;
28
31
  set panelDescriptor(panelDescriptor: AppMenuItemPanelDescriptor);
29
- constructor(driver: GmailDriver);
30
- /**
31
- * @internal
32
- */
33
- activate(): void;
32
+ get element(): HTMLElement;
33
+ get scrollablePaneElement(): Element | null;
34
+ constructor(driver: GmailDriver, panelDescriptor: AppMenuItemPanelDescriptor);
34
35
  remove(): void;
35
- addNavItem(navItemDescriptor: NavItemDescriptor | Kefir.Observable<NavItemDescriptor, any>): NavItemView | undefined;
36
+ addNavItem(navItemDescriptor: NavItemDescriptor | Kefir.Observable<NavItemDescriptor, any>): NavItemView;
36
37
  }
37
38
  export {};
38
39
  //# sourceMappingURL=collapsible-panel-view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collapsible-panel-view.d.ts","sourceRoot":"","sources":["../../../../../src/platform-implementation-js/views/collapsible-panel-view.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAIpE,OAAO,WAAW,MAAM,kCAAkC,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAE1C,eAAO,MAAM,YAAY,OAAiB,CAAC;AAC3C,eAAO,MAAM,cAAc,8BAAwC,CAAC;AAQpE,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CAC/B,CAAC;mDAEmE,aAAa,aAAa,CAAC;AAAhG,qBAAa,oBAAqB,SAAQ,yBAAuD;;IAC/F,MAAM,CAAC,gBAAgB;;;MAGZ;IACX,MAAM,CAAC,UAAU;;;QAGf,kDAAkD;;;MAGzC;IAQX,IAAI,OAAO,4BAEV;IAED,IAAI,eAAe,CAAC,eAAe,EAAE,0BAA0B,EAG9D;gBAEW,MAAM,EAAE,WAAW;IAS/B;;OAEG;IACH,QAAQ;IAQR,MAAM;IAON,UAAU,CACR,iBAAiB,EACb,iBAAiB,GACjB,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,GAAG,CAAC;CAkK/C"}
1
+ {"version":3,"file":"collapsible-panel-view.d.ts","sourceRoot":"","sources":["../../../../../src/platform-implementation-js/views/collapsible-panel-view.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AAEzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAIpE,OAAO,WAAW,MAAM,kCAAkC,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,WAAW,MAAM,iBAAiB,CAAC;AAI1C,eAAO,MAAM,YAAY,OAAiB,CAAC;AAC3C,eAAO,MAAM,cAAc,8BAAwC,CAAC;AAcpE,KAAK,aAAa,GAAG;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CAC/B,CAAC;mDAEmE,aAAa,aAAa,CAAC;AAAhG,qBAAa,oBAAqB,SAAQ,yBAAuD;;IAC/F,MAAM,CAAC,gBAAgB;;;MAGZ;IACX,MAAM,CAAC,UAAU;;;QAGf,kDAAkD;;;;MAIzC;IASX,IAAI,OAAO,YAEV;IAED,UAAU,CAAC,OAAO,EAAE,OAAO;IAS3B,IAAI,eAAe,+BAElB;IAED,IAAI,eAAe,CAAC,eAAe,4BAAA,EAGlC;IAED,IAAI,OAAO,gBAEV;IAED,IAAI,qBAAqB,mBAExB;gBAGC,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,0BAA0B;IAmB7C,MAAM;IAON,UAAU,CACR,iBAAiB,EACb,iBAAiB,GACjB,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,GAAG,CAAC;CA4M/C"}
@@ -6,11 +6,18 @@ import autoHtml from 'auto-html';
6
6
  import querySelector from '../lib/dom/querySelectorOrFail';
7
7
  import GmailElementGetter from '../dom-driver/gmail/gmail-element-getter';
8
8
  import NavItemView from './nav-item-view';
9
+ import { stylesStream } from '../dom-driver/gmail/gmail-driver/track-gmail-styles';
10
+ import isEqual from 'fast-deep-equal';
9
11
  export const NATIVE_CLASS = 'aqn';
10
12
  export const INBOXSDK_CLASS = 'inboxsdk__collapsiblePanel';
11
13
  const ELEMENT_CLASS = `${NATIVE_CLASS} ${INBOXSDK_CLASS} oy8Mbf`;
12
14
  const PRIMARY_BUTTON_ELEMENT_CLASS = 'T-I T-I-KE L3';
13
15
  const PRIMARY_BUTTON_ELEMENT_SELECTOR = '.T-I.T-I-KE.L3';
16
+ const scrollablePanelClass = 'at9';
17
+ const scrollablePanelSelector = `.${scrollablePanelClass}`;
18
+ const loadingElementClass = 'inboxsdk__collapsiblePanel_loading_container';
19
+ const panelLoadingClass = `${loadingElementClass}--active`;
20
+ const loadingElementSelector = `.${loadingElementClass}`;
14
21
  const NAV_MENU_CONTAINER_ELEMENT_SELECTOR = '.at9 .n3 .TK';
15
22
  export class CollapsiblePanelView extends EventEmitter {
16
23
  static elementSelectors = {
@@ -23,6 +30,7 @@ export class CollapsiblePanelView extends EventEmitter {
23
30
  /** A hover popover has both ACTIVE _and_ HOVER */
24
31
  HOVER: 'aJu',
25
32
  COLLAPSED_HOVER: 'bym',
33
+ PANEL_LESS: 'a3W',
26
34
  };
27
35
  #panelDescriptor;
28
36
  #element;
@@ -30,42 +38,57 @@ export class CollapsiblePanelView extends EventEmitter {
30
38
  #id = Math.random().toFixed(3);
31
39
  #ARIA_LABELLED_BY_ID = Math.random().toFixed(3);
32
40
  #driver;
33
- get element() {
34
- return this.#element;
41
+ #loading;
42
+ get loading() {
43
+ return this.#loading;
44
+ }
45
+ setLoading(loading) {
46
+ const changed = this.#loading !== loading;
47
+ this.#loading = loading;
48
+ if (changed) {
49
+ this.#update();
50
+ }
51
+ }
52
+ get panelDescriptor() {
53
+ return this.#panelDescriptor;
35
54
  }
36
55
  set panelDescriptor(panelDescriptor) {
37
56
  this.#panelDescriptor = panelDescriptor;
38
57
  this.#update();
39
58
  }
40
- constructor(driver) {
59
+ get element() {
60
+ return this.#element;
61
+ }
62
+ get scrollablePaneElement() {
63
+ return this.element.querySelector(scrollablePanelSelector);
64
+ }
65
+ constructor(driver, panelDescriptor) {
41
66
  super();
42
67
  this.#driver = driver;
68
+ this.#panelDescriptor = panelDescriptor;
69
+ this.#loading = panelDescriptor.loadingIcon != null;
43
70
  this.#element = this.#setupElement();
44
71
  this.#element.addEventListener('mouseleave', (e) => {
45
72
  this.emit('blur', e);
46
73
  });
47
- }
48
- /**
49
- * @internal
50
- */
51
- activate() {
52
- const element = this.element;
53
- if (!element)
54
- return;
55
- element?.classList.remove(CollapsiblePanelView.elementCss.HOVER);
56
- element.classList.add(CollapsiblePanelView.elementCss.ACTIVE);
74
+ stylesStream
75
+ .skipDuplicates((a, b) => isEqual(a, b))
76
+ .onValue(({ type }) => {
77
+ if (type === 'theme') {
78
+ this.#update();
79
+ }
80
+ });
57
81
  }
58
82
  remove() {
59
83
  if (this.#destroyed)
60
84
  return;
61
85
  this.#destroyed = true;
62
- this.element?.remove();
86
+ this.element.remove();
63
87
  this.emit('destroy');
64
88
  }
65
89
  addNavItem(navItemDescriptor) {
66
- const element = this.element;
67
- if (!element)
68
- return;
90
+ this.setLoading(false);
91
+ const { element } = this;
69
92
  const navMenuContainerElement = querySelector(element, NAV_MENU_CONTAINER_ELEMENT_SELECTOR);
70
93
  const appId = `collapsible-panel-${this.#id}`;
71
94
  const navItemDescriptorPropertyStream = kefirCast(Kefir, navItemDescriptor).toProperty();
@@ -73,23 +96,39 @@ export class CollapsiblePanelView extends EventEmitter {
73
96
  const navItemView = new NavItemView(appId, this.#driver, navItemDescriptorPropertyStream, gmailNavItemView);
74
97
  return navItemView;
75
98
  }
99
+ #extractPrimaryButtonTheme() {
100
+ const { iconUrl } = this.panelDescriptor.primaryButton ?? {};
101
+ if (!iconUrl) {
102
+ return;
103
+ }
104
+ const theme = GmailElementGetter.isDarkTheme() ? iconUrl.darkTheme : iconUrl.lightTheme;
105
+ if (!theme) {
106
+ return;
107
+ }
108
+ if (typeof theme === 'string') {
109
+ return {
110
+ panelHovered: theme,
111
+ panelDefault: theme,
112
+ };
113
+ }
114
+ else {
115
+ return {
116
+ panelDefault: theme.panelDefault,
117
+ panelHovered: theme.panelHovered,
118
+ };
119
+ }
120
+ }
76
121
  #setupElement() {
77
- const { iconUrl: themedIcons, className, name = '', } = this.#panelDescriptor?.primaryButton ?? {};
122
+ const { panelDescriptor } = this;
123
+ const { loadingIcon } = panelDescriptor;
124
+ const { className, name = '' } = panelDescriptor?.primaryButton ?? {};
78
125
  const element = document.createElement('div');
79
- const burgerMenuOpen = GmailElementGetter.isAppBurgerMenuOpen();
80
- element.className = cx(ELEMENT_CLASS, {
81
- [CollapsiblePanelView.elementCss.COLLAPSED]: !burgerMenuOpen,
82
- });
126
+ element.className = cx(ELEMENT_CLASS, this.panelDescriptor.className);
83
127
  const primaryButtonClass = cx(PRIMARY_BUTTON_ELEMENT_CLASS, className);
84
- let iconUrl;
85
- if (themedIcons) {
86
- if (GmailElementGetter.isDarkTheme()) {
87
- iconUrl = themedIcons.darkTheme;
88
- }
89
- else {
90
- iconUrl = themedIcons.lightTheme;
91
- }
92
- }
128
+ const loadingElClass = cx(loadingElementClass, {
129
+ [panelLoadingClass]: this.#loading,
130
+ });
131
+ const { panelDefault: defaultIconUrl, panelHovered: hoverPanelIconUrl } = this.#extractPrimaryButtonTheme() ?? {};
93
132
  element.innerHTML = autoHtml `
94
133
  <div class="aBO">
95
134
  <div class="aic">
@@ -99,7 +138,8 @@ export class CollapsiblePanelView extends EventEmitter {
99
138
  </div>
100
139
  </div>
101
140
  </div>
102
- <div class="at9">
141
+ <div class="${scrollablePanelClass}">
142
+ <div class="${loadingElClass}">${loadingIcon ? { __html: loadingIcon } : ''}</div>
103
143
  <div class="Ls77Lb aZ6">
104
144
  <div class="pp" style="user-select: none;">
105
145
  <div>
@@ -123,42 +163,42 @@ export class CollapsiblePanelView extends EventEmitter {
123
163
  </div>
124
164
  </div>
125
165
  </div>
126
- <div class="aTV" style="top: 27px;"></div>
166
+ <div class="aTV"></div>
127
167
  `.trim();
128
168
  const primaryBtnEl = querySelector(element, PRIMARY_BUTTON_ELEMENT_SELECTOR);
129
- primaryBtnEl.style.setProperty('--background-image', iconUrl ? `url(${iconUrl})` : 'unset');
169
+ primaryBtnEl.style.setProperty('--background-image', defaultIconUrl ? `url(${defaultIconUrl})` : 'unset');
170
+ primaryBtnEl.style.setProperty('--background-image--hover', hoverPanelIconUrl ? `url(${hoverPanelIconUrl})` : 'unset');
130
171
  primaryBtnEl.addEventListener('click', this.#onPrimaryButtonClick);
131
172
  return element;
132
173
  }
133
174
  #onPrimaryButtonClick = (e) => {
134
- this.#panelDescriptor?.primaryButton?.onClick?.(e);
175
+ this.panelDescriptor.primaryButton?.onClick?.(e);
135
176
  };
136
177
  #update() {
137
178
  const element = this.element;
138
179
  if (!element)
139
180
  return;
140
- const { ACTIVE, COLLAPSED } = CollapsiblePanelView.elementCss;
141
- const isActive = element.classList.contains(ACTIVE);
142
- const isCollapsed = element.classList.contains(COLLAPSED);
143
- element.className = cx(ELEMENT_CLASS, this.#panelDescriptor?.className, {
144
- [ACTIVE]: isActive,
145
- [COLLAPSED]: isCollapsed,
146
- });
181
+ const existingClassNames = Object.values(CollapsiblePanelView.elementCss).filter((className) => element.classList.contains(className));
182
+ element.className = cx(ELEMENT_CLASS, this.panelDescriptor.className, ...existingClassNames);
147
183
  this.#updateName(element);
148
184
  this.#updateIcon(element);
185
+ this.#updateScrollablePanelLoading(element);
149
186
  }
150
187
  #updateIcon(element) {
151
188
  const iconContainerEl = querySelector(element, PRIMARY_BUTTON_ELEMENT_SELECTOR);
152
- const { iconUrl, className } = this.#panelDescriptor?.primaryButton ?? {};
153
- if (iconUrl) {
154
- const backgroundImage = `url(${GmailElementGetter.isDarkTheme()
155
- ? iconUrl.darkTheme
156
- : iconUrl.lightTheme})`;
157
- iconContainerEl.style.setProperty('--background-image', backgroundImage);
158
- }
159
- else {
160
- iconContainerEl.style.setProperty('--background-image', 'unset');
189
+ const { panelDefault, panelHovered } = this.#extractPrimaryButtonTheme() ?? {};
190
+ for (const [key, value] of Object.entries({
191
+ '--background-image--hover': panelHovered,
192
+ '--background-image': panelDefault,
193
+ })) {
194
+ if (value) {
195
+ iconContainerEl.style.setProperty(key, `url(${value})`);
196
+ }
197
+ else {
198
+ iconContainerEl.style.removeProperty(key);
199
+ }
161
200
  }
201
+ const { className } = this.panelDescriptor.primaryButton ?? {};
162
202
  iconContainerEl.className = cx(PRIMARY_BUTTON_ELEMENT_CLASS, className);
163
203
  }
164
204
  #updateName(element) {
@@ -166,6 +206,18 @@ export class CollapsiblePanelView extends EventEmitter {
166
206
  if (!buttonTextEl) {
167
207
  return;
168
208
  }
169
- buttonTextEl.textContent = this.#panelDescriptor?.primaryButton?.name ?? '';
209
+ buttonTextEl.textContent = this.panelDescriptor.primaryButton?.name ?? '';
210
+ }
211
+ #updateScrollablePanelLoading(element) {
212
+ const scrollablePanelLoadingEl = element.querySelector(loadingElementSelector);
213
+ if (!scrollablePanelLoadingEl) {
214
+ return;
215
+ }
216
+ if (this.loading) {
217
+ scrollablePanelLoadingEl.classList.add(panelLoadingClass);
218
+ }
219
+ else {
220
+ scrollablePanelLoadingEl.classList.remove(panelLoadingClass);
221
+ }
170
222
  }
171
223
  }