update
This commit is contained in:
parent
c78c6117b6
commit
99ee9e680c
13 changed files with 49 additions and 226 deletions
|
@ -2,7 +2,7 @@
|
||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es2021": true
|
"es2023": true
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"extends": "eslint:recommended",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
|
|
37
README.md
37
README.md
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
# Electron Tabs
|
# Electron Tabs
|
||||||
|
|
||||||
![Electron Tab Demo](image.jpg)
|
![Electron Tab Demo](image.png)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
@ -93,9 +93,6 @@ Add a new tab and returns the related `Tab` instance.
|
||||||
|
|
||||||
* `title`: tab title.
|
* `title`: tab title.
|
||||||
* `src`: URL to the page which will be loaded into the view. This is actually the same than `options.webview.src`.
|
* `src`: URL to the page which will be loaded into the view. This is actually the same than `options.webview.src`.
|
||||||
* `badge`: optional text to put into a badge, badge will be hidden if false.
|
|
||||||
* `iconURL`: optional URL to the tab icon.
|
|
||||||
* `icon`: optional code for a tab icon. Can be used with symbol libraries (example with Font Awesome: `icon: 'fa fa-icon-name'`). This attribute is ignored if an `iconURL` was given.
|
|
||||||
* `closable` (default: `true`): if set to `true` the close button won't be displayed and the user won't be able to close the tab. See also `tab.close()`.
|
* `closable` (default: `true`): if set to `true` the close button won't be displayed and the user won't be able to close the tab. See also `tab.close()`.
|
||||||
* `visible` (default: `true`): set this to `false` if you don't want to display the tab once it is loaded. If set to `false` then you will need to call `tab.show()` to display the tab.
|
* `visible` (default: `true`): set this to `false` if you don't want to display the tab once it is loaded. If set to `false` then you will need to call `tab.show()` to display the tab.
|
||||||
* `active` (default: `false`): set this to `true` if you want to activate the tab once it is loaded. Otherwise you will need to call `tab.activate()`.
|
* `active` (default: `false`): set this to `true` if you want to activate the tab once it is loaded. Otherwise you will need to call `tab.activate()`.
|
||||||
|
@ -172,22 +169,6 @@ Set tab title.
|
||||||
|
|
||||||
Get current tab title.
|
Get current tab title.
|
||||||
|
|
||||||
#### `tab.setBadge(badge)`
|
|
||||||
|
|
||||||
Set tab badge.
|
|
||||||
|
|
||||||
#### `tab.getBadge()`
|
|
||||||
|
|
||||||
Get current tab badge.
|
|
||||||
|
|
||||||
#### `tab.setIcon (iconURL, icon)`
|
|
||||||
|
|
||||||
Set tab icon (a iconURL or an icon must be given).
|
|
||||||
|
|
||||||
#### `tab.getIcon()`
|
|
||||||
|
|
||||||
Get current tab icon URL / icon.
|
|
||||||
|
|
||||||
#### `tab.setPosition(newPosition)`
|
#### `tab.setPosition(newPosition)`
|
||||||
|
|
||||||
Move tab to the specified position. See [`tabGroup.getTabByPosition`](#tabgroupgettabbypositionposition) for information about positions.
|
Move tab to the specified position. See [`tabGroup.getTabByPosition`](#tabgroupgettabbypositionposition) for information about positions.
|
||||||
|
@ -222,8 +203,6 @@ The following events are emitted:
|
||||||
* `tab.on("webview-ready", (tab) => { ... });`
|
* `tab.on("webview-ready", (tab) => { ... });`
|
||||||
* `tab.on("webview-dom-ready", (tab) => { ... });`
|
* `tab.on("webview-dom-ready", (tab) => { ... });`
|
||||||
* `tab.on("title-changed", (title, tab) => { ... });`
|
* `tab.on("title-changed", (title, tab) => { ... });`
|
||||||
* `tab.on("badge-changed", (badge, tab) => { ... });`
|
|
||||||
* `tab.on("icon-changed", (icon, tab) => { ... });`
|
|
||||||
* `tab.on("active", (tab) => { ... });`
|
* `tab.on("active", (tab) => { ... });`
|
||||||
* `tab.on("inactive", (tab) => { ... });`
|
* `tab.on("inactive", (tab) => { ... });`
|
||||||
* `tab.on("visible", (tab) => { ... });`
|
* `tab.on("visible", (tab) => { ... });`
|
||||||
|
@ -259,15 +238,12 @@ Since `TabGroup` is a Web Component you won't be able to change its styles direc
|
||||||
</tab-group>
|
</tab-group>
|
||||||
```
|
```
|
||||||
|
|
||||||
This method is particularly useful when you need to define custom badges or tab styles:
|
This method is particularly useful when you need to define tab styles:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<tab-group new-tab-button="true" sortable="true">
|
<tab-group new-tab-button="true" sortable="true">
|
||||||
<style>
|
<style>
|
||||||
/* Add custom styles */
|
/* Add custom styles */
|
||||||
.my-badge {
|
|
||||||
background-color: orange;
|
|
||||||
}
|
|
||||||
.my-custom-tab {
|
.my-custom-tab {
|
||||||
color: red;
|
color: red;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -280,15 +256,6 @@ This method is particularly useful when you need to define custom badges or tab
|
||||||
<script>
|
<script>
|
||||||
const tabGroup = document.querySelector("tab-group");
|
const tabGroup = document.querySelector("tab-group");
|
||||||
|
|
||||||
tabGroup.addTab({
|
|
||||||
title: "Tab with custom badge",
|
|
||||||
src: "page.html",
|
|
||||||
badge: {
|
|
||||||
text: "5",
|
|
||||||
classname: "my-badge"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tabGroup.addTab({
|
tabGroup.addTab({
|
||||||
title: "Tab with custom style",
|
title: "Tab with custom style",
|
||||||
src: "page.html",
|
src: "page.html",
|
||||||
|
|
|
@ -3,6 +3,15 @@ const app = electron.app;
|
||||||
|
|
||||||
app.on("ready", function () {
|
app.on("ready", function () {
|
||||||
const mainWindow = new electron.BrowserWindow({
|
const mainWindow = new electron.BrowserWindow({
|
||||||
|
titleBarStyle: 'hidden',
|
||||||
|
frame: false,
|
||||||
|
width: 1300,
|
||||||
|
height: 1000,
|
||||||
|
titleBarOverlay: { // For Windows and Linux`
|
||||||
|
color: '#e7eaed',
|
||||||
|
symbolColor: '#696A6C',
|
||||||
|
height: 40,
|
||||||
|
},
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
webviewTag: true
|
webviewTag: true
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
|
|
||||||
<tab-group new-tab-button="true" sortable="true">
|
<tab-group new-tab-button="true" sortable="true">
|
||||||
<style>
|
<style>
|
||||||
|
/* If you use a custom titlebar, add drag ability to navigation bar */
|
||||||
|
/* Electron Documentation: https://www.electronjs.org/docs/latest/tutorial/custom-window-interactions#custom-draggable-regions */
|
||||||
|
.nav {-webkit-app-region: drag} /* Apply to navigation bar */
|
||||||
|
.tab {-webkit-app-region: no-drag} /* Unapply it from the tabs */
|
||||||
|
button {-webkit-app-region: no-drag} /* Unapply it from the buttons */
|
||||||
|
|
||||||
/* Add custom styles */
|
/* Add custom styles */
|
||||||
.my-badge {
|
.my-badge {
|
||||||
background-color: #327BB1;
|
background-color: #327BB1;
|
||||||
|
@ -26,15 +32,15 @@
|
||||||
tabGroup.on("ready", () => console.info("TabGroup is ready"));
|
tabGroup.on("ready", () => console.info("TabGroup is ready"));
|
||||||
|
|
||||||
tabGroup.setDefaultTab({
|
tabGroup.setDefaultTab({
|
||||||
title: "Wikipedia",
|
title: "Opengist",
|
||||||
src: "https://www.wikipedia.org/",
|
src: "https://gist.sudovanilla.org/all",
|
||||||
active: true,
|
active: true,
|
||||||
ready: () => console.info("New Tab is ready")
|
ready: () => console.info("New Tab is ready")
|
||||||
});
|
});
|
||||||
|
|
||||||
tabGroup.addTab({
|
tabGroup.addTab({
|
||||||
title: "electron-tabs on NPM",
|
title: "electron-tabs | SudoVanilla Ark",
|
||||||
src: "https://www.npmjs.com/package/electron-tabs",
|
src: "https://ark.sudovanilla.org/Korbs/electron-tabs/",
|
||||||
badge: {
|
badge: {
|
||||||
text: "5",
|
text: "5",
|
||||||
classname: "my-badge"
|
classname: "my-badge"
|
||||||
|
@ -42,8 +48,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
tabGroup.addTab({
|
tabGroup.addTab({
|
||||||
title: "electron-tabs on Github",
|
title: "electron-tabs | SudoVanilla Registry",
|
||||||
src: "https://github.com/brrd/electron-tabs",
|
src: "https://registry.sudovanilla.org/-/web/detail/@sudovanilla/electron-tabs",
|
||||||
iconURL: "mark-github.svg",
|
iconURL: "mark-github.svg",
|
||||||
active: true
|
active: true
|
||||||
});
|
});
|
||||||
|
|
14
dist/electron-tabs.d.ts
vendored
14
dist/electron-tabs.d.ts
vendored
|
@ -10,10 +10,7 @@ interface TabGroupOptions {
|
||||||
}
|
}
|
||||||
interface TabOptions {
|
interface TabOptions {
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
badge?: Badge;
|
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
icon?: string;
|
|
||||||
iconURL?: string;
|
|
||||||
ready?: ((tab: Tab) => void);
|
ready?: ((tab: Tab) => void);
|
||||||
src?: string;
|
src?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -22,10 +19,6 @@ interface TabOptions {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
interface Badge {
|
|
||||||
text: string;
|
|
||||||
classname: string;
|
|
||||||
}
|
|
||||||
export class TabGroup extends HTMLElement {
|
export class TabGroup extends HTMLElement {
|
||||||
buttonContainer: HTMLDivElement;
|
buttonContainer: HTMLDivElement;
|
||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
|
@ -56,11 +49,8 @@ export class TabGroup extends HTMLElement {
|
||||||
activateRecentTab(): void;
|
activateRecentTab(): void;
|
||||||
}
|
}
|
||||||
export class Tab extends EventTarget {
|
export class Tab extends EventTarget {
|
||||||
badge: Badge;
|
|
||||||
closable: boolean;
|
closable: boolean;
|
||||||
element: HTMLDivElement;
|
element: HTMLDivElement;
|
||||||
icon: string;
|
|
||||||
iconURL: string;
|
|
||||||
id: number;
|
id: number;
|
||||||
isClosed: boolean;
|
isClosed: boolean;
|
||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
|
@ -80,10 +70,6 @@ export class Tab extends EventTarget {
|
||||||
initWebview(): void;
|
initWebview(): void;
|
||||||
setTitle(title: string): this;
|
setTitle(title: string): this;
|
||||||
getTitle(): string;
|
getTitle(): string;
|
||||||
setBadge(badge?: Badge): void;
|
|
||||||
getBadge(): Badge;
|
|
||||||
setIcon(iconURL: string, icon: string): this;
|
|
||||||
getIcon(): string;
|
|
||||||
setPosition(newPosition: number): this;
|
setPosition(newPosition: number): this;
|
||||||
getPosition(fromRight?: boolean): number;
|
getPosition(fromRight?: boolean): number;
|
||||||
activate(): this;
|
activate(): this;
|
||||||
|
|
2
dist/electron-tabs.d.ts.map
vendored
2
dist/electron-tabs.d.ts.map
vendored
File diff suppressed because one or more lines are too long
55
dist/electron-tabs.js
vendored
55
dist/electron-tabs.js
vendored
|
@ -2622,10 +2622,10 @@ var $64afbd09cd65a300$export$2e2bcd8739ae039 = $64afbd09cd65a300$export$31b3ca70
|
||||||
|
|
||||||
|
|
||||||
var $761c8257657e0bda$exports = {};
|
var $761c8257657e0bda$exports = {};
|
||||||
$761c8257657e0bda$exports = ":host {\n --tabgroup-background: #e7eaed;\n --tab-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --tab-font-size: 13px;\n --tab-background: #e7eaed;\n --tab-color: #696a6c;\n --tab-border-color: #dadce0;\n --tab-transition: background-color .2s ease-out, color .2s ease-out;\n --tab-cursor: pointer;\n --tab-active-color: currentcolor;\n --tab-active-background: #fff;\n --tag-hover-color: currentcolor;\n --tag-hover-background: #f1f3f4;\n --button-font-size: 15px;\n --button-background: none;\n --button-color: #696a6c;\n --button-hover-background: #dadce0;\n --button-hover-color: #383a3e;\n --button-border-radius: 50%;\n --button-cursor: pointer;\n --badge-background: #383a3e;\n --badge-color: #fff;\n --close-button-visibility: visible;\n}\n\nwebview {\n visibility: hidden;\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\nwebview.visible {\n visibility: visible;\n}\n\n.etabs {\n font-family: var(--tab-font-family);\n text-rendering: optimizeLegibility;\n font-feature-settings: \"liga\", \"clig\", \"kern\";\n}\n\n.nav {\n background: var(--tabgroup-background);\n box-shadow: inset 0 -1px var(--tab-border-color);\n border-top: 1px solid var(--tab-border-color);\n font-size: var(--tab-font-size);\n cursor: default;\n -webkit-user-select: none;\n user-select: none;\n width: 100%;\n height: 32px;\n display: none;\n}\n\n.nav.visible {\n display: flex;\n}\n\n.tabs {\n height: 100%;\n}\n\n.tab {\n background: var(--tab-background);\n box-shadow: inset 0 -1px var(--tab-border-color);\n color: var(--tab-color);\n cursor: var(--tab-cursor);\n font-size: var(--tab-font-size);\n transition: var(--tab-transition);\n box-sizing: border-box;\n align-items: center;\n height: 100%;\n padding: 5px 9px;\n display: none;\n position: relative;\n}\n\n.tab:first-child {\n border-left: none;\n}\n\n.tab.visible {\n display: inline-flex;\n}\n\n.tab.active {\n color: var(--tab-active-color);\n background: var(--tab-active-background);\n border-left: 1px solid var(--tab-border-color);\n border-right: 1px solid var(--tab-border-color);\n box-shadow: none;\n padding-left: 8px;\n padding-right: 8px;\n}\n\n.tab.active:last-child {\n border-right: none;\n}\n\n.tab.visible:not(.active) + .tab.visible:not(.active) {\n border-left: 1px solid var(--tab-border-color);\n padding-left: 8px;\n}\n\n.tab:not(.active):hover {\n background: var(--tab-hover-background);\n color: var(--tab-hover-color);\n}\n\n.tab-badge {\n background: var(--badge-background);\n color: var(--badge-color);\n text-align: center;\n border-radius: 5px;\n margin-left: 5px;\n padding: 1px 4px;\n font-size: 8px;\n font-weight: bold;\n line-height: 1.2;\n}\n\n.tab-badge.hidden {\n display: none;\n}\n\n.tab-icon {\n height: 16px;\n display: inline-block;\n}\n\n.tab-icon img {\n max-width: 16px;\n max-height: 16px;\n}\n\n.tab-title, .tab-close {\n margin-left: 10px;\n display: inline-block;\n}\n\n.tab-close button {\n background: var(--button-background);\n border-radius: var(--button-border-radius);\n color: var(--button-color);\n cursor: var(--button-cursor);\n font-size: var(--button-font-size);\n text-align: center;\n width: 20px;\n height: 20px;\n visibility: var(--close-button-visibility);\n border: none;\n padding: 1px 0 0;\n display: inline-block;\n}\n\n.tab.active .tab-close button {\n visibility: visible;\n}\n\n.tab-close button:hover {\n color: var(--button-hover-color);\n background: var(--button-hover-background);\n}\n\n.buttons {\n border-left: 1px solid var(--tab-border-color);\n padding: 5px;\n display: flex;\n}\n\n.buttons button {\n color: var(--button-color);\n background: var(--button-background);\n border-radius: var(--button-border-radius);\n cursor: var(--button-cursor);\n font-size: var(--button-font-size);\n text-align: center;\n border: none;\n width: 20px;\n height: 20px;\n margin: 0;\n padding: 1px 0 0;\n font-family: inherit;\n line-height: 1;\n display: block;\n}\n\n.buttons button:hover {\n color: var(--button-hover-color);\n background: var(--button-hover-background);\n}\n\n.views {\n height: calc(100vh - 33px);\n position: relative;\n}\n";
|
$761c8257657e0bda$exports = ":host {\n --tabgroup-background: #e7eaed;\n --tab-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen-Sans, Ubuntu, Cantarell, \"Helvetica Neue\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n --tab-font-size: 13px;\n --tab-background: #e7eaed;\n --tab-color: #696a6c;\n --tab-border-color: #dadce0;\n --tab-border-radius: 4px;\n --tab-transition: background-color .2s ease-out, color .2s ease-out;\n --tab-cursor: pointer;\n --tab-active-color: currentcolor;\n --tab-active-background: #fff;\n --tag-hover-color: currentcolor;\n --tag-hover-background: #f1f3f4;\n --button-font-size: 15px;\n --button-background: none;\n --button-color: #696a6c;\n --button-hover-background: #dadce0;\n --button-hover-color: #383a3e;\n --button-border-radius: 4px;\n --button-cursor: pointer;\n --close-button-visibility: visible;\n}\n\nwebview {\n visibility: hidden;\n width: 100%;\n height: 100%;\n position: absolute;\n}\n\nwebview.visible {\n visibility: visible;\n}\n\n.etabs {\n font-family: var(--tab-font-family);\n text-rendering: optimizeLegibility;\n font-feature-settings: \"liga\", \"clig\", \"kern\";\n}\n\n.nav {\n background: var(--tabgroup-background);\n border-top: 1px solid var(--tab-border-color);\n font-size: var(--tab-font-size);\n cursor: default;\n -webkit-user-select: none;\n user-select: none;\n width: calc(100% - 16px);\n height: 32px;\n padding: 4px 6px;\n display: none;\n}\n\n.nav.visible {\n display: flex;\n}\n\n.tabs {\n gap: 4px;\n height: 100%;\n display: flex;\n}\n\n.tab {\n background: var(--tab-background);\n border: 1px var(--tab-border-color) solid;\n color: var(--tab-color);\n cursor: var(--tab-cursor);\n font-size: var(--tab-font-size);\n transition: var(--tab-transition);\n border-radius: var(--tab-border-radius);\n box-sizing: border-box;\n align-items: center;\n height: 100%;\n padding: 6px 0;\n display: none;\n position: relative;\n}\n\n.tab:first-child {\n border-left: none;\n}\n\n.tab.visible {\n display: inline-flex;\n}\n\n.tab.active {\n color: var(--tab-active-color);\n background: var(--tab-active-background);\n border-left: 1px solid var(--tab-border-color);\n border-right: 1px solid var(--tab-border-color);\n border: 1px var(--tab-border-color) solid;\n}\n\n.tab.active:last-child {\n border-right: none;\n}\n\n.tab.visible:not(.active) + .tab.visible:not(.active) {\n border-left: 1px solid var(--tab-border-color);\n}\n\n.tab:not(.active):hover {\n background: var(--tab-hover-background);\n color: var(--tab-hover-color);\n}\n\n.tab-title, .tab-close {\n margin-left: 10px;\n display: inline-block;\n}\n\n.tab-close button {\n background: var(--button-background);\n border-radius: var(--button-border-radius);\n color: var(--button-color);\n cursor: var(--button-cursor);\n font-size: var(--button-font-size);\n text-align: center;\n width: 26px;\n height: 26px;\n visibility: var(--close-button-visibility);\n border: none;\n margin-right: 4px;\n padding: 1px 0 0;\n display: inline-block;\n}\n\n.tab.active .tab-close button {\n visibility: visible;\n}\n\n.tab-close button:hover {\n color: var(--button-hover-color);\n background: var(--button-hover-background);\n}\n\n.buttons {\n border-left: 1px solid var(--tab-border-color);\n padding: 5px;\n display: flex;\n}\n\n.buttons button {\n color: var(--button-color);\n background: var(--button-background);\n border-radius: var(--button-border-radius);\n cursor: var(--button-cursor);\n font-size: var(--button-font-size);\n text-align: center;\n border: none;\n width: 20px;\n height: 20px;\n margin: 0;\n padding: 1px 0 0;\n font-family: inherit;\n line-height: 1;\n display: block;\n}\n\n.buttons button:hover {\n color: var(--button-hover-color);\n background: var(--button-hover-background);\n}\n\n.views {\n height: calc(100vh - 41px);\n position: relative;\n}\n";
|
||||||
|
|
||||||
|
|
||||||
if (!document) throw Error("electron-tabs module must be called in renderer process");
|
if (!document) throw Error("Electron Tabs(electron-tabs) module must be called in renderer process");
|
||||||
const $eda442ba39f881a8$var$CLASSNAMES = {
|
const $eda442ba39f881a8$var$CLASSNAMES = {
|
||||||
ROOT: "etabs",
|
ROOT: "etabs",
|
||||||
NAV: "nav",
|
NAV: "nav",
|
||||||
|
@ -2813,11 +2813,8 @@ class $eda442ba39f881a8$var$TabGroup extends HTMLElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class $eda442ba39f881a8$var$Tab extends EventTarget {
|
class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
badge;
|
|
||||||
closable;
|
closable;
|
||||||
element;
|
element;
|
||||||
icon;
|
|
||||||
iconURL;
|
|
||||||
id;
|
id;
|
||||||
isClosed;
|
isClosed;
|
||||||
isReady;
|
isReady;
|
||||||
|
@ -2828,10 +2825,7 @@ class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
webviewAttributes;
|
webviewAttributes;
|
||||||
constructor(tabGroup, id, args){
|
constructor(tabGroup, id, args){
|
||||||
super();
|
super();
|
||||||
this.badge = args.badge;
|
|
||||||
this.closable = args.closable === false ? false : true;
|
this.closable = args.closable === false ? false : true;
|
||||||
this.icon = args.icon;
|
|
||||||
this.iconURL = args.iconURL;
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
this.isReady = false;
|
this.isReady = false;
|
||||||
|
@ -2861,9 +2855,7 @@ class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
const tab = this.element = document.createElement("div");
|
const tab = this.element = document.createElement("div");
|
||||||
tab.classList.add($eda442ba39f881a8$var$CLASSNAMES.TAB);
|
tab.classList.add($eda442ba39f881a8$var$CLASSNAMES.TAB);
|
||||||
for (let el of [
|
for (let el of [
|
||||||
"icon",
|
|
||||||
"title",
|
"title",
|
||||||
"badge",
|
|
||||||
"close"
|
"close"
|
||||||
]){
|
]){
|
||||||
const span = tab.appendChild(document.createElement("span"));
|
const span = tab.appendChild(document.createElement("span"));
|
||||||
|
@ -2871,8 +2863,6 @@ class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
this.spans[el] = span;
|
this.spans[el] = span;
|
||||||
}
|
}
|
||||||
this.setTitle(this.title);
|
this.setTitle(this.title);
|
||||||
this.setBadge(this.badge);
|
|
||||||
this.setIcon(this.iconURL, this.icon);
|
|
||||||
this.initTabCloseButton();
|
this.initTabCloseButton();
|
||||||
this.initTabClickHandler();
|
this.initTabClickHandler();
|
||||||
this.tabGroup.tabContainer.appendChild(this.element);
|
this.tabGroup.tabContainer.appendChild(this.element);
|
||||||
|
@ -2908,13 +2898,6 @@ class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
this.emit("webview-ready", this);
|
this.emit("webview-ready", this);
|
||||||
};
|
};
|
||||||
this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);
|
this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);
|
||||||
const tabWebviewDomReadyHandler = function(e) {
|
|
||||||
// Remove this once https://github.com/electron/electron/issues/14474 is fixed
|
|
||||||
webview.blur();
|
|
||||||
webview.focus();
|
|
||||||
this.emit("webview-dom-ready", this);
|
|
||||||
};
|
|
||||||
this.webview.addEventListener("dom-ready", tabWebviewDomReadyHandler.bind(this), false);
|
|
||||||
this.webview.classList.add($eda442ba39f881a8$var$CLASSNAMES.VIEW);
|
this.webview.classList.add($eda442ba39f881a8$var$CLASSNAMES.VIEW);
|
||||||
if (this.webviewAttributes) {
|
if (this.webviewAttributes) {
|
||||||
const attrs = this.webviewAttributes;
|
const attrs = this.webviewAttributes;
|
||||||
|
@ -2939,40 +2922,6 @@ class $eda442ba39f881a8$var$Tab extends EventTarget {
|
||||||
if (this.isClosed) return;
|
if (this.isClosed) return;
|
||||||
return this.title;
|
return this.title;
|
||||||
}
|
}
|
||||||
setBadge(badge) {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
const span = this.spans.badge;
|
|
||||||
this.badge = badge;
|
|
||||||
if (badge) {
|
|
||||||
span.innerHTML = badge.text;
|
|
||||||
span.classList.add(badge.classname);
|
|
||||||
span.classList.remove("hidden");
|
|
||||||
} else span.classList.add("hidden");
|
|
||||||
this.emit("badge-changed", badge, this);
|
|
||||||
}
|
|
||||||
getBadge() {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
return this.badge;
|
|
||||||
}
|
|
||||||
setIcon(iconURL, icon) {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
this.iconURL = iconURL;
|
|
||||||
this.icon = icon;
|
|
||||||
const span = this.spans.icon;
|
|
||||||
if (iconURL) {
|
|
||||||
span.innerHTML = `<img src="${iconURL}" />`;
|
|
||||||
this.emit("icon-changed", iconURL, this);
|
|
||||||
} else if (icon) {
|
|
||||||
span.innerHTML = `<i class="${icon}"></i>`;
|
|
||||||
this.emit("icon-changed", icon, this);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
getIcon() {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
if (this.iconURL) return this.iconURL;
|
|
||||||
return this.icon;
|
|
||||||
}
|
|
||||||
setPosition(newPosition) {
|
setPosition(newPosition) {
|
||||||
const tabContainer = this.tabGroup.tabContainer;
|
const tabContainer = this.tabGroup.tabContainer;
|
||||||
const length = tabContainer.childElementCount;
|
const length = tabContainer.childElementCount;
|
||||||
|
|
2
dist/electron-tabs.js.map
vendored
2
dist/electron-tabs.js.map
vendored
File diff suppressed because one or more lines are too long
BIN
image.jpg
BIN
image.jpg
Binary file not shown.
Before Width: | Height: | Size: 155 KiB |
BIN
image.png
Normal file
BIN
image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@sudovanilla/electron-tabs",
|
"name": "@sudovanilla/electron-tabs",
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"description": "Simple tabs for Electron applications",
|
"description": "Simple tabs for Electron applications",
|
||||||
"main": "dist/electron-tabs.js",
|
"main": "dist/electron-tabs.js",
|
||||||
"types": "dist/electron-tabs.d.ts",
|
"types": "dist/electron-tabs.d.ts",
|
||||||
|
|
80
src/index.ts
80
src/index.ts
|
@ -3,7 +3,7 @@ import Sortable from "sortablejs";
|
||||||
import styles from "bundle-text:./style.css";
|
import styles from "bundle-text:./style.css";
|
||||||
|
|
||||||
if (!document) {
|
if (!document) {
|
||||||
throw Error("electron-tabs module must be called in renderer process");
|
throw Error("Electron Tabs(electron-tabs) module must be called in renderer process");
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TabGroupOptions {
|
interface TabGroupOptions {
|
||||||
|
@ -18,10 +18,7 @@ interface TabGroupOptions {
|
||||||
|
|
||||||
interface TabOptions {
|
interface TabOptions {
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
badge?: Badge;
|
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
icon?: string;
|
|
||||||
iconURL?: string;
|
|
||||||
ready?: ((tab: Tab) => void);
|
ready?: ((tab: Tab) => void);
|
||||||
src?: string;
|
src?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
@ -29,11 +26,6 @@ interface TabOptions {
|
||||||
webviewAttributes?: { [key: string]: any };
|
webviewAttributes?: { [key: string]: any };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Badge {
|
|
||||||
text: string,
|
|
||||||
classname: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const CLASSNAMES = {
|
const CLASSNAMES = {
|
||||||
ROOT: "etabs",
|
ROOT: "etabs",
|
||||||
NAV: "nav",
|
NAV: "nav",
|
||||||
|
@ -116,7 +108,7 @@ class TabGroup extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
private createComponent() {
|
private createComponent() {
|
||||||
const shadow = this.attachShadow({mode: "open"});
|
const shadow = this.attachShadow({ mode: "open" });
|
||||||
this.shadow = shadow;
|
this.shadow = shadow;
|
||||||
|
|
||||||
const wrapper = document.createElement("div");
|
const wrapper = document.createElement("div");
|
||||||
|
@ -278,11 +270,8 @@ class TabGroup extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Tab extends EventTarget {
|
class Tab extends EventTarget {
|
||||||
badge: Badge;
|
|
||||||
closable: boolean;
|
closable: boolean;
|
||||||
element: HTMLDivElement;
|
element: HTMLDivElement;
|
||||||
icon: string;
|
|
||||||
iconURL: string;
|
|
||||||
id: number;
|
id: number;
|
||||||
isClosed: boolean;
|
isClosed: boolean;
|
||||||
isReady: boolean;
|
isReady: boolean;
|
||||||
|
@ -294,10 +283,7 @@ class Tab extends EventTarget {
|
||||||
|
|
||||||
constructor(tabGroup: TabGroup, id: number, args: TabOptions) {
|
constructor(tabGroup: TabGroup, id: number, args: TabOptions) {
|
||||||
super();
|
super();
|
||||||
this.badge = args.badge;
|
|
||||||
this.closable = args.closable === false ? false : true;
|
this.closable = args.closable === false ? false : true;
|
||||||
this.icon = args.icon;
|
|
||||||
this.iconURL = args.iconURL;
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.isClosed = false;
|
this.isClosed = false;
|
||||||
this.isReady = false;
|
this.isReady = false;
|
||||||
|
@ -335,15 +321,13 @@ class Tab extends EventTarget {
|
||||||
private initTab() {
|
private initTab() {
|
||||||
const tab = this.element = document.createElement("div");
|
const tab = this.element = document.createElement("div");
|
||||||
tab.classList.add(CLASSNAMES.TAB);
|
tab.classList.add(CLASSNAMES.TAB);
|
||||||
for (let el of ["icon", "title", "badge", "close"]) {
|
for (let el of ["title", "close"]) {
|
||||||
const span = tab.appendChild(document.createElement("span"));
|
const span = tab.appendChild(document.createElement("span"));
|
||||||
span.classList.add(`${CLASSNAMES.TAB}-${el}`);
|
span.classList.add(`${CLASSNAMES.TAB}-${el}`);
|
||||||
this.spans[el] = span;
|
this.spans[el] = span;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setTitle(this.title);
|
this.setTitle(this.title);
|
||||||
this.setBadge(this.badge);
|
|
||||||
this.setIcon(this.iconURL, this.icon);
|
|
||||||
this.initTabCloseButton();
|
this.initTabCloseButton();
|
||||||
this.initTabClickHandler();
|
this.initTabClickHandler();
|
||||||
|
|
||||||
|
@ -361,7 +345,7 @@ class Tab extends EventTarget {
|
||||||
|
|
||||||
private initTabClickHandler() {
|
private initTabClickHandler() {
|
||||||
// Mouse up
|
// Mouse up
|
||||||
const tabClickHandler = function(e: KeyboardEvent) {
|
const tabClickHandler = function (e: KeyboardEvent) {
|
||||||
if (this.isClosed) return;
|
if (this.isClosed) return;
|
||||||
if (e.which === 2) {
|
if (e.which === 2) {
|
||||||
this.close();
|
this.close();
|
||||||
|
@ -369,7 +353,7 @@ class Tab extends EventTarget {
|
||||||
};
|
};
|
||||||
this.element.addEventListener("mouseup", tabClickHandler.bind(this), false);
|
this.element.addEventListener("mouseup", tabClickHandler.bind(this), false);
|
||||||
// Mouse down
|
// Mouse down
|
||||||
const tabMouseDownHandler = function(e: KeyboardEvent) {
|
const tabMouseDownHandler = function (e: KeyboardEvent) {
|
||||||
if (this.isClosed) return;
|
if (this.isClosed) return;
|
||||||
if (e.which === 1) {
|
if (e.which === 1) {
|
||||||
if ((e.target as HTMLElement).matches("button")) return;
|
if ((e.target as HTMLElement).matches("button")) return;
|
||||||
|
@ -382,21 +366,12 @@ class Tab extends EventTarget {
|
||||||
initWebview() {
|
initWebview() {
|
||||||
const webview = this.webview = document.createElement("webview");
|
const webview = this.webview = document.createElement("webview");
|
||||||
|
|
||||||
const tabWebviewDidFinishLoadHandler = function(e: Event) {
|
const tabWebviewDidFinishLoadHandler = function (e: Event) {
|
||||||
this.emit("webview-ready", this);
|
this.emit("webview-ready", this);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);
|
this.webview.addEventListener("did-finish-load", tabWebviewDidFinishLoadHandler.bind(this), false);
|
||||||
|
|
||||||
const tabWebviewDomReadyHandler = function(e: Event) {
|
|
||||||
// Remove this once https://github.com/electron/electron/issues/14474 is fixed
|
|
||||||
webview.blur();
|
|
||||||
webview.focus();
|
|
||||||
this.emit("webview-dom-ready", this);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.webview.addEventListener("dom-ready", tabWebviewDomReadyHandler.bind(this), false);
|
|
||||||
|
|
||||||
this.webview.classList.add(CLASSNAMES.VIEW);
|
this.webview.classList.add(CLASSNAMES.VIEW);
|
||||||
if (this.webviewAttributes) {
|
if (this.webviewAttributes) {
|
||||||
const attrs = this.webviewAttributes;
|
const attrs = this.webviewAttributes;
|
||||||
|
@ -425,49 +400,6 @@ class Tab extends EventTarget {
|
||||||
return this.title;
|
return this.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
setBadge(badge?: Badge) {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
const span = this.spans.badge;
|
|
||||||
this.badge = badge;
|
|
||||||
|
|
||||||
if (badge) {
|
|
||||||
span.innerHTML = badge.text;
|
|
||||||
span.classList.add(badge.classname);
|
|
||||||
span.classList.remove("hidden");
|
|
||||||
} else {
|
|
||||||
span.classList.add("hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit("badge-changed", badge, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBadge() {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
return this.badge;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIcon(iconURL: string, icon: string) {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
this.iconURL = iconURL;
|
|
||||||
this.icon = icon;
|
|
||||||
const span = this.spans.icon;
|
|
||||||
if (iconURL) {
|
|
||||||
span.innerHTML = `<img src="${iconURL}" />`;
|
|
||||||
this.emit("icon-changed", iconURL, this);
|
|
||||||
} else if (icon) {
|
|
||||||
span.innerHTML = `<i class="${icon}"></i>`;
|
|
||||||
this.emit("icon-changed", icon, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
getIcon() {
|
|
||||||
if (this.isClosed) return;
|
|
||||||
if (this.iconURL) return this.iconURL;
|
|
||||||
return this.icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
setPosition(newPosition: number) {
|
setPosition(newPosition: number) {
|
||||||
const tabContainer = this.tabGroup.tabContainer;
|
const tabContainer = this.tabGroup.tabContainer;
|
||||||
const length = tabContainer.childElementCount;
|
const length = tabContainer.childElementCount;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
--tab-background: #E7EAED;
|
--tab-background: #E7EAED;
|
||||||
--tab-color: #696A6C;
|
--tab-color: #696A6C;
|
||||||
--tab-border-color: #DADCE0;
|
--tab-border-color: #DADCE0;
|
||||||
|
--tab-border-radius: 4px;
|
||||||
--tab-transition: background-color 200ms ease-out, color 200ms ease-out;
|
--tab-transition: background-color 200ms ease-out, color 200ms ease-out;
|
||||||
--tab-cursor: pointer;
|
--tab-cursor: pointer;
|
||||||
--tab-active-color: currentcolor;
|
--tab-active-color: currentcolor;
|
||||||
|
@ -19,10 +20,8 @@
|
||||||
--button-color: #696A6C;
|
--button-color: #696A6C;
|
||||||
--button-hover-background: #DADCE0;
|
--button-hover-background: #DADCE0;
|
||||||
--button-hover-color: #383a3e;
|
--button-hover-color: #383a3e;
|
||||||
--button-border-radius: 50%;
|
--button-border-radius: 4px;
|
||||||
--button-cursor: pointer;
|
--button-cursor: pointer;
|
||||||
--badge-background: #383a3e;
|
|
||||||
--badge-color: #fff;
|
|
||||||
--close-button-visibility: visible;
|
--close-button-visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,15 +47,15 @@ webview.visible {
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
background: var(--tabgroup-background);
|
background: var(--tabgroup-background);
|
||||||
box-shadow: inset 0 -1px var(--tab-border-color);
|
|
||||||
border-top: 1px solid var(--tab-border-color);
|
border-top: 1px solid var(--tab-border-color);
|
||||||
font-size: var(--tab-font-size);
|
font-size: var(--tab-font-size);
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: calc(100% - 16px);
|
||||||
height: 32px;
|
height: 32px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
padding: 4px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav.visible {
|
.nav.visible {
|
||||||
|
@ -65,20 +64,23 @@ webview.visible {
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
background: var(--tab-background);
|
background: var(--tab-background);
|
||||||
box-shadow: inset 0 -1px var(--tab-border-color);
|
border: 1px var(--tab-border-color) solid;
|
||||||
color: var(--tab-color);
|
color: var(--tab-color);
|
||||||
cursor: var(--tab-cursor);
|
cursor: var(--tab-cursor);
|
||||||
font-size: var(--tab-font-size);
|
font-size: var(--tab-font-size);
|
||||||
transition: var(--tab-transition);
|
transition: var(--tab-transition);
|
||||||
|
border-radius: var(--tab-border-radius);
|
||||||
display: none;
|
display: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 5px 9px;
|
padding: 6px 0px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,9 +97,7 @@ webview.visible {
|
||||||
background: var(--tab-active-background);
|
background: var(--tab-active-background);
|
||||||
border-left: 1px solid var(--tab-border-color);
|
border-left: 1px solid var(--tab-border-color);
|
||||||
border-right: 1px solid var(--tab-border-color);
|
border-right: 1px solid var(--tab-border-color);
|
||||||
padding-left: 8px;
|
border: 1px var(--tab-border-color) solid;
|
||||||
padding-right: 8px;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab.active:last-child {
|
.tab.active:last-child {
|
||||||
|
@ -106,7 +106,6 @@ webview.visible {
|
||||||
|
|
||||||
.tab.visible:not(.active)+.tab.visible:not(.active) {
|
.tab.visible:not(.active)+.tab.visible:not(.active) {
|
||||||
border-left: 1px solid var(--tab-border-color);
|
border-left: 1px solid var(--tab-border-color);
|
||||||
padding-left: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab:not(.active):hover {
|
.tab:not(.active):hover {
|
||||||
|
@ -114,32 +113,6 @@ webview.visible {
|
||||||
color: var(--tab-hover-color);
|
color: var(--tab-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-badge {
|
|
||||||
background: var(--badge-background);
|
|
||||||
color: var(--badge-color);
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-left: 5px;
|
|
||||||
padding: 1px 4px;
|
|
||||||
font-size: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-badge.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-icon {
|
|
||||||
display: inline-block;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-icon img {
|
|
||||||
max-width: 16px;
|
|
||||||
max-height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-title {
|
.tab-title {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
@ -158,11 +131,12 @@ webview.visible {
|
||||||
font-size: var(--button-font-size);
|
font-size: var(--button-font-size);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: none;
|
border: none;
|
||||||
width: 20px;
|
width: 26px;
|
||||||
height: 20px;
|
height: 26px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 1px 0 0 0;
|
padding: 1px 0 0 0;
|
||||||
visibility: var(--close-button-visibility);
|
visibility: var(--close-button-visibility);
|
||||||
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab.active .tab-close button {
|
.tab.active .tab-close button {
|
||||||
|
@ -204,5 +178,5 @@ webview.visible {
|
||||||
|
|
||||||
.views {
|
.views {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100vh - 33px);
|
height: calc(100vh - 41px);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue