Full Code of zyra/ionic2-super-tabs for AI

master e4882248a025 cached
77 files
133.4 KB
36.1k tokens
153 symbols
1 requests
Download .txt
Repository: zyra/ionic2-super-tabs
Branch: master
Commit: e4882248a025
Files: 77
Total size: 133.4 KB

Directory structure:
gitextract_r57jfzom/

├── .dockerignore
├── .docs.yaml
├── .doctemplate
├── .drone.yml
├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .gitignore
├── CHANGELOG.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── angular/
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── angular.json
│   ├── ng-package.json
│   ├── package.json
│   ├── rollup.config.js
│   ├── rollup.config.legacy.js
│   ├── src/
│   │   ├── app-init.ts
│   │   ├── directives/
│   │   │   ├── proxies-list.txt
│   │   │   ├── proxies-utils.ts
│   │   │   └── proxies.ts
│   │   ├── public-api.ts
│   │   └── super-tabs.module.ts
│   ├── tsconfig.json
│   ├── tsconfig.legacy.json
│   ├── tsconfig.lib.json
│   ├── tsconfig.lib.prod.json
│   └── tslint.json
├── core/
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── package.json
│   ├── src/
│   │   ├── components.d.ts
│   │   ├── index.ts
│   │   ├── interface.d.ts
│   │   ├── mixins.scss
│   │   ├── super-tab/
│   │   │   ├── readme.md
│   │   │   ├── super-tab.component.scss
│   │   │   └── super-tab.component.tsx
│   │   ├── super-tab-button/
│   │   │   ├── readme.md
│   │   │   ├── super-tab-button.component.scss
│   │   │   └── super-tab-button.component.tsx
│   │   ├── super-tab-indicator/
│   │   │   ├── readme.md
│   │   │   ├── super-tab-indicator.component.scss
│   │   │   └── super-tab-indicator.component.tsx
│   │   ├── super-tabs/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs.component.scss
│   │   │   └── super-tabs.component.tsx
│   │   ├── super-tabs-container/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs-container.component.scss
│   │   │   └── super-tabs-container.component.tsx
│   │   ├── super-tabs-toolbar/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs-toolbar.component.scss
│   │   │   └── super-tabs-toolbar.component.tsx
│   │   ├── utils.ts
│   │   └── variables.scss
│   ├── stencil.config.ts
│   └── tsconfig.json
├── doc-pages/
│   ├── configuration.md
│   ├── getting-started/
│   │   └── angular.md
│   ├── home.md
│   └── usage/
│       └── angular.md
├── lerna.json
├── package.json
├── react/
│   ├── .gitignore
│   ├── package.json
│   ├── rollup.config.js
│   ├── src/
│   │   ├── components.ts
│   │   ├── index.ts
│   │   └── react-component-lib/
│   │       ├── createComponent.tsx
│   │       ├── createControllerComponent.tsx
│   │       ├── createOverlayComponent.tsx
│   │       ├── index.ts
│   │       └── utils/
│   │           ├── attachEventProps.ts
│   │           └── index.tsx
│   └── tsconfig.json
└── super-tabs.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
.git
.idea
Dockerfile
.docs.yaml
.drone.yml
.gitignore
README.md
super-tabs.sh
docs
node_modules
core/node_modules
core/dist
core/loader
core/hydrate
core/.stencil
angular/node_modules
angular/dist
react/node_modules
react/dist
react/dist-transpiled


================================================
FILE: .docs.yaml
================================================
siteTitle: Super Tabs
description: Swipeable tabs for Ionic apps
repo: https://github.com/zyra/ionic-super-tabs
outDir: docs
baseUrl: https://zyra.github.io/ionic-super-tabs/

pagePatterns:
- name: '{{ index .PathMatches 0 1 }}'
  sourceGlob: core/src/**/readme.md
  pattern: '([a-z-]+)/readme.md$'
  path: 'components/{{ index .PathMatches 0 1 }}'
  editOnGithub: true
  addToMenu: true
  menuGroup: components

pages:
- name: home
  title: Super Tabs - Swipeable tabs for Ionic apps
  path: /
  source: doc-pages/home.md
  editOnGithub: true
- name: config
  title: Configuration
  path: configuration
  source: doc-pages/configuration.md
  editOnGithub: true
- name: install-ng
  title: Getting started with Angular
  path: getting-started/angular
  source: doc-pages/getting-started/angular.md
  editOnGithub: true
- name: usage-ng
  title: Angular Usage Guide
  path: usage/angular
  source: doc-pages/usage/angular.md
  editOnGithub: true


menuItems:
- title: Getting started
  name: getting-started
  group: true
  items:
  - title: Introduction
  - title: Angular
    link: getting-started/angular
#  - title: JavaScript
#    link: getting-started/javascript

- title: Configuration
  link: configuration

- title: Usage guide
  name: usage-guide
  group: true
  items:
  - title: Angular
    link: usage/angular

- title: Components
  name: components
  group: true

templates:
- name: base
  source: .doctemplate


================================================
FILE: .doctemplate
================================================
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{- .Title }}</title>
    {{ if .Description }}<meta name="description" content="{{ .Description }}">{{ end }}
    {{ if .BaseURL }}<base href="{{ .BaseURL }}" />{{ end }}
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism-tomorrow.min.css" integrity="sha256-xevuwyBEb2ZYh4nDhj0g3Z/rDBnM569hg9Vq6gEw/Sg=" crossorigin="anonymous" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="theme-color" content="#fafafa">
    <style>
    h1, h2, h3, h4, h5, h6, p, div, code {
      -webkit-font-smoothing: auto;
      -moz-osx-font-smoothing: auto;
    }

    h1 {
      font-size: 2rem;
      font-weight: 600;
      line-height: 3rem;
      color: rgba(102, 126, 234, 0.6);
      margin-bottom: 2rem;
    }

    h2 {
      font-size: 1.2rem;
      line-height: 1.4rem;
      text-transform: uppercase;
      margin-top: 3rem;
      font-weight: 600;
      color: rgba(95, 128, 187, 0.8);
    }

    h4 {
        font-size: 1rem;
        line-height: 1.2rem;
        text-transform: uppercase;
        margin-top: 1rem;
        font-weight: 600;
        color: rgba(63, 93, 150, 0.99);
    }

    h4 + p {
      padding-top: 0.4rem;
    }

    p {
      padding-top: 1rem;
      font-size: 1rem;
      line-height: 1.4rem;
      letter-spacing: 0.07rem;
      max-width: 600px;
      text-align: justify;
      color: rgba(0,0,0,0.87);
    }

    p code, table code {
        background: rgb(45, 45, 45);
        color: #ffb5b7;
        padding: 2px 8px;
        word-break: break-all;
        letter-spacing: normal;
        display: inline-block;
    }

    a {
      color: #6470dc;
    }

    a:hover {
      color: #4659ff;
    }

    table {
        background: rgba(0,0,0,0.01);
        margin: 1rem 0;
        width: 100%;
        max-width: 100%;
        overflow-y: auto;
    }

    thead {

    }

    thead tr {

    }

    thead tr th {
      padding: 1rem 0.5rem;
      background: rgba(0,0,0,0.03);
      color: rgba(0,0,0,0.67);
    }

    thead tr th:not(:last-child), tbody tr td:not(:last-child) {
      border-right: 1px solid rgba(0,0,0,0.15);
    }

    thead tr, tbody tr:not(:last-child) {
      border-bottom: 1px solid rgba(0,0,0,0.15);
    }

    tbody {

    }

    tbody tr {

    }

    tbody tr td {
      padding: 0.5rem;
    }

    #graph, #graph + pre, #dependencies, #depends-on, #depends-on + ul {
      display: none;
    }

    hr {
      margin-top: 3rem;
    }

    #properties + table tbody tr td:nth-child(3) {
      width: 40%;
    }

    #events + table tbody tr td:nth-child(2) {
      width: 48%;
    }

    </style>
</head>
<body>
<nav role="navigation">
    <div class="container flex items-center justify-between flex-wrap p-6 mx-auto">
        <div class="flex items-center flex-shrink-0 text-indigo-500 mr-6">
            <span class="font-semibold text-xl tracking-tight">
                {{ .SiteTitle }}
            </span>
        </div>
        <div class="block">
            <button id="sidenav-open-button" class="inline lg:hidden flex items-center px-3 py-2 text-indigo-400 hover:text-indigo-500">
                <svg class="fill-current h-5 w-5" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
            </button>
            <button id="sidenav-close-button" class="flex items-center px-3 py-2 text-indigo-400 hover:text-indigo-500 hidden">
                <svg class="fill-current w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"></path></svg>
            </button>
        </div>
    </div>
</nav>
<div class="container mx-auto">
    <div class="flex">
        <nav class="w-full lg:w-1/4 p-6 hidden lg:block" id="sidenav" role="navigation">
            <ul class="list-reset" role="none">
{{- range $index, $element := .MenuItems }}
	{{- if $element.Group }}
				<li role="none" class="my-1">
					<span class="font-semibold text-gray-400">{{ $element.Title }}</span>
					<ul class="list-reset ml-1" role="none">
						{{- range $ci, $ce := $element.Items }}
							<li role="none">
								<a href="{{ $ce.Link }}" role="link" aria-label="{{ $ce.Title }}" class="block p-1 {{ if $ce.Active }}text-indigo-600{{ else }}text-gray-600 hover:text-gray-700{{ end }}">{{ $ce.Title }}</a>
							</li>
						{{- end }}
					</ul>
				</li>
	{{- else }}
				<li role="none" class="my=1">
					<a href="{{ $element.Link }}" role="link" aria-label="{{ $element.Title }}" class="block py-1 pr-1 {{ if $element.Active }}text-indigo-600{{ else }}text-gray-600 hover:text-gray-700{{ end }}">{{ $element.Title }}</a>
				</li>
	{{- end }}
{{- end }}
            </ul>
        </nav>
        <div class="w-full lg:w-3/4 p-6" id="content-container">
		{{ .Content }}
        </div>
    </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/prism.js" integrity="sha256-hFhFKoZ+mZTEMFJc8FQyuDDHVB1x9v+rJRu3DelyOHQ=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-typescript.js" integrity="sha256-pDpItYLMSApStvqbBe51zq9wIgBkVM81OWNH2pqL3mQ=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-shell-session.min.js" integrity="sha256-Jy8oX8yb4vOF1XXD4omkL5QRBb1wxSC8A0Ck9En8fa8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/components/prism-bash.js" integrity="sha256-iAZZqWH4eVQeSza3X25jRVetUoFVIWqF/YYVyFJl9R0=" crossorigin="anonymous"></script>
<script>
    (function () {
        const openButton = document.getElementById('sidenav-open-button');
        const closeButton  = document.getElementById('sidenav-close-button');
        const sidenav = document.getElementById('sidenav');
        const container = document.getElementById('content-container');

        openButton.addEventListener('click', () => {
            sidenav.classList.replace('hidden', 'block');
            container.classList.add('hidden');
            openButton.classList.add('hidden');
            closeButton.classList.remove('hidden');
        });

        closeButton.addEventListener('click', () => {
            sidenav.classList.replace('block', 'hidden');
            container.classList.remove('hidden');
            openButton.classList.remove('hidden');
            closeButton.classList.add('hidden');
        });
    })();
</script>
</body>
</html>


================================================
FILE: .drone.yml
================================================
---
kind: pipeline
type: docker
name: default

clone:
  depth: 1

volumes:
- name: dockersock
  host:
    path: /var/run/docker.sock

steps:
- name: Fast build
  image: docker
  when:
    event:
      exclude:
      - tag
  volumes:
  - name: dockersock
    path: /var/run/docker.sock
  commands:
  - docker build .

- name: Build
  image: node:12
  when:
    event:
    - tag
  commands:
  - npm i
  - ./super-tabs.sh setup
  - ./super-tabs.sh build

- name: Publish
  image: node:12
  when:
    event:
    - tag
  environment:
    NPM_TOKEN:
      from_secret: npm_token
  commands:
    - echo '//registry.npmjs.org/:_authToken=$${NPM_TOKEN}' > ~/.npmrc
    - ./super-tabs.sh publish

- name: Generate docs
  image: harbor.zyra.ca/public/zmdocs:v1.1.0
  when:
    branch:
    - master
  commands:
  - zmdocs g

- name: Publish docs
  image: plugins/gh-pages
  when:
    event:
      exclude:
      - pull_request
    branch:
    - master
  settings:
    username:
      from_secret: gh_user
    password:
      from_secret: gh_token
    pages_directory: docs

#- name: Update example project
#  image: plugins/downstream
#  settings:
#    server: https://drone.zyra.ca
#    token:
#      from_secret: drone_token
#    repositories:
#    - zyra/ionic-super-tabs-example
#    fork: true

---
kind: signature
hmac: 325be6f79fe9c33c34d9376df0ffce76ae06e1e831666c434bdfa2c45837b85b

...


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .gitignore
================================================
node_modules
.idea
.DS_STORE
docs


================================================
FILE: CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [6.0.5](https://github.com/zyra/ionic-super-tabs/compare/v6.0.4...v6.0.5) (2019-11-13)


### Bug Fixes

* **super-tabs:** allow usage without a toolbar ([5247db7](https://github.com/zyra/ionic-super-tabs/commit/5247db7ba79c0e401e91878e78a9cc9c2763532e))


================================================
FILE: Dockerfile
================================================
FROM node:12-alpine
COPY . .
RUN npm i
RUN npx lerna bootstrap
RUN npm run build


================================================
FILE: LICENSE.md
================================================
MIT License

Copyright (c) 2019 Zyra Media Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Super Tabs
Swipeable tabs module for Ionic apps.

* [Packages](#packages)
  * [Ionic 4](#ionic-4)
  * [Ionic 2 / Ionic 3](#ionic-2--ionic-3)
* [Documentation](https://zyra.github.io/ionic-super-tabs)
  * Getting started
    * [Angular](https://zyra.github.io/ionic-super-tabs/getting-started/angular)
    * JavaScript - WIP
  * Usage guide
    * [Angular](https://zyra.github.io/ionic-super-tabs/usage/angular)
    * JavaScript - WIP
  * [Configuration](https://zyra.github.io/ionic-super-tabs/configuration)
* [Example Project](https://github.com/zyra/ionic-super-tabs-example)
* [Notes](#notes)
* [License](#license)

---

## Packages

#### Ionic 4
Packages published under the `@ionic-super-tabs/` scope are compatible with `@ionic/angular@^4.0.0` _(4.0.0 and above)_.

> @ionic-super-tabs/core
>
> ![npm (scoped)](https://img.shields.io/npm/v/@ionic-super-tabs/core?style=flat-square)
> ![npm](https://img.shields.io/npm/dt/@ionic-super-tabs/core?style=flat-square)
> ![npm](https://img.shields.io/npm/dm/@ionic-super-tabs/core?style=flat-square)
>
>
> @ionic-super-tabs/angular
>
> ![npm (scoped)](https://img.shields.io/npm/v/@ionic-super-tabs/angular?style=flat-square)
> ![npm](https://img.shields.io/npm/dt/@ionic-super-tabs/angular?style=flat-square)
> ![npm](https://img.shields.io/npm/dm/@ionic-super-tabs/angular?style=flat-square)

#### Ionic 2 / Ionic 3
For Ionic 2 / Ionic 3 apps, see the [v5 branch](https://github.com/zyra/ionic-super-tabs/tree/v5) for the previous version of Super Tabs.

> ionic2-super-tabs
>
> ![npm](https://img.shields.io/npm/v/ionic2-super-tabs?label=ionic2-super-tabs)
> ![npm](https://img.shields.io/npm/dt/ionic2-super-tabs?style=flat-square)
> ![npm](https://img.shields.io/npm/dm/ionic2-super-tabs?style=flat-square)

---

## Notes
This module has been tested with Angular and Stencil based apps only. 
Compatibility with React and Vue has not been tested yet.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details


================================================
FILE: angular/.gitignore
================================================
build
node_modules
dist


================================================
FILE: angular/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [6.0.5](https://github.com/zyra/ionic-super-tabs/compare/v6.0.4...v6.0.5) (2019-11-13)

**Note:** Version bump only for package @ionic-super-tabs/angular


================================================
FILE: angular/angular.json
================================================
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "super-tabs": {
      "projectType": "library",
      "root": "",
      "sourceRoot": "src",
      "prefix": "super",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-ng-packagr:build",
          "options": {
            "tsConfig": "tsconfig.lib.json",
            "project": "ng-package.json"
          },
          "configurations": {
            "production": {
              "tsConfig": "tsconfig.lib.prod.json"
            }
          }
        }
      }
    }},
  "defaultProject": "super-tabs"
}


================================================
FILE: angular/ng-package.json
================================================
{
  "$schema": "./node_modules/ng-packagr/ng-package.schema.json",
  "dest": "./dist/",
  "lib": {
    "entryFile": "src/public-api.ts"
  },
  "whitelistedNonPeerDependencies": [
    "@ionic-super-tabs/core"
  ]
}


================================================
FILE: angular/package.json
================================================
{
  "name": "@ionic-super-tabs/angular",
  "version": "7.0.8",
  "description": "Ionic Super Tabs bindings for Angular applications",
  "scripts": {
    "build": "ng build",
    "prebuild": "npm run clean",
    "test": "ng test",
    "clean": "rm -rf dist"
  },
  "author": "Zyra Media Inc. <info@zyra.ca>",
  "license": "MIT",
  "dependencies": {
    "@ionic-super-tabs/core": "^7.0.8"
  },
  "keywords": [
    "ionic",
    "swipeable",
    "tabs",
    "module",
    "component",
    "angular"
  ],
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.901.8",
    "@angular-devkit/build-ng-packagr": "~0.901.8",
    "@angular-devkit/core": "~9.1.8",
    "@angular-devkit/schematics": "~9.1.8",
    "@angular/cli": "~9.1.8",
    "@angular/common": "~9.1.11",
    "@angular/compiler": "~9.1.11",
    "@angular/compiler-cli": "~9.1.11",
    "@angular/core": "~9.1.11",
    "@angular/forms": "~9.1.11",
    "@angular/platform-browser": "~9.1.11",
    "@angular/platform-browser-dynamic": "~9.1.11",
    "@angular/router": "~9.1.11",
    "@types/node": "~14.0.13",
    "fs-extra": "~9.0.1",
    "glob": "~7.1.6",
    "ng-packagr": "~9.1.5",
    "rxjs": "~6.5.5",
    "tsickle": "~0.38.1",
    "tslint": "~5.15.0",
    "typescript": "~3.8.3",
    "zone.js": "~0.10.3"
  }
}


================================================
FILE: angular/rollup.config.js
================================================
import resolve from 'rollup-plugin-node-resolve';

export default {
  input: 'build/es2015/core.js',
  output: [
    {
      file: 'dist/fesm2015.js',
      format: 'es',
    },
  ],
  external: (id) => {
    // anything else is external
    // Windows: C:\xxxxxx\xxx
    const colonPosition = 1;
    return !(id.startsWith('.') || id.startsWith('/') || id.charAt(colonPosition) === ':');
  },
  plugins: [
    resolve({
      module: true,
    }),
  ],
};


================================================
FILE: angular/rollup.config.legacy.js
================================================
import config from './rollup.config';

const newConfig = {
  ...config,
  input: 'build/es5/core.js',
};

newConfig.output = [
  {
    file: 'dist/fesm5.js',
    format: 'es'
  },
  {
    file: 'dist/fesm5.cjs.js',
    format: 'cjs'
  }
];

export { newConfig as default };


================================================
FILE: angular/src/app-init.ts
================================================
import { NgZone } from '@angular/core';
import { applyPolyfills, defineCustomElements } from '@ionic-super-tabs/core/loader';


let didInitialize = false;

export function appInit(doc: Document, zone: NgZone) {
  return async function () {

    const win: any = doc.defaultView as any;


    if (!win || didInitialize) {
      return;
    }

    didInitialize = true;

    const aelFn = '__zone_symbol__addEventListener' in (doc.body as any)
      ? '__zone_symbol__addEventListener'
      : 'addEventListener';


    await applyPolyfills();

    await defineCustomElements(win, {
      syncQueue: true,
      raf,
      jmp: (h: any) => zone.runOutsideAngular(h),
      ael(elm, eventName, cb, opts) {
        (elm as any)[aelFn](eventName, cb, opts);
      },
      rel(elm, eventName, cb, opts) {
        elm.removeEventListener(eventName, cb, opts);
      },
    });
  };
};

declare const __zone_symbol__requestAnimationFrame: any;
declare const requestAnimationFrame: any;

export const raf = (h: any) => {
  if (typeof __zone_symbol__requestAnimationFrame === 'function') {
    return __zone_symbol__requestAnimationFrame(h);
  }
  if (typeof requestAnimationFrame === 'function') {
    return requestAnimationFrame(h);
  }
  return setTimeout(h);
};


================================================
FILE: angular/src/directives/proxies-list.txt
================================================

import * as d from './proxies';

export const DIRECTIVES = [
d.SuperTab,
  d.SuperTabButton,
  d.SuperTabs,
  d.SuperTabsContainer,
  d.SuperTabsToolbar
];


================================================
FILE: angular/src/directives/proxies-utils.ts
================================================
/* tslint:disable */
import { fromEvent } from 'rxjs';

export const proxyInputs = (Cmp: any, inputs: string[]) => {
  const Prototype = Cmp.prototype;
  inputs.forEach(item => {
    Object.defineProperty(Prototype, item, {
      get() { return this.el[item]; },
      set(val: any) { this.z.runOutsideAngular(() => (this.el[item] = val)); }
    });
  });
};

export const proxyMethods = (Cmp: any, methods: string[]) => {
  const Prototype = Cmp.prototype;
  methods.forEach(methodName => {
    Prototype[methodName] = function () {
      const args = arguments;
      return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
    };
  });
};

export const proxyOutputs = (instance: any, el: any, events: string[]) => {
  events.forEach(eventName => instance[eventName] = fromEvent(el, eventName));
}

// tslint:disable-next-line: only-arrow-functions
export function ProxyCmp(opts: { inputs?: any; methods?: any }) {
  const decorator =  function(cls: any){
    if (opts.inputs) {
      proxyInputs(cls, opts.inputs);
    }
    if (opts.methods) {
      proxyMethods(cls, opts.methods);
    }
    return cls;
  };
  return decorator;
}


================================================
FILE: angular/src/directives/proxies.ts
================================================
/* tslint:disable */
/* auto-generated angular directive proxies */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, NgZone } from '@angular/core';
import { ProxyCmp, proxyOutputs } from './proxies-utils';

import { Components } from '@ionic-super-tabs/core'

export declare interface SuperTab extends Components.SuperTab {}
@ProxyCmp({inputs: ['loaded', 'noScroll', 'visible'], 'methods': ['getRootScrollableEl']})
@Component({ selector: 'super-tab', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['loaded', 'noScroll', 'visible'] })
export class SuperTab {
  protected el: HTMLElement;
  constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
    c.detach();
    this.el = r.nativeElement;
  }
}

export declare interface SuperTabButton extends Components.SuperTabButton {}
@ProxyCmp({inputs: ['disabled']})
@Component({ selector: 'super-tab-button', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['disabled'] })
export class SuperTabButton {
  protected el: HTMLElement;
  constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
    c.detach();
    this.el = r.nativeElement;
  }
}

export declare interface SuperTabs extends Components.SuperTabs {}
@ProxyCmp({inputs: ['activeTabIndex', 'config'], 'methods': ['setConfig', 'selectTab']})
@Component({ selector: 'super-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['activeTabIndex', 'config'] })
export class SuperTabs {
  tabChange!: EventEmitter<CustomEvent>;
  protected el: HTMLElement;
  constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
    c.detach();
    this.el = r.nativeElement;
    proxyOutputs(this, this.el, ['tabChange']);
  }
}

export declare interface SuperTabsContainer extends Components.SuperTabsContainer {}
@ProxyCmp({inputs: ['autoScrollTop', 'swipeEnabled'], 'methods': ['scrollToTop']})
@Component({ selector: 'super-tabs-container', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['autoScrollTop', 'swipeEnabled'] })
export class SuperTabsContainer {
  activeTabIndexChange!: EventEmitter<CustomEvent>;
  selectedTabIndexChange!: EventEmitter<CustomEvent>;
  protected el: HTMLElement;
  constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
    c.detach();
    this.el = r.nativeElement;
    proxyOutputs(this, this.el, ['activeTabIndexChange', 'selectedTabIndexChange']);
  }
}

export declare interface SuperTabsToolbar extends Components.SuperTabsToolbar {}
@ProxyCmp({inputs: ['color', 'scrollable', 'scrollablePadding', 'showIndicator']})
@Component({ selector: 'super-tabs-toolbar', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', inputs: ['color', 'scrollable', 'scrollablePadding', 'showIndicator'] })
export class SuperTabsToolbar {
  buttonClick!: EventEmitter<CustomEvent>;
  protected el: HTMLElement;
  constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
    c.detach();
    this.el = r.nativeElement;
    proxyOutputs(this, this.el, ['buttonClick']);
  }
}


================================================
FILE: angular/src/public-api.ts
================================================
export * from './directives/proxies';
export { SuperTabsModule } from './super-tabs.module';


================================================
FILE: angular/src/super-tabs.module.ts
================================================
import { CommonModule, DOCUMENT } from '@angular/common';
import { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZone } from '@angular/core';
import { appInit } from './app-init';
import { SuperTab, SuperTabButton, SuperTabs, SuperTabsContainer, SuperTabsToolbar } from './directives/proxies';

export const DECLARATIONS = [
  SuperTab,
  SuperTabButton,
  SuperTabs,
  SuperTabsContainer,
  SuperTabsToolbar,
];

@NgModule({
  declarations: DECLARATIONS,
  exports: DECLARATIONS,
  imports: [CommonModule],
})
export class SuperTabsModule {
  static forRoot(): ModuleWithProviders<SuperTabsModule> {
    return {
      ngModule: SuperTabsModule,
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: appInit,
          multi: true,
          deps: [DOCUMENT, NgZone],
        },
      ],
    };
  }
}


================================================
FILE: angular/tsconfig.json
================================================
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "super-tabs": [
        "dist/super-tabs"
      ],
      "super-tabs/*": [
        "dist/super-tabs/*"
      ]
    }
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true,
    "enableIvy": false
  }
}


================================================
FILE: angular/tsconfig.legacy.json
================================================
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "target": "es5",
    "declarationDir": "build/es5",
    "outDir": "build/es5"
  }
}


================================================
FILE: angular/tsconfig.lib.json
================================================
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/lib",
    "target": "es2015",
    "declaration": true,
    "inlineSources": true,
    "types": [],
    "lib": [
      "dom",
      "es2018"
    ]
  },
  "angularCompilerOptions": {
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "enableResourceInlining": true
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}


================================================
FILE: angular/tsconfig.lib.prod.json
================================================
{
  "extends": "./tsconfig.lib.json",
  "angularCompilerOptions": {
    "enableIvy": false
  }
}


================================================
FILE: angular/tslint.json
================================================
{
  "extends": "tslint:recommended",
  "rulesDirectory": [
    "codelyzer"
  ],
  "rules": {
    "array-type": false,
    "arrow-parens": false,
    "deprecation": {
      "severity": "warning"
    },
    "import-blacklist": [
      true,
      "rxjs/Rx"
    ],
    "interface-name": false,
    "max-classes-per-file": false,
    "max-line-length": [
      true,
      140
    ],
    "member-access": false,
    "member-ordering": [
      true,
      {
        "order": [
          "static-field",
          "instance-field",
          "static-method",
          "instance-method"
        ]
      }
    ],
    "no-consecutive-blank-lines": false,
    "no-console": [
      true,
      "debug",
      "info",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-empty": false,
    "no-inferrable-types": [
      true,
      "ignore-params"
    ],
    "no-non-null-assertion": true,
    "no-redundant-jsdoc": true,
    "no-switch-case-fall-through": true,
    "no-var-requires": false,
    "object-literal-key-quotes": [
      true,
      "as-needed"
    ],
    "object-literal-sort-keys": false,
    "ordered-imports": false,
    "quotemark": [
      true,
      "single"
    ],
    "trailing-comma": false,
    "component-class-suffix": true,
    "contextual-lifecycle": true,
    "directive-class-suffix": true,
    "no-conflicting-lifecycle": true,
    "no-host-metadata-property": true,
    "no-input-rename": true,
    "no-inputs-metadata-property": true,
    "no-output-native": true,
    "no-output-on-prefix": true,
    "no-output-rename": true,
    "no-outputs-metadata-property": true,
    "template-banana-in-box": true,
    "template-no-negated-async": true,
    "use-lifecycle-interface": true,
    "use-pipe-transform-interface": true
  }
}


================================================
FILE: core/.gitignore
================================================
node_modules
dist
stats.json
.stencil
loader
hydrate


================================================
FILE: core/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [6.0.5](https://github.com/zyra/ionic-super-tabs/compare/v6.0.4...v6.0.5) (2019-11-13)


### Bug Fixes

* **super-tabs:** allow usage without a toolbar ([5247db7](https://github.com/zyra/ionic-super-tabs/commit/5247db7ba79c0e401e91878e78a9cc9c2763532e))


================================================
FILE: core/package.json
================================================
{
  "name": "@ionic-super-tabs/core",
  "version": "7.0.8",
  "description": "",
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "es2015": "dist/esm/index.mjs",
  "es2017": "dist/esm/index.mjs",
  "jsnext:main": "dist/esm/index.mjs",
  "collection:main": "dist/collection/index.js",
  "collection": "dist/collection/collection-manifest.json",
  "types": "dist/types/interface.d.ts",
  "files": [
    "dist/",
    "loader/",
    "hydrate/"
  ],
  "scripts": {
    "build": "stencil build"
  },
  "keywords": [
    "ionic",
    "swipeable",
    "tabs",
    "module",
    "component"
  ],
  "author": "Zyra Media Inc.",
  "license": "MIT",
  "devDependencies": {
    "@ionic/core": "~5.2.1",
    "@stencil/angular-output-target": "0.0.2",
    "@stencil/core": "~1.14.0",
    "@stencil/react-output-target": "0.0.6",
    "@stencil/sass": "~1.3.1"
  }
}


================================================
FILE: core/src/components.d.ts
================================================
/* eslint-disable */
/* tslint:disable */
/**
 * This is an autogenerated file created by the Stencil compiler.
 * It contains typing information for all components that exist in this project.
 */
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { SuperTabChangeEventDetail, SuperTabsConfig } from "./interface";
export namespace Components {
    interface SuperTab {
        /**
          * Returns the root scrollable element
         */
        "getRootScrollableEl": () => Promise<HTMLElement | null>;
        "loaded": boolean;
        /**
          * Set this to true to prevent vertical scrolling of this tab. Defaults to `false`.  This property will automatically be set to true if there is a direct child element of `ion-content`. To override this behaviour make sure to explicitly set this property to `false`.
         */
        "noScroll": boolean;
        "visible": boolean;
    }
    interface SuperTabButton {
        "active"?: boolean;
        /**
          * Whether the button is disabled
         */
        "disabled"?: boolean;
        "index"?: number;
        "scrollableContainer": boolean;
    }
    interface SuperTabIndicator {
        /**
          * Toolbar position This determines the position of the indicator
         */
        "toolbarPosition": 'top' | 'bottom';
    }
    interface SuperTabs {
        /**
          * Initial active tab index. Defaults to `0`.
          * @type {number}
         */
        "activeTabIndex": number;
        /**
          * Global Super Tabs configuration.  This is the only place you need to configure the components. Any changes to this input will propagate to child components.
          * @type {SuperTabsConfig}
         */
        "config"?: SuperTabsConfig;
        /**
          * Set the selected tab. This will move the container and the toolbar to the selected tab.
          * @param index the index of the tab you want to select
          * @param animate whether you want to animate the transition
          * @param emit whether you want to emit tab change event
         */
        "selectTab": (index: number, animate?: boolean, emit?: boolean) => Promise<void>;
        /**
          * Set/update the configuration
          * @param config Configuration object
         */
        "setConfig": (config: SuperTabsConfig) => Promise<void>;
    }
    interface SuperTabsContainer {
        /**
          * Set to true to automatically scroll to the top of the tab when the button is clicked while the tab is already selected.
         */
        "autoScrollTop": boolean;
        "config"?: SuperTabsConfig;
        /**
          * @param scrollX
          * @param animate
         */
        "moveContainer": (scrollX: number, animate?: boolean | undefined) => Promise<void>;
        /**
          * @param index Index of the tab
          * @param animate Whether to animate the transition
         */
        "moveContainerByIndex": (index: number, animate?: boolean | undefined) => Promise<void>;
        "reindexTabs": () => Promise<void>;
        /**
          * Scroll the active tab to the top.
         */
        "scrollToTop": () => Promise<void>;
        "setActiveTabIndex": (index: number, moveContainer?: boolean, animate?: boolean) => Promise<void>;
        /**
          * Enable/disable swiping
         */
        "swipeEnabled": boolean;
    }
    interface SuperTabsToolbar {
        /**
          * Background color. Defaults to `'primary'`
         */
        "color": string | undefined;
        "config"?: SuperTabsConfig;
        "moveContainer": (scrollX: number, animate?: boolean | undefined) => Promise<void>;
        /**
          * Whether the toolbar is scrollable. Defaults to `false`.
         */
        "scrollable": boolean;
        /**
          * If scrollable is set to true, there will be an added padding to the left of the buttons.  Setting this property to false will remove that padding.  The padding is also configurable via a CSS variable.
         */
        "scrollablePadding": boolean;
        "setActiveTab": (index: number, align?: boolean | undefined, animate?: boolean | undefined) => Promise<void>;
        "setSelectedTab": (index: number, animate?: boolean | undefined) => Promise<void>;
        /**
          * Whether to show the indicator. Defaults to `true`
         */
        "showIndicator": boolean;
    }
}
declare global {
    interface HTMLSuperTabElement extends Components.SuperTab, HTMLStencilElement {
    }
    var HTMLSuperTabElement: {
        prototype: HTMLSuperTabElement;
        new (): HTMLSuperTabElement;
    };
    interface HTMLSuperTabButtonElement extends Components.SuperTabButton, HTMLStencilElement {
    }
    var HTMLSuperTabButtonElement: {
        prototype: HTMLSuperTabButtonElement;
        new (): HTMLSuperTabButtonElement;
    };
    interface HTMLSuperTabIndicatorElement extends Components.SuperTabIndicator, HTMLStencilElement {
    }
    var HTMLSuperTabIndicatorElement: {
        prototype: HTMLSuperTabIndicatorElement;
        new (): HTMLSuperTabIndicatorElement;
    };
    interface HTMLSuperTabsElement extends Components.SuperTabs, HTMLStencilElement {
    }
    var HTMLSuperTabsElement: {
        prototype: HTMLSuperTabsElement;
        new (): HTMLSuperTabsElement;
    };
    interface HTMLSuperTabsContainerElement extends Components.SuperTabsContainer, HTMLStencilElement {
    }
    var HTMLSuperTabsContainerElement: {
        prototype: HTMLSuperTabsContainerElement;
        new (): HTMLSuperTabsContainerElement;
    };
    interface HTMLSuperTabsToolbarElement extends Components.SuperTabsToolbar, HTMLStencilElement {
    }
    var HTMLSuperTabsToolbarElement: {
        prototype: HTMLSuperTabsToolbarElement;
        new (): HTMLSuperTabsToolbarElement;
    };
    interface HTMLElementTagNameMap {
        "super-tab": HTMLSuperTabElement;
        "super-tab-button": HTMLSuperTabButtonElement;
        "super-tab-indicator": HTMLSuperTabIndicatorElement;
        "super-tabs": HTMLSuperTabsElement;
        "super-tabs-container": HTMLSuperTabsContainerElement;
        "super-tabs-toolbar": HTMLSuperTabsToolbarElement;
    }
}
declare namespace LocalJSX {
    interface SuperTab {
        "loaded"?: boolean;
        /**
          * Set this to true to prevent vertical scrolling of this tab. Defaults to `false`.  This property will automatically be set to true if there is a direct child element of `ion-content`. To override this behaviour make sure to explicitly set this property to `false`.
         */
        "noScroll": boolean;
        "visible"?: boolean;
    }
    interface SuperTabButton {
        "active"?: boolean;
        /**
          * Whether the button is disabled
         */
        "disabled"?: boolean;
        "index"?: number;
        "scrollableContainer"?: boolean;
    }
    interface SuperTabIndicator {
        /**
          * Toolbar position This determines the position of the indicator
         */
        "toolbarPosition"?: 'top' | 'bottom';
    }
    interface SuperTabs {
        /**
          * Initial active tab index. Defaults to `0`.
          * @type {number}
         */
        "activeTabIndex"?: number;
        /**
          * Global Super Tabs configuration.  This is the only place you need to configure the components. Any changes to this input will propagate to child components.
          * @type {SuperTabsConfig}
         */
        "config"?: SuperTabsConfig;
        /**
          * Tab change event.  This event fires up when a tab button is clicked, or when a user swipes between tabs.  The event will fire even if the tab did not change, you can check if the tab changed by checking the `changed` property in the event detail.
         */
        "onTabChange"?: (event: CustomEvent<SuperTabChangeEventDetail>) => void;
    }
    interface SuperTabsContainer {
        /**
          * Set to true to automatically scroll to the top of the tab when the button is clicked while the tab is already selected.
         */
        "autoScrollTop"?: boolean;
        "config"?: SuperTabsConfig;
        /**
          * Emits an event when the active tab changes. An active tab is the tab that the user looking at.  This event emitter will not notify you if the user has changed the current active tab. If you need that information, you should use the `tabChange` event emitted by the `super-tabs` element.
         */
        "onActiveTabIndexChange"?: (event: CustomEvent<number>) => void;
        /**
          * Emits events when the container moves. Selected tab index represents what the user should be seeing. If you receive a decimal as the emitted number, it means that the container is moving between tabs. This number is used for animations, and can be used for high tab customizations.
         */
        "onSelectedTabIndexChange"?: (event: CustomEvent<number>) => void;
        /**
          * Enable/disable swiping
         */
        "swipeEnabled"?: boolean;
    }
    interface SuperTabsToolbar {
        /**
          * Background color. Defaults to `'primary'`
         */
        "color"?: string | undefined;
        "config"?: SuperTabsConfig;
        /**
          * Emits an event when a button is clicked Event data contains the clicked SuperTabButton component
         */
        "onButtonClick"?: (event: CustomEvent<HTMLSuperTabButtonElement>) => void;
        /**
          * Whether the toolbar is scrollable. Defaults to `false`.
         */
        "scrollable"?: boolean;
        /**
          * If scrollable is set to true, there will be an added padding to the left of the buttons.  Setting this property to false will remove that padding.  The padding is also configurable via a CSS variable.
         */
        "scrollablePadding"?: boolean;
        /**
          * Whether to show the indicator. Defaults to `true`
         */
        "showIndicator"?: boolean;
    }
    interface IntrinsicElements {
        "super-tab": SuperTab;
        "super-tab-button": SuperTabButton;
        "super-tab-indicator": SuperTabIndicator;
        "super-tabs": SuperTabs;
        "super-tabs-container": SuperTabsContainer;
        "super-tabs-toolbar": SuperTabsToolbar;
    }
}
export { LocalJSX as JSX };
declare module "@stencil/core" {
    export namespace JSX {
        interface IntrinsicElements {
            "super-tab": LocalJSX.SuperTab & JSXBase.HTMLAttributes<HTMLSuperTabElement>;
            "super-tab-button": LocalJSX.SuperTabButton & JSXBase.HTMLAttributes<HTMLSuperTabButtonElement>;
            "super-tab-indicator": LocalJSX.SuperTabIndicator & JSXBase.HTMLAttributes<HTMLSuperTabIndicatorElement>;
            "super-tabs": LocalJSX.SuperTabs & JSXBase.HTMLAttributes<HTMLSuperTabsElement>;
            "super-tabs-container": LocalJSX.SuperTabsContainer & JSXBase.HTMLAttributes<HTMLSuperTabsContainerElement>;
            "super-tabs-toolbar": LocalJSX.SuperTabsToolbar & JSXBase.HTMLAttributes<HTMLSuperTabsToolbarElement>;
        }
    }
}


================================================
FILE: core/src/index.ts
================================================
export { DEFAULT_CONFIG } from './utils';
export { SuperTabsConfig } from './interface';


================================================
FILE: core/src/interface.d.ts
================================================
export * from './components';

/**
 * Configuration object for the `super-tabs` component.
 */
export interface SuperTabsConfig {
  /**
   * Max drag angle in degrees.
   *
   * Defaults to `40`
   */
  maxDragAngle?: number;

  /**
   * Drag threshold in pixels.
   *
   * This value defines how far the user have to swipe for the swipe to be treated as a swipe gesture.
   *
   * Defaults to `20`
   */
  dragThreshold?: number;

  /**
   * Allows elements inside tabs to be dragged or scrolled through.
   *
   * Setting this value to `true` will allow touch events to be propagated to child components.
   *
   * Defaults to `false`.
   */
  allowElementScroll?: boolean;

  /**
   * Transition duration in milliseconds.
   *
   * This value is used for all transitions and animations.
   *
   * Defaults to `150`.
   */
  transitionDuration?: number;

  /**
   * Side menu location.
   *
   * If this value is set to `right` or `left`, the super tabs component will avoid listening to swipe events
   * in the specified region(s) to avoid interfering with a side menu event listeners.
   *
   * Defaults to `undefined`.
   */
  sideMenu?: 'left' | 'right' | 'both';

  /**
   * Side menu threshold in pixels.
   *
   * Defaults to `50`.
   */
  sideMenuThreshold?: number;

  /**
   * Short swipe duration in milliseconds.
   *
   * Short swipe is when a user quickly swipes between tabs. If the swipe duration is less than or equal to this
   * configured value, then we assume that the user wants to switch tabs.
   * To disable this behaviour set this value to `0`.
   *
   * Defaults to `300`
   */
  shortSwipeDuration?: number;

  /**
   * Enable debug mode.
   * Defaults to `false`.
   */
  debug?: boolean;

  /**
   * Whether the container should look and avoid elements with avoid-super-tabs attribute
   */
  avoidElements?: boolean;

  nativeSmoothScroll?: boolean;

  lazyLoad?: boolean;
  unloadWhenInvisible?: boolean;
}

/**
 * Event detail emitted by the `tabChange` event from the `super-tabs` component.
 */
export interface SuperTabChangeEventDetail {
  /**
   * Selected tab index.
   */
  index: number;

  /**
   * Indicates whether the tab index has changed.
   */
  changed: boolean;
}



================================================
FILE: core/src/mixins.scss
================================================
@import "./variables";

@mixin st-button-variables() {
  --st-base-color-active: #{$st-button-base-color-active};
  --st-base-color-inactive: #{$st-button-base-color-inactive};

  --st-icon-size: #{$st-button-icon-size};
  --st-icon-color-inactive: #{$st-button-icon-color-inactive};
  --st-icon-color-active: #{$st-button-icon-color-active};

  --st-label-line-height: #{$st-button-label-line-height};
  --st-label-height: #{$st-button-label-height};
  --st-label-font-size: #{$st-button-label-font-size};
  --st-label-text-transform: #{$st-button-label-text-transform};
  --st-label-font-weight: #{$st-button-label-font-weight};
  --st-label-padding-bottom: #{$st-button-label-padding-bottom};
  --st-label-color-inactive: #{$st-button-label-color-inactive};
  --st-label-color-active: #{$st-button-label-color-active};
}

@mixin st-tab-variables() {
  --super-tab-width: #{$st-width};
  --super-tab-height: #{$st-height};
}

@mixin st-indicator-variables() {
  --st-indicator-height: #{$st-indicator-height};
  --st-indicator-color: #{$st-indicator-color};
}

@mixin st-toolbar-variables() {
  --st-scrollable-toolbar-padding-left: #{$st-scrollable-toolbar-padding-left};
  --super-tabs-toolbar-background: #{$st-toolbar-background};
}


================================================
FILE: core/src/super-tab/readme.md
================================================
# super-tab



<!-- Auto Generated Below -->


## Properties

| Property                | Attribute   | Description                                                                                                                                                                                                                                                             | Type      | Default     |
| ----------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ----------- |
| `loaded`                | `loaded`    |                                                                                                                                                                                                                                                                         | `boolean` | `false`     |
| `noScroll` _(required)_ | `no-scroll` | Set this to true to prevent vertical scrolling of this tab. Defaults to `false`.  This property will automatically be set to true if there is a direct child element of `ion-content`. To override this behaviour make sure to explicitly set this property to `false`. | `boolean` | `undefined` |
| `visible`               | `visible`   |                                                                                                                                                                                                                                                                         | `boolean` | `false`     |


## Methods

### `getRootScrollableEl() => Promise<HTMLElement | null>`

Returns the root scrollable element

#### Returns

Type: `Promise<HTMLElement | null>`




## CSS Custom Properties

| Name                 | Description                            |
| -------------------- | -------------------------------------- |
| `--super-tab-height` | Height of the tab. Defaults to `100%`. |
| `--super-tab-width`  | Width of the tab. Defaults to `100vw`. |


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tab/super-tab.component.scss
================================================
@import "../variables";

:host {
  /**
  * @prop --super-tab-width: Width of the tab. Defaults to `100vw`.
  * @prop --super-tab-height: Height of the tab. Defaults to `100%`.
  */

  height: var(--super-tab-height, $st-height);
  position: relative;
  display: block;
  overflow-x: hidden;
  overflow-y: auto;
  contain: size style;

  &[noScroll] {
    overflow-y: hidden;
  }

  z-index: 1;
  flex-shrink: 0;
  flex-grow: 0;
  width: var(--super-tab-width, $st-width);
  transform: translate3d(0,0,0);
  box-sizing: border-box;
  order: -1;

  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-font-smoothing: antialiased;
}

ion-nav, ion-content {
  height: 100%;
  max-height: 100%;
  position: absolute;

  > .ion-page {
    position: absolute;
  }
}


================================================
FILE: core/src/super-tab/super-tab.component.tsx
================================================
import { Component, ComponentInterface, Element, h, Host, Method, Prop } from '@stencil/core';


@Component({
  tag: 'super-tab',
  styleUrl: 'super-tab.component.scss',
  shadow: true,
  scoped: false,
})
export class SuperTabComponent implements ComponentInterface {
  @Element() el!: HTMLSuperTabElement;

  /**
   * Set this to true to prevent vertical scrolling of this tab. Defaults to `false`.
   *
   * This property will automatically be set to true if there is
   * a direct child element of `ion-content`. To override this
   * behaviour make sure to explicitly set this property to `false`.
   */
  @Prop({
    reflect: true,
  }) noScroll!: boolean;

  @Prop() loaded = false;
  @Prop() visible = false;

  componentDidLoad() {
    this.checkIonContent();
  }

  componentDidUpdate() {
    // check for ion-content after update, in case it was dynamically loaded
    this.checkIonContent();
  }

  /**
   * Check if we have an ion-content as a child and update the `noScroll` property
   * if it's not set yet.
   */
  private checkIonContent() {
    if (typeof this.noScroll !== 'boolean') {
      const ionContentEl = this.el.querySelector('ion-content');

      if (ionContentEl && ionContentEl.parentElement === this.el) {
        this.noScroll = true;
      }
    }
  }

  /**
   * Returns the root scrollable element
   */
  @Method()
  async getRootScrollableEl(): Promise<HTMLElement | null> {
    if (!this.noScroll && this.el.scrollHeight > this.el.clientHeight) {
      return this.el;
    }

    const ionContent: any = this.el.querySelector('ion-content');

    if (ionContent) {
      return ionContent.getScrollElement();
    }

    if (this.noScroll) {
      return null;
    }

    return this.el;
  }

  render() {
    return <Host style={{ visibility: this.visible ? 'visible' : 'hidden' }}>
      {
        this.loaded ? <slot></slot> : null
      }
    </Host>;
  }
}


================================================
FILE: core/src/super-tab-button/readme.md
================================================
# super-tab-button



<!-- Auto Generated Below -->


## Properties

| Property   | Attribute  | Description                    | Type                   | Default     |
| ---------- | ---------- | ------------------------------ | ---------------------- | ----------- |
| `disabled` | `disabled` | Whether the button is disabled | `boolean \| undefined` | `undefined` |


## CSS Custom Properties

| Name                        | Description                                                                             |
| --------------------------- | --------------------------------------------------------------------------------------- |
| `--st-base-color-active`    | base color for active buttons. Defaults to `--ion-color-contrast`.                      |
| `--st-base-color-inactive`  | base color for inactive buttons. Defaults to `rgba(var(--ion-color-contrast-rgb), 0.7)` |
| `--st-icon-color-active`    | active icon color. Defaults to `var(--st-base-color-active)`                            |
| `--st-icon-color-inactive`  | inactive icon color. Defaults to `var(--st-base-color-inactive)`                        |
| `--st-icon-size`            | icon size. Defaults to `24px`.                                                          |
| `--st-label-color-active`   | active label color. Defaults to `var(--st-base-color-active)`                           |
| `--st-label-color-inactive` | inactive label color. Defaults to `var(--st-base-color-inactive)`                       |
| `--st-label-font-size`      | Font size of the label. Defaults to `14px`.                                             |
| `--st-label-font-weight`    | Font weight of the label. Defaults to `500`                                             |
| `--st-label-height`         | label height. Defaults to `14px`                                                        |
| `--st-label-line-height`    | label line height. Defaults to `14px`                                                   |
| `--st-label-padding-bottom` | label padding bottom. Defaults to `16px`                                                |
| `--st-label-text-transform` | Text transformation to apply to the label text. Defaults to `uppercase`.                |


----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tab-button/super-tab-button.component.scss
================================================
@import "../variables";

@mixin labelIcon {
  ion-label, ion-icon, ::slotted(ion-label), ::slotted(ion-icon) {
    @content
  }
}

@mixin label {
  ion-label, ::slotted(ion-label) {
    @content
  }
}

@mixin icon {
  ion-icon, ::slotted(ion-icon) {
    @content
  }
}

:host {
  /**
   * @prop --st-base-color-active: base color for active buttons. Defaults to `--ion-color-contrast`.
   * @prop --st-base-color-inactive: base color for inactive buttons. Defaults to `rgba(var(--ion-color-contrast-rgb), 0.7)`
   * @prop --st-icon-size: icon size. Defaults to `24px`.
   * @prop --st-icon-color-inactive: inactive icon color. Defaults to `var(--st-base-color-inactive)`
   * @prop --st-icon-color-active: active icon color. Defaults to `var(--st-base-color-active)`
   * @prop --st-label-line-height: label line height. Defaults to `14px`
   * @prop --st-label-height: label height. Defaults to `14px`
   * @prop --st-label-font-size: Font size of the label. Defaults to `14px`.
   * @prop --st-label-text-transform: Text transformation to apply to the label text. Defaults to `uppercase`.
   * @prop --st-label-font-weight: Font weight of the label. Defaults to `500`
   * @prop --st-label-padding-bottom: label padding bottom. Defaults to `16px`
   * @prop --st-label-color-inactive: inactive label color. Defaults to `var(--st-base-color-inactive)`
   * @prop --st-label-color-active: active label color. Defaults to `var(--st-base-color-active)`
   */

  flex: 1 0 0;
  cursor: pointer;
  position: relative;
  max-width: 100%;
  overflow: hidden;
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  transform: translate3d(0, 0, 0);
  height: 72px;
  padding: 0 24px;

  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-font-smoothing: antialiased;

  @include labelIcon {
    transition-property: all;
    transition-duration: 300ms;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-delay: 0s;
    box-sizing: content-box !important;
    -webkit-user-select: none;
    -webkit-text-size-adjust: none;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    -webkit-font-smoothing: antialiased;
  }

  @include label {
    color: var(--st-label-color-inactive, $st-button-label-color-inactive);
    line-height: var(--st-label-line-height, $st-button-label-line-height);
    height: var(--st-label-height, $st-button-label-height);
    font-size: var(--st-label-font-size, $st-button-label-font-size);
    text-transform: var(--st-label-text-transform, $st-button-label-text-transform);
    font-weight: var(--st-label-font-weight, $st-button-label-font-weight);
    padding-bottom: var(--st-label-padding-bottom, $st-button-label-padding-bottom);
  }

  @include icon {
    color: var(--st-icon-color-inactive, $st-button-icon-color-inactive);
    fill: var(--st-icon-color-inactive, $st-button-icon-color-inactive);
    min-height: var(--st-icon-size, $st-button-icon-size);
    min-width: var(--st-icon-size, $st-button-icon-size);
    font-size: var(--st-icon-size, $st-button-icon-size);
    padding-top: 12px;
  }
}

@media(hover: hover) {
  :host(:hover) {
    background: rgba(var(--ion-color-contrast-rgb), 0.04);
  }
}


:host(.active) {
  @include labelIcon {
    transition-delay: 75ms;
  }

  @include label {
    color: var(--st-label-color-active, $st-button-label-color-active);
  }

  @include icon {
    color: var(--st-icon-color-active, $st-button-label-color-active);
    fill: var(--st-icon-color-active, $st-button-label-color-active);
  }
}

:host(.icon-only), :host(.label-only) {
  height: 48px;
  justify-content: center;
}

:host(.scrollableContainer) {
  flex-grow: 0;
  flex-basis: auto;
  min-width: 90px;
  max-width: 360px;
}

::slotted {
  flex-shrink: 1;
}

:host(.label-only) {
  @include label {
    padding-bottom: 0;
  }
}

:host(.icon-only) {
  @include icon {
    padding-top: 0;
  }
}


================================================
FILE: core/src/super-tab-button/super-tab-button.component.tsx
================================================
import { Component, ComponentInterface, Element, h, Host, Prop, State } from '@stencil/core';


const maxRetryAttempts = 1e3;

@Component({
  tag: 'super-tab-button',
  styleUrl: 'super-tab-button.component.scss',
  shadow: true,
})
export class SuperTabButtonComponent implements ComponentInterface {
  @Element() el!: HTMLSuperTabButtonElement;

  /** @internal */
  @Prop({ reflectToAttr: true }) active?: boolean;

  /** @internal */
  @Prop({ reflectToAttr: true }) index?: number;

  /**
   * Whether the button is disabled
   */
  @Prop({ reflectToAttr: true }) disabled?: boolean;

  /** @internal */
  @Prop() scrollableContainer: boolean = false;

  @State() label!: HTMLElement | null;
  @State() icon!: HTMLElement | null;

  private retryAttempts: number = 0;

  componentDidLoad() {
    this.indexChildren();
    this.initCmp();
  }

  private initCmp() {
    if (!this.el || !this.el.shadowRoot) {
      if (++this.retryAttempts < maxRetryAttempts) {
        requestAnimationFrame(() => this.initCmp());
        return;
      }
    }

    if (!this.label && !this.icon) {
      this.indexChildren();
    }

    const slot = this.el!.shadowRoot!.querySelector('slot');
    slot!.addEventListener('slotchange', () => {
      this.indexChildren();
    });
  }

  private indexChildren() {
    this.label = this.el.querySelector('ion-label');
    this.icon = this.el.querySelector('ion-icon');
  }

  render() {
    return (
      <Host
        role="button"
        aria-label={this.label ? this.label.innerText : false}
        aria-disabled={this.disabled ? 'true' : false}
        aria-selected={this.active ? 'true' : 'false'}
        class={{
          'ion-activatable': true,
          'ion-focusable': true,
          'icon-only': !!this.icon && !this.label,
          'label-only': !!this.label && !this.icon,
          active: Boolean(this.active),
          scrollableContainer: this.scrollableContainer,
        }}>
        <slot/>
        <ion-ripple-effect type="unbounded"/>
      </Host>
    );
  }
}


================================================
FILE: core/src/super-tab-indicator/readme.md
================================================
# super-tab-indicator



<!-- Auto Generated Below -->


## Properties

| Property          | Attribute          | Description                                                    | Type                | Default |
| ----------------- | ------------------ | -------------------------------------------------------------- | ------------------- | ------- |
| `toolbarPosition` | `toolbar-position` | Toolbar position This determines the position of the indicator | `"bottom" \| "top"` | `'top'` |


## Dependencies

### Used by

 - [super-tabs-toolbar](../super-tabs-toolbar)

### Graph
```mermaid
graph TD;
  super-tabs-toolbar --> super-tab-indicator
  style super-tab-indicator fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tab-indicator/super-tab-indicator.component.scss
================================================
@import "../variables";

:host {
  display: block;
  height: var(--st-indicator-height, $st-indicator-height);
  width: 100px;
  background: var(--st-indicator-color, $st-indicator-color);
  position: absolute;
  pointer-events: none;
  touch-action: none;
  left: 0;
  transform-origin: 0;
  transform: translate3d(var(--st-indicator-position-x, 0), 0, 0) scale3d(var(--st-indicator-scale-x, 0), 1, 1);
  transition: transform var(--st-indicator-transition-duration, 300ms) cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
  box-sizing: border-box;
  order: -1;

  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-font-smoothing: antialiased;
}


================================================
FILE: core/src/super-tab-indicator/super-tab-indicator.component.tsx
================================================
import { Component, ComponentInterface, h, Host, Prop } from '@stencil/core';


@Component({
  tag: 'super-tab-indicator',
  styleUrl: 'super-tab-indicator.component.scss',
  shadow: true,
})
export class SuperTabIndicatorComponent implements ComponentInterface {

  /**
   * Toolbar position
   * This determines the position of the indicator
   */
  @Prop() toolbarPosition: 'top' | 'bottom' = 'top';

  render() {
    const style: any = {};

    if (this.toolbarPosition === 'bottom') {
      style.top = 0;
    } else {
      style.bottom = 0;
    }

    return (
      <Host style={style}/>
    );
  }
}


================================================
FILE: core/src/super-tabs/readme.md
================================================
# super-tabs



<!-- Auto Generated Below -->


## Properties

| Property         | Attribute          | Description                                                                                                                                                  | Type                           | Default     |
| ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------- |
| `activeTabIndex` | `active-tab-index` | Initial active tab index. Defaults to `0`.                                                                                                                   | `number`                       | `0`         |
| `config`         | --                 | Global Super Tabs configuration.  This is the only place you need to configure the components. Any changes to this input will propagate to child components. | `SuperTabsConfig \| undefined` | `undefined` |


## Events

| Event       | Description                                                                                                                                                                                                                                            | Type                                     |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| `tabChange` | Tab change event.  This event fires up when a tab button is clicked, or when a user swipes between tabs.  The event will fire even if the tab did not change, you can check if the tab changed by checking the `changed` property in the event detail. | `CustomEvent<SuperTabChangeEventDetail>` |


## Methods

### `selectTab(index: number, animate?: boolean, emit?: boolean) => Promise<void>`

Set the selected tab.
This will move the container and the toolbar to the selected tab.

#### Returns

Type: `Promise<void>`



### `setConfig(config: SuperTabsConfig) => Promise<void>`

Set/update the configuration

#### Returns

Type: `Promise<void>`




----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tabs/super-tabs.component.scss
================================================
:host {
  height: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 1;
  position: relative;
  contain: layout size style;
  order: -1;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-font-smoothing: antialiased;
  touch-action: none;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}


================================================
FILE: core/src/super-tabs/super-tabs.component.tsx
================================================
import {
  Component,
  ComponentInterface,
  Element,
  Event,
  EventEmitter,
  h,
  Host,
  Listen,
  Method,
  Prop,
  Watch,
} from '@stencil/core';
import { SuperTabChangeEventDetail, SuperTabsConfig } from '../interface';
import { debugLog, DEFAULT_CONFIG } from '../utils';


const maxInitRetries: number = 1e3;

/**
 * Root component that controls the other super-tab components.
 *
 * This component propagates configuration over to children and keeps track of the tabs state.
 */
@Component({
  tag: 'super-tabs',
  styleUrl: 'super-tabs.component.scss',
  shadow: true,
})
export class SuperTabsComponent implements ComponentInterface {
  @Element() el!: HTMLSuperTabsElement;

  /**
   * Tab change event.
   *
   * This event fires up when a tab button is clicked, or when a user swipes between tabs.
   *
   * The event will fire even if the tab did not change, you can check if the tab changed by checking the `changed`
   * property in the event detail.
   */
  @Event() tabChange!: EventEmitter<SuperTabChangeEventDetail>;

  /**
   * Global Super Tabs configuration.
   *
   * This is the only place you need to configure the components. Any changes to this input will propagate to child
   * components.
   *
   * @type {SuperTabsConfig}
   */
  @Prop() config?: SuperTabsConfig;

  /**
   * Initial active tab index.
   * Defaults to `0`.
   *
   * @type {number}
   */
  @Prop({ reflectToAttr: true, mutable: true }) activeTabIndex: number = 0;

  private container!: HTMLSuperTabsContainerElement;
  private toolbar!: HTMLSuperTabsToolbarElement;
  private _config: SuperTabsConfig = DEFAULT_CONFIG;
  private initAttempts: number = 0;
  private readonly initPromise: Promise<void>;
  private initPromiseResolve!: Function;

  constructor() {
    this.initPromise = new Promise<void>((resolve) => {
      this.initPromiseResolve = resolve;
    });
  }

  /**
   * Set/update the configuration
   * @param {SuperTabsConfig} config Configuration object
   */
  @Method()
  async setConfig(config: SuperTabsConfig) {
    this._config = { ...DEFAULT_CONFIG, ...config };
  }

  private propagateConfig() {
    this.container && (this.container.config = this._config);
    this.toolbar && (this.toolbar.config = this._config);
  }

  /**
   * Set the selected tab.
   * This will move the container and the toolbar to the selected tab.
   * @param index {number} the index of the tab you want to select
   * @param [animate=true] {boolean} whether you want to animate the transition
   * @param [emit=true] {boolean} whether you want to emit tab change event
   */
  @Method()
  async selectTab(index: number, animate: boolean = true, emit: boolean = true) {
    this.debug('selectTab', index, animate);

    await this.initPromise;

    const lastIndex = this.activeTabIndex;

    if (this.container) {
      await this.container.setActiveTabIndex(index, true, animate);
    }

    if (this.toolbar) {
      await this.toolbar.setActiveTab(index, true, animate);
    }

    if (emit) {
      this.emitTabChangeEvent(index, lastIndex);
    }

    this.activeTabIndex = lastIndex;
  }

  @Watch('config')
  async onConfigChange(config: SuperTabsConfig) {
    await this.setConfig(config);
  }

  @Listen('resize', { target: 'window', capture: false, passive: true })
  onWindowResize() {
    this.debug('onWindowResize');
    this.toolbar && this.toolbar.setSelectedTab(this.activeTabIndex);
    this.container.reindexTabs();
  }

  async componentWillLoad() {
    if (this.config) {
      await this.setConfig(this.config);
    }
  }

  componentDidLoad() {
    this.debug('componentDidLoad');

    // index children
    this.indexChildren();

    // set the selected tab so the toolbar & container are aligned and in sync
    if (this.container) {
      this.container.setActiveTabIndex(this.activeTabIndex, true, false);
    }

    if (this.toolbar) {
      this.toolbar.setActiveTab(this.activeTabIndex, true, false);
    }

    // listen to `slotchange` event to detect any changes in children
    this.el.shadowRoot!.addEventListener('slotchange', this.onSlotchange.bind(this));

    requestAnimationFrame(() => {
      this.initComponent();
    });
  }

  private initComponent() {
    if (!this.container) {
      if (++this.initAttempts <= maxInitRetries) {
        requestAnimationFrame(() => {
          this.initComponent();
        });
        return;
      } else {
        this.debug(`container still doesn't exists after ${maxInitRetries} frames`);
      }
    }

    if (this.activeTabIndex > 0) {
      if (this.container) {
        this.container.moveContainerByIndex(this.activeTabIndex, false);
      }

      if (this.toolbar) {
        this.toolbar.setActiveTab(this.activeTabIndex, true);
      }
    }

    this.propagateConfig();
    this.setupEventListeners();

    this.initPromiseResolve();
  }

  /**
   * Setup event listeners to synchronize child components
   */
  private async setupEventListeners() {
    if (this.container) {
      await this.container.componentOnReady();
      this.el.addEventListener('selectedTabIndexChange', this.onContainerSelectedTabChange.bind(this));
      this.el.addEventListener('activeTabIndexChange', this.onContainerActiveTabChange.bind(this));
    } else {
      this.debug('setupEventListeners: container does not exist');
    }

    if (this.toolbar) {
      await this.toolbar.componentOnReady();
      this.el.addEventListener('buttonClick', this.onToolbarButtonClick.bind(this));
    } else {
      this.debug('setupEventListeners: toolbar does not exist');
    }
  }

  private async onContainerSelectedTabChange(ev: any) {
    this.debug('onContainerSelectedTabChange called with: ', ev);

    if (this.toolbar) {
      await this.toolbar.setSelectedTab(ev.detail);
    }
  }

  private emitTabChangeEvent(newIndex: number, oldIndex?: number) {
    if (typeof (newIndex as unknown) !== 'number' || newIndex < 0) {
      return;
    }

    if (typeof oldIndex !== 'number' || oldIndex < 0) {
      oldIndex = this.activeTabIndex;
    }

    this.tabChange.emit({
      changed: newIndex !== oldIndex,
      index: newIndex,
    });
  }

  private onContainerActiveTabChange(ev: any) {
    this.debug('onContainerActiveTabChange', ev);
    const index: number = ev.detail;

    this.emitTabChangeEvent(index);

    this.activeTabIndex = index;

    this.toolbar && this.toolbar.setActiveTab(index, true, true);
  }

  private onToolbarButtonClick(ev: any) {
    this.debug('onToolbarButtonClick', ev);

    const { index } = ev.detail;

    this.container && this.container.setActiveTabIndex(index, true, true);

    this.emitTabChangeEvent(index);

    this.activeTabIndex = index;
  }

  private indexChildren() {
    this.debug('indexChildren');

    const container = this.el.querySelector('super-tabs-container');
    const toolbar = this.el.querySelector('super-tabs-toolbar');

    if (container && this.container !== container) {
      this.container = container;
    }

    if (toolbar && this.toolbar !== toolbar) {
      this.toolbar = toolbar;
    }

    this.propagateConfig();
  }

  private async onSlotchange() {
    // re-index the child components
    this.indexChildren();

    // reselect the current tab to ensure that we're on the correct tab
    this.selectTab(this.activeTabIndex, true, false);
  }

  /**
   * Internal method to output values in debug mode.
   */
  private debug(...vals: any[]) {
    debugLog(this._config, 'tabs', vals);
  }

  render() {
    // Render 3 slots
    // Top & bottom slots allow the toolbar position to be configurable via slots.
    // The nameless slot is used to hold the `super-tabs-container`.
    return (
      <Host>
        <slot name="top"/>
        <slot/>
        <slot name="bottom"/>
      </Host>
    );
  }
}


================================================
FILE: core/src/super-tabs-container/readme.md
================================================
# super-tabs-container



<!-- Auto Generated Below -->


## Properties

| Property        | Attribute         | Description                                                                                                             | Type      | Default |
| --------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
| `autoScrollTop` | `auto-scroll-top` | Set to true to automatically scroll to the top of the tab when the button is clicked while the tab is already selected. | `boolean` | `false` |
| `swipeEnabled`  | `swipe-enabled`   | Enable/disable swiping                                                                                                  | `boolean` | `true`  |


## Events

| Event                    | Description                                                                                                                                                                                                                                                                                    | Type                  |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `activeTabIndexChange`   | Emits an event when the active tab changes. An active tab is the tab that the user looking at.  This event emitter will not notify you if the user has changed the current active tab. If you need that information, you should use the `tabChange` event emitted by the `super-tabs` element. | `CustomEvent<number>` |
| `selectedTabIndexChange` | Emits events when the container moves. Selected tab index represents what the user should be seeing. If you receive a decimal as the emitted number, it means that the container is moving between tabs. This number is used for animations, and can be used for high tab customizations.      | `CustomEvent<number>` |


## Methods

### `scrollToTop() => Promise<void>`

Scroll the active tab to the top.

#### Returns

Type: `Promise<void>`




----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tabs-container/super-tabs-container.component.scss
================================================
@import "../variables";

:host {
  display: flex;
  flex-flow: row nowrap;
  min-width: 100%;
  flex: 1 1 auto;
  position: relative;
  box-sizing: border-box;
  width: var(--super-tab-width, $st-width);
  height: var(--super-tab-height, $st-height);
  overflow: hidden;
  transform: translate3d(0, 0, 0);
  touch-action: pan-y;
  user-select: none;
  will-change: scroll-position;
  order: -1;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-font-smoothing: antialiased;
}


================================================
FILE: core/src/super-tabs-container/super-tabs-container.component.tsx
================================================
import {
  Component,
  ComponentInterface,
  Element,
  Event,
  EventEmitter,
  h,
  Listen,
  Method,
  Prop,
  QueueApi,
  State,
} from '@stencil/core';
import { SuperTabsConfig } from '../interface';
import { checkGesture, debugLog, getTs, pointerCoord, scrollEl, STCoord } from '../utils';

@Component({
  tag: 'super-tabs-container',
  styleUrl: 'super-tabs-container.component.scss',
  shadow: true,
})
export class SuperTabsContainerComponent implements ComponentInterface {
  @Element() el!: HTMLSuperTabsContainerElement;

  /** @internal */
  @Prop({ mutable: true }) config?: SuperTabsConfig;

  /** @internal */
  @Prop({ context: 'queue' }) queue!: QueueApi;

  /**
   * Enable/disable swiping
   */
  @Prop() swipeEnabled: boolean = true;

  /**
   * Set to true to automatically scroll to the top of the tab when the button is clicked while the tab is
   * already selected.
   */
  @Prop() autoScrollTop: boolean = false;

  /**
   * Emits an event when the active tab changes.
   * An active tab is the tab that the user looking at.
   *
   * This event emitter will not notify you if the user has changed the current active tab.
   * If you need that information, you should use the `tabChange` event emitted by the `super-tabs` element.
   */
  @Event() activeTabIndexChange!: EventEmitter<number>;

  /**
   * Emits events when the container moves.
   * Selected tab index represents what the user should be seeing.
   * If you receive a decimal as the emitted number, it means that the container is moving between tabs.
   * This number is used for animations, and can be used for high tab customizations.
   */
  @Event() selectedTabIndexChange!: EventEmitter<number>;

  @State() tabs: HTMLSuperTabElement[] = [];

  private initialCoords: STCoord | undefined;
  private lastPosX: number | undefined;
  private isDragging: boolean = false;
  private initialTimestamp?: number;
  private _activeTabIndex: number | undefined;
  private _selectedTabIndex?: number;
  private leftThreshold: number = 0;
  private rightThreshold: number = 0;
  private scrollWidth: number = 0;
  private slot!: HTMLSlotElement;
  private ready?: boolean;
  private width: number = 0;

  async componentDidLoad() {
    this.debug('componentDidLoad');
    this.updateWidth();
    await this.indexTabs();
    this.slot = this.el.shadowRoot!.querySelector('slot') as HTMLSlotElement;
    this.slot.addEventListener('slotchange', this.onSlotChange.bind(this));
  }

  private async onSlotChange() {
    this.debug('onSlotChange', this.tabs.length);
    this.updateWidth();
    this.indexTabs();
  }

  async componentDidRender() {
    this.updateWidth();
  }

  /**
   * @internal
   */
  @Method()
  async reindexTabs() {
    this.updateWidth();
    await this.indexTabs();
  }

  /**
   * @internal
   *
   * Moves the container to align with the specified tab index
   * @param index {number} Index of the tab
   * @param animate {boolean} Whether to animate the transition
   */
  @Method()
  moveContainerByIndex(index: number, animate?: boolean): Promise<void> {
    const scrollX = this.indexToPosition(index);

    if (scrollX === 0 && index > 0) {
      return Promise.resolve();
    }

    return this.moveContainer(scrollX, animate);
  }

  /**
   * @internal
   *
   * Sets the scrollLeft property of the container
   * @param scrollX {number}
   * @param animate {boolean}
   */
  @Method()
  moveContainer(scrollX: number, animate?: boolean): Promise<void> {
    if (animate) {
      scrollEl(this.el, scrollX, this.config!.nativeSmoothScroll!, this.config!.transitionDuration);
    } else {
      this.el.scroll(scrollX, 0);
    }

    return Promise.resolve();
  }

  /** @internal */
  @Method()
  async setActiveTabIndex(index: number, moveContainer: boolean = true, animate: boolean = true): Promise<void> {
    this.debug('setActiveTabIndex', index);

    if (this._activeTabIndex === index) {
      if (!this.autoScrollTop) {
        return;
      }

      await this.scrollToTop();
    }

    if (moveContainer) {
      await this.moveContainerByIndex(index, animate);
    }

    await this.updateActiveTabIndex(index, false);
  }

  /**
   * Scroll the active tab to the top.
   */
  @Method()
  async scrollToTop() {
    if (this._activeTabIndex === undefined || this.tabs === undefined) {
      this.debug('activeTabIndex or tabs was undefined');
      return;
    }

    const current = this.tabs[this._activeTabIndex];
    this.queue.read(() => {
      if (!current) {
        this.debug('Current active tab was undefined in scrollToTop');
        return;
      }
      //  deepcode ignore PromiseNotCaughtGeneral: <comment the reason here>
      current.getRootScrollableEl().then((el) => {
        if (el) {
          scrollEl(el, 0, this.config!.nativeSmoothScroll!, this.config!.transitionDuration);
        }
      });
    });
  }

  private updateActiveTabIndex(index: number, emit: boolean = true) {
    this.debug('updateActiveTabIndex', index, emit, this._activeTabIndex);

    this._activeTabIndex = index;
    emit && this.activeTabIndexChange.emit(this._activeTabIndex);

    this.lazyLoadTabs();
  }

  private updateSelectedTabIndex(index: number) {
    if (index === this._selectedTabIndex) {
      return;
    }

    this._selectedTabIndex = index;
    this.selectedTabIndexChange.emit(this._selectedTabIndex);
  }

  @Listen('touchstart')
  async onTouchStart(ev: TouchEvent) {
    if (!this.swipeEnabled) {
      return;
    }

    if (this.config!.avoidElements) {
      let avoid: boolean = false;
      let element: any = ev.target;

      if (element) {
        do {
          if (typeof element.getAttribute === 'function' && element.getAttribute('avoid-super-tabs')) {
            return;
          }

          element = element.parentElement;
        } while (element && !avoid);
      }
    }

    const coords = pointerCoord(ev);
    this.updateWidth();
    const vw = this.width;
    if (coords.x < this.leftThreshold || coords.x > vw - this.rightThreshold) {
      // ignore this gesture, it started in the side menu touch zone
      return;
    }

    if (this.config!.shortSwipeDuration! > 0) {
      this.initialTimestamp = getTs();
    }

    this.initialCoords = coords;
    this.lastPosX = coords.x;
  }

  @Listen('click', { passive: false, capture: true })
  async onClick(ev: TouchEvent) {
    if (this.isDragging) {
      ev.stopImmediatePropagation();
      ev.preventDefault();
    }
  }

  @Listen('touchmove', { passive: true, capture: true })
  async onTouchMove(ev: TouchEvent) {
    if (!this.swipeEnabled || !this.initialCoords || typeof this.lastPosX !== 'number') {
      return;
    }

    const coords = pointerCoord(ev);

    if (!this.isDragging) {
      if (!checkGesture(coords, this.initialCoords, this.config!)) {
        if (Math.abs(coords.y - this.initialCoords.y) > 100) {
          this.initialCoords = void 0;
          this.lastPosX = void 0;
        }
        return;
      }

      this.isDragging = true;
    }

    // stop anything else from capturing these events, to make sure the content doesn't slide
    if (!this.config!.allowElementScroll) {
      ev.stopImmediatePropagation();
    }

    // get delta X
    const deltaX: number = this.lastPosX! - coords.x;

    if (deltaX === 0) {
      return;
    }

    const scrollX = Math.max(0, Math.min(this.scrollWidth - this.width, this.el.scrollLeft + deltaX));

    if (Math.floor(scrollX) === Math.floor(this.el.scrollLeft)) {
      return;
    }

    const index = Math.round(this.positionToIndex(scrollX) * 100) / 100;
    this.updateSelectedTabIndex(index);

    // update last X value
    this.lastPosX = coords.x;

    this.el.scroll(scrollX, 0);
  }

  @Listen('touchend', { passive: false, capture: true })
  async onTouchEnd(ev: TouchEvent) {
    if (!this.swipeEnabled || !this.isDragging) {
      return;
    }

    const coords = pointerCoord(ev);

    const deltaTime: number = getTs() - this.initialTimestamp!;
    const shortSwipe = this.config!.shortSwipeDuration! > 0 && deltaTime <= this.config!.shortSwipeDuration!;
    const shortSwipeDelta = coords.x - this.initialCoords!.x;

    let selectedTabIndex = this.calcSelectedTab();
    const expectedTabIndex = Math.round(selectedTabIndex);

    if (shortSwipe && expectedTabIndex === this._activeTabIndex) {
      selectedTabIndex += shortSwipeDelta > 0 ? -1 : 1;
    }

    selectedTabIndex = this.normalizeSelectedTab(selectedTabIndex);
    this.updateActiveTabIndex(selectedTabIndex);
    this.moveContainerByIndex(selectedTabIndex, true);

    this.isDragging = false;
    this.initialCoords = void 0;
    this.lastPosX = void 0;
  }

  private updateWidth() {
    const boundingRect = this.el.getBoundingClientRect();
    this.width = Math.round(boundingRect.width * 10000) / 10000;
  }

  private async indexTabs() {
    if (this.width === 0) {
      requestAnimationFrame(() => {
        this.updateWidth();
        this.indexTabs();
      });
      return;
    }

    const tabs = Array.from(this.el.querySelectorAll('super-tab'));

    this.scrollWidth = this.width * tabs.length;

    this.debug('indexTab', this.scrollWidth, this.width);

    await Promise.all(tabs.map((t) => t.componentOnReady()));
    this.tabs = tabs;

    const activeTabIndex = this._activeTabIndex

    if (this.ready && typeof activeTabIndex === 'number') {
      this.moveContainerByIndex(activeTabIndex, true);
      this.lazyLoadTabs();
    }

    if (this.config) {
      switch (this.config.sideMenu) {
        case 'both':
          this.rightThreshold = this.leftThreshold = this.config.sideMenuThreshold || 0;
          break;
        case 'left':
          this.leftThreshold = this.config.sideMenuThreshold || 0;
          break;
        case 'right':
          this.rightThreshold = this.config.sideMenuThreshold || 0;
          break;
      }
    }

    if (activeTabIndex !== undefined) {
      this.moveContainerByIndex(activeTabIndex, false).then(() => {
        this.lazyLoadTabs();
        this.ready = true;
      });
    }
  }

  private lazyLoadTabs() {
    if (typeof this._activeTabIndex === 'undefined') {
      this.debug('lazyLoadTabs', 'called when _activeTabIndex is undefined');
      return;
    }

    if (!this.config) {
      this.debug('lazyLoadTabs', 'called with no config available');
      return;
    }

    const activeTab = this._activeTabIndex;
    const tabs = [...this.tabs];

    if (!this.config!.lazyLoad) {
      for (const tab of this.tabs) {
        tab.loaded = true
        tab.visible = true
      }
      return;
    }

    const min = activeTab - 1;
    const max = activeTab + 1;

    let index = 0;

    for (const tab of tabs) {
      tab.visible = index >= min && index <= max;

      tab.loaded = tab.visible || (this.config!.unloadWhenInvisible ? false : tab.loaded);

      index++;
    }
    this.tabs = tabs;
  }

  private calcSelectedTab(): number {
    const scrollX = Math.max(0, Math.min(this.scrollWidth - this.width, this.el.scrollLeft));
    return this.positionToIndex(scrollX);
  }

  private positionToIndex(scrollX: number) {
    const tabWidth = this.width;
    return scrollX / tabWidth;
  }

  private indexToPosition(tabIndex: number) {
    return Math.round(tabIndex * this.width * 10000) / 10000;
  }

  private normalizeSelectedTab(index: number): number {
    const scrollX = Math.max(0, Math.min(this.scrollWidth - this.width, this.indexToPosition(index)));
    return Math.round(scrollX / this.width);
  }

  /**
   * Internal method to output values in debug mode.
   */
  private debug(...vals: any[]) {
    debugLog(this.config!, 'container', vals);
  }

  render() {
    return <slot></slot>;
  }
}


================================================
FILE: core/src/super-tabs-toolbar/readme.md
================================================
# super-tabs-toolbar



<!-- Auto Generated Below -->


## Properties

| Property            | Attribute            | Description                                                                                                                                                                                              | Type                  | Default     |
| ------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----------- |
| `color`             | `color`              | Background color. Defaults to `'primary'`                                                                                                                                                                | `string \| undefined` | `'primary'` |
| `scrollable`        | `scrollable`         | Whether the toolbar is scrollable. Defaults to `false`.                                                                                                                                                  | `boolean`             | `false`     |
| `scrollablePadding` | `scrollable-padding` | If scrollable is set to true, there will be an added padding to the left of the buttons.  Setting this property to false will remove that padding.  The padding is also configurable via a CSS variable. | `boolean`             | `true`      |
| `showIndicator`     | `show-indicator`     | Whether to show the indicator. Defaults to `true`                                                                                                                                                        | `boolean`             | `true`      |


## Events

| Event         | Description                                                                                      | Type                                     |
| ------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| `buttonClick` | Emits an event when a button is clicked Event data contains the clicked SuperTabButton component | `CustomEvent<HTMLSuperTabButtonElement>` |


## CSS Custom Properties

| Name                                   | Description                                                        |
| -------------------------------------- | ------------------------------------------------------------------ |
| `--st-indicator-color`                 | Indicator color. Defaults to `--ion-color-contrast`.               |
| `--st-indicator-height`                | Indicator height. Defaults to `2px`.                               |
| `--st-scrollable-toolbar-padding-left` | Left padding when `scrollable` is set to true. Defaults to `52px`. |
| `--super-tabs-toolbar-background`      | Toolbar background color. Defaults to `--ion-color-base`.          |


## Dependencies

### Depends on

- [super-tab-indicator](../super-tab-indicator)

### Graph
```mermaid
graph TD;
  super-tabs-toolbar --> super-tab-indicator
  style super-tabs-toolbar fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*


================================================
FILE: core/src/super-tabs-toolbar/super-tabs-toolbar.component.scss
================================================
@import "../variables";

:host {
  /**
   * @prop --super-tabs-toolbar-background: Toolbar background color. Defaults to `--ion-color-base`.
   * @prop --st-scrollable-toolbar-padding-left: Left padding when `scrollable` is set to true. Defaults to `52px`.
   * @prop --st-indicator-height: Indicator height. Defaults to `2px`.
   * @prop --st-indicator-color: Indicator color. Defaults to `--ion-color-contrast`.
   */

  flex: 0 1 auto;
  display: block;
  width: 100%;
  transform: translate3d(0, 0, 0);
  position: relative;
  background: var(--super-tabs-toolbar-background, $st-toolbar-background);
  overflow: visible;
  box-sizing: border-box;
  pointer-events: auto;
  touch-action: pan-x;
  z-index: 2;
  order: -1;

  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
  -webkit-font-smoothing: antialiased;

  .buttons-container {
    display: flex;
    flex-flow: row nowrap;
    width: 100%;
    transform: translate3d(0, 0, 0);
    overflow: hidden;
  }
}

:host(:not([no-border])):after {
  left: 0;
  bottom: -8px;
  background-position: left 0 top 0;
  position: absolute;
  width: 100%;
  height: 8px;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAIBAMAAAACWGKkAAAAFVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAASAQCkAAAAB3RSTlMFTEIzJBcOYhQUIwAAAB9JREFUCNdjEIQCBiUoYDCGAgYXKGAIhQKGNChgwAAAorMLKSCkL40AAAAASUVORK5CYII=);
  background-repeat: repeat-x;
  content: '';
  z-index: 3;
  transform: translate3d(0,0,0);
}

:host([scrollable]) .buttons-container {
  will-change: scroll-position;
}

:host([scrollable][scrollable-padding]) .buttons-container {
  padding-left: var(--st-scrollable-toolbar-padding-left, $st-scrollable-toolbar-padding-left);
  width: calc(100% - var(--st-scrollable-toolbar-padding-left, $st-scrollable-toolbar-padding-left));
}


================================================
FILE: core/src/super-tabs-toolbar/super-tabs-toolbar.component.tsx
================================================
import {
  Component,
  ComponentInterface,
  Element,
  Event,
  EventEmitter,
  h,
  Host,
  Listen,
  Method,
  Prop,
  State,
  Watch,
} from '@stencil/core';
import { SuperTabsConfig } from '../interface';
import { checkGesture, debugLog, getNormalizedScrollX, pointerCoord, scrollEl, STCoord } from '../utils';


@Component({
  tag: 'super-tabs-toolbar',
  styleUrl: 'super-tabs-toolbar.component.scss',
  shadow: true,
})
export class SuperTabsToolbarComponent implements ComponentInterface {

  @Element() el!: HTMLSuperTabsToolbarElement;

  /** @internal */
  @Prop({ mutable: true }) config?: SuperTabsConfig;

  /**
   * Whether to show the indicator. Defaults to `true`
   */
  @Prop() showIndicator: boolean = true;

  /**
   * Background color. Defaults to `'primary'`
   */
  @Prop() color: string | undefined = 'primary';

  /**
   * Whether the toolbar is scrollable. Defaults to `false`.
   */
  @Prop({ reflectToAttr: true }) scrollable: boolean = false;

  /**
   * If scrollable is set to true, there will be an added padding
   * to the left of the buttons.
   *
   * Setting this property to false will remove that padding.
   *
   * The padding is also configurable via a CSS variable.
   */
  @Prop({ reflectToAttr: true }) scrollablePadding: boolean = true;

  /**
   * Emits an event when a button is clicked
   * Event data contains the clicked SuperTabButton component
   */
  @Event() buttonClick!: EventEmitter<HTMLSuperTabButtonElement>;

  @State() buttons: HTMLSuperTabButtonElement[] = [];

  width!: number;
  offsetLeft!: number;

  /**
   * Current indicator position.
   * This value is undefined until the component is fully initialized.
   * @private
   */
  private indicatorPosition: number | undefined;

  /**
   * Current indicator width.
   * This value is undefined until the component is fully initialized.
   * @private
   */
  private indicatorWidth: number | undefined;

  /**
   * Reference to the current active button
   * @private
   */
  private activeButton?: HTMLSuperTabButtonElement;
  private activeTabIndex: number = 0;
  private indicatorEl: HTMLSuperTabIndicatorElement | undefined;
  private buttonsContainerEl: HTMLDivElement | undefined;
  private initialCoords?: STCoord;
  private lastPosX: number | undefined;
  private touchStartTs: number = 0;
  private lastClickTs: number = 0;
  private isDragging: boolean | undefined;
  private leftThreshold: number = 0;
  private rightThreshold: number = 0;
  private slot!: HTMLSlotElement;
  private hostCls: any = {};

  async componentDidLoad() {
    this.setHostCls();
    await this.queryButtons();
    this.slot = this.el.shadowRoot!.querySelector('slot') as HTMLSlotElement;
    this.slot.addEventListener('slotchange', this.onSlotChange.bind(this));

    this.updateWidth();

    requestAnimationFrame(() => {
      this.setActiveTab(this.activeTabIndex, true, false);
    });
  }

  componentWillUpdate() {
    this.debug('componentWillUpdate');
    this.updateThresholds();
  }

  componentDidRender() {
    this.updateWidth();
  }

  private updateWidth() {
    const cr = this.el.getBoundingClientRect();
    this.width = Math.round(cr.width * 100) / 100;
    this.offsetLeft = cr.left;
  }

  /** @internal */
  @Method()
  setActiveTab(index: number, align?: boolean, animate?: boolean): Promise<void> {
    index = Math.max(0, Math.min(Math.round(index), this.buttons.length - 1));

    this.debug('setActiveTab', index, align, animate);

    this.activeTabIndex = index;
    this.markButtonActive(this.buttons[index]);

    if (align) {
      this.alignIndicator(index, animate);
    }

    return Promise.resolve();
  }

  /** @internal */
  @Method()
  setSelectedTab(index: number, animate?: boolean): Promise<void> {
    this.alignIndicator(index, animate);
    return Promise.resolve();
  }

  /** @internal */
  @Method()
  moveContainer(scrollX: number, animate?: boolean): Promise<void> {
    if (!this.buttonsContainerEl) {
      this.debug('moveContainer called before this.buttonsContainerEl was defined');
      return Promise.resolve();
    }

    scrollEl(this.buttonsContainerEl, scrollX, this.config!.nativeSmoothScroll!, animate ? this.config!.transitionDuration : 0);
    return Promise.resolve();
  }

  private getButtonFromEv(ev: any): HTMLSuperTabButtonElement | undefined {
    let button: HTMLSuperTabButtonElement = ev.target;

    const tag = button.tagName.toLowerCase();

    if (tag !== 'super-tab-button') {
      if (tag === 'super-tabs-toolbar') {
        return;
      }

      button = button.closest('super-tab-button') as HTMLSuperTabButtonElement;
    }

    return button;
  }

  @Listen('click')
  onClick(ev: any) {
    if (!ev || !ev.target) {
      this.debug('Got a click event with no target!', ev);
      return;
    }

    if (Date.now() - this.touchStartTs <= 150) {
      return;
    }

    const button = this.getButtonFromEv(ev);

    if (!button) {
      return;
    }

    this.onButtonClick(button);
  }

  private onButtonClick(button: HTMLSuperTabButtonElement) {
    this.lastClickTs = Date.now();
    this.setActiveTab(button.index as number, true, true);
    this.buttonClick.emit(button);
  }

  @Listen('touchstart')
  async onTouchStart(ev: TouchEvent) {
    if (!this.scrollable) {
      return;
    }

    this.debug('onTouchStart', ev);

    const coords = pointerCoord(ev);
    const vw = this.width;

    if (coords.x < this.leftThreshold || coords.x > vw - this.rightThreshold) {
      // ignore this gesture, it started in the side menu touch zone
      return;
    }

    this.touchStartTs = Date.now();
    this.initialCoords = coords;
    this.lastPosX = coords.x;
  }

  @Listen('touchmove', { passive: true, capture: true })
  async onTouchMove(ev: TouchEvent) {
    if (!this.buttonsContainerEl || !this.scrollable || !this.initialCoords || typeof this.lastPosX !== 'number') {
      return;
    }

    const coords = pointerCoord(ev);

    if (!this.isDragging) {
      const shouldCapture = checkGesture(coords, this.initialCoords!, this.config!);

      if (!shouldCapture) {
        if (Math.abs(coords.y - this.initialCoords.y) > 100) {
          this.initialCoords = void 0;
          this.lastPosX = void 0;
        }
        return;
      }

      // gesture is good, let's capture all next onTouchMove events
      this.isDragging = true;
    }

    if (!this.isDragging) {
      return;
    }

    ev.stopImmediatePropagation();

    // get delta X
    const deltaX: number = this.lastPosX - coords.x;

    if (deltaX === 0) {
      return;
    }

    // update last X value
    this.lastPosX = coords.x;

    requestAnimationFrame(() => {
      if (!this.isDragging) {
        // when swiping fast; this might run after we're already done scrolling
        // which leads to "choppy" animations since this instantly scrolls to location
        return;
      }

      // scroll container
      const scrollX = getNormalizedScrollX(this.buttonsContainerEl!, this.buttonsContainerEl!.clientWidth, deltaX);

      if (scrollX === this.buttonsContainerEl!.scrollLeft) {
        return;
      }

      this.buttonsContainerEl!.scroll(scrollX, 0);
    });
  }

  @Listen('touchend', { passive: false, capture: true })
  async onTouchEnd(ev: TouchEvent) {
    if (this.lastClickTs < this.touchStartTs && Date.now() - this.touchStartTs <= 150) {
      const coords = pointerCoord(ev);
      if (Math.abs(coords.x - this.initialCoords?.x!) < this.config?.dragThreshold!) {
        const button = this.getButtonFromEv(ev);

        if (!button) {
          return;
        }

        this.onButtonClick(button);
      }
    }

    this.isDragging = false;
    this.initialCoords = void 0;
    this.lastPosX = void 0;
  }

  @Watch('color')
  async onColorUpdate() {
    this.setHostCls();
  }

  private setHostCls() {
    const cls: any = {};

    if (typeof this.color === 'string' && this.color.trim().length > 0) {
      cls['ion-color-' + this.color.trim()] = true;
    }

    this.hostCls = cls;
  }

  private async onSlotChange() {
    this.debug('onSlotChange');
    this.updateWidth();
    await this.queryButtons();
    await this.setActiveTab(this.activeTabIndex, true);
  }

  private async queryButtons() {
    this.debug('Querying buttons');
    const buttons = Array.from(this.el.querySelectorAll('super-tab-button'));
    await Promise.all(buttons.map(b => b.componentOnReady()));

    if (buttons) {
      for (let i = 0; i < buttons.length; i++) {
        const button = buttons[i];
        button.index = i;
        button.scrollableContainer = this.scrollable;
        button.active = this.activeTabIndex === i;

        if (button.active) {
          this.activeButton = button;
        }
      }
    }

    this.buttons = buttons;
  }

  private updateThresholds() {
    if (!this.config) {
      return;
    }

    if (this.config!.sideMenu === 'both' || this.config!.sideMenu === 'left') {
      this.leftThreshold = this.config!.sideMenuThreshold!;
    }

    if (this.config!.sideMenu === 'both' || this.config!.sideMenu === 'right') {
      this.rightThreshold = this.config!.sideMenuThreshold!;
    }
  }

  private markButtonActive(button: HTMLSuperTabButtonElement) {
    if (!button) {
      this.debug('markButtonActive', 'button was undefined!');
      return;
    }

    if (this.activeButton) {
      this.activeButton.active = false;
    }

    button.active = true;
    this.activeButton = button;
  }

  private setButtonsContainerEl(el: HTMLDivElement) {
    if (el) {
      this.buttonsContainerEl = el;
    }
  }

  private adjustContainerScroll(animate: boolean) {
    if (!this.buttonsContainerEl) {
      this.debug('adjustContainerScroll called before this.buttonsContainerEl was defined');
      return;
    }

    let pos: number;

    const ip = this.indicatorPosition!;
    const iw = this.indicatorWidth!;
    const mw = this.buttonsContainerEl.clientWidth;
    const sp = this.buttonsContainerEl.scrollLeft;

    const centerDelta = ((mw / 2 - iw / 2));

    const a = Math.floor((ip + iw + centerDelta));
    const b = Math.floor((ip - centerDelta));
    const c = Math.floor((mw + sp));

    if (a > c) {
      // we need to move the segment container to the left
      pos = ip + iw + centerDelta - mw;
    } else if (b < sp) {
      // we need to move the segment container to the right
      pos = Math.max(ip - centerDelta, 0);
      pos = pos > ip ? ip - mw + iw : pos;
    } else {
      return;
    }

    if (!animate) {
      scrollEl(this.buttonsContainerEl, pos!, false, 50);
    } else {
      this.moveContainer(pos!, animate);
    }
  }

  /**
   * Align the indicator with the selected button.
   * This will adjust the width and the position of the indicator element.
   * @param index {number} the active tab index
   * @param [animate] {boolean=false} whether to animate the transition
   */
  private async alignIndicator(index: number, animate: boolean = false) {
    if (!this.showIndicator || !this.indicatorEl) {
      return;
    }

    this.debug('Aligning indicator', index);

    const remainder = index % 1;
    const isDragging = this.isDragging = remainder > 0;

    const floor = Math.floor(index), ceil = Math.ceil(index);
    const button = this.buttons[floor];

    if (!button) {
      return;
    }

    let position = button.offsetLeft;
    let width = button.clientWidth;

    if (isDragging && floor !== ceil) {
      const buttonB = this.buttons[ceil];

      if (!buttonB) {
        // the scroll position we received is higher than the max possible position
        // this could happen due to bad CSS (by developer or this module)
        // or bad scrolling logic?
        return;
      }

      const buttonBPosition = buttonB.offsetLeft;
      const buttonBWidth = buttonB.clientWidth;

      position += remainder * (buttonBPosition - position);
      width += remainder * (buttonBWidth - width);
    }

    requestAnimationFrame(() => {
      this.indicatorPosition = position;
      this.indicatorWidth = width;

      if (this.scrollable) {
        this.adjustContainerScroll(animate || !isDragging);
      }

      this.indicatorEl!.style.setProperty('--st-indicator-position-x', this.indicatorPosition + 'px');
      this.indicatorEl!.style.setProperty('--st-indicator-scale-x', String(this.indicatorWidth! / 100));
      this.indicatorEl!.style.setProperty('--st-indicator-transition-duration', this.isDragging ? '0' : `${this.config!.transitionDuration}ms`);
    });
  }

  /**
   * Internal method to output values in debug mode.
   */
  private debug(...vals: any[]) {
    debugLog(this.config!, 'toolbar', vals);
  }

  render() {
    return (
      <Host role="navigation" class={this.hostCls}>
        <div class="buttons-container" ref={(ref: any) => this.setButtonsContainerEl(ref)}>
          <slot/>
          {this.showIndicator &&
          <super-tab-indicator ref={(ref: any) => this.indicatorEl = ref}
                               toolbarPosition={this.el!.assignedSlot!.name as any}/>}
        </div>
      </Host>
    );
  }
}


================================================
FILE: core/src/utils.ts
================================================
import { SuperTabsConfig } from './interface';


export const DEFAULT_CONFIG: SuperTabsConfig = {
  dragThreshold: 20,
  allowElementScroll: false,
  maxDragAngle: 40,
  sideMenuThreshold: 50,
  transitionDuration: 150,
  shortSwipeDuration: 300,
  debug: false,
  avoidElements: false,
  lazyLoad: false,
  unloadWhenInvisible: false,
};

export type STCoord = {
  x: number;
  y: number;
}

export function pointerCoord(ev: any): STCoord {
  // get X coordinates for either a mouse click
  // or a touch depending on the given event
  if (ev) {
    const changedTouches = ev.changedTouches;
    if (changedTouches && changedTouches.length > 0) {
      const touch = changedTouches[0];
      return { x: touch.clientX, y: touch.clientY };
    }
    if (ev.pageX !== undefined) {
      return { x: ev.pageX, y: ev.pageY };
    }
  }
  return { x: 0, y: 0 };
}

const nativeScrollAvailable: boolean = 'scrollBehavior' in document.documentElement.style;

let _getTs: () => number;

if (window.performance && window.performance.now) {
  _getTs = window.performance.now.bind(window.performance);
} else {
  _getTs = Date.now.bind(Date);
}

export const getTs = _getTs;

export const easeInOutCubic = (t: number) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

function getScrollCoord(start: number, dest: number, startTime: number, currentTime: number, duration: number) {
  const time = Math.min(1, (currentTime - startTime) / duration);
  const timeFn = easeInOutCubic(time);
  return Math.ceil((timeFn * (dest - start)) + start);
}

function scroll(el: Element, startX: number, x: number, startTime: number, duration: number) {
  const currentTime = getTs();
  const scrollX = startX === x ? x : getScrollCoord(startX, x, startTime, currentTime, duration);

  el.scrollTo(scrollX, 0);

  if (currentTime - startTime >= duration) {
    return;
  }

  requestAnimationFrame(() => {
    scroll(el, startX, x, startTime, duration);
  });
}

export const scrollEl = (el: Element, x: number, native: boolean, duration: number = 300) => {
  if (duration <= 0) {
    requestAnimationFrame(() => {
      el.scrollTo(x, 0);
    });
    return;
  }

  if (native && nativeScrollAvailable) {
    el.scrollTo({
      left: x,
      behavior: 'smooth',
    });
    return;
  }

  requestAnimationFrame(() => {
    scroll(el, el.scrollLeft, x, getTs(), duration);
  });
};

export function checkGesture(newCoords: STCoord, initialCoords: STCoord, config: SuperTabsConfig): boolean {
  if (!initialCoords) {
    return false;
  }

  const radians = config.maxDragAngle! * (Math.PI / 180);
  const maxCosine = Math.cos(radians);
  const deltaX = newCoords.x - initialCoords.x;
  const deltaY = newCoords.y - initialCoords.y;
  const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

  if (distance >= config.dragThreshold!) {
    // swipe is long enough
    // lets check the angle
    const angle = Math.atan2(deltaY, deltaX);
    const cosine = Math.cos(angle);
    return Math.abs(cosine) > maxCosine;
  }

  return false;
}

export function getNormalizedScrollX(el: HTMLElement, width: number, delta: number = 0): number {
  return Math.max(0, Math.min(el.scrollWidth - width, el.scrollLeft + delta))
}

const debugStyle1 = 'background: linear-gradient(135deg,#4150b2,#f71947); border: 1px solid #9a9a9a; color: #ffffff; border-bottom-left-radius: 2px; border-top-left-radius: 2px; padding: 2px 0 2px 4px;';
const debugStyle2 = 'background: #252b3e; border: 1px solid #9a9a9a; border-top-right-radius: 2px; border-bottom-right-radius: 2px; margin-left: -2px; padding: 2px 4px; color: white;';

export function debugLog(config: SuperTabsConfig, tag: string, vals: any[]) {
  if (!config || !config.debug) {
    return;
  }

  // Some gorgeous logging, because apparently I have lots of free time to style console logs and write this comment
  console.log(`%csuper-tabs %c%s`, debugStyle1, debugStyle2, ' '.repeat(10 - tag.length) + tag, ...vals);
}


================================================
FILE: core/src/variables.scss
================================================
/**
 * super-tab-button variables
 */

/// @prop - Active color of a toolbar button
$st-button-base-color-active: #{var(--ion-color-contrast)} !default;
/// @prop - Inactive color of a toolbar button
$st-button-base-color-inactive: #{rgba(var(--ion-color-contrast-rgb), 0.7)} !default;

/// @prop - Toolbar button icon size
$st-button-icon-size: 24px !default;
/// @prop - Toolbar button inactive color
$st-button-icon-color-inactive: var(--st-base-color-inactive) !default;
/// @prop - Toolbar button active color
$st-button-icon-color-active: var(--st-base-color-active) !default;

$st-button-label-line-height: 14px !default;
$st-button-label-height: 14px !default;
$st-button-label-font-size: 14px !default;
$st-button-label-text-transform: uppercase !default;
$st-button-label-font-weight: 500 !default;
$st-button-label-padding-bottom: 16px !default;
$st-button-label-color-inactive: var(--st-base-color-inactive) !default;
$st-button-label-color-active: var(--st-base-color-active) !default;

/**
 * super-tab variables
 */
$st-width: 100vw !default;
$st-height: 100% !default;

/**
 * super-tab-indicator variables
 */
$st-indicator-height: 2px !default;
$st-indicator-color: var(--ion-color-contrast, white) !default;

/**
 * super-tab-toolbar variables
 */
$st-scrollable-toolbar-padding-left: 52px !default;
$st-toolbar-background: var(--ion-color-base) !default;


================================================
FILE: core/stencil.config.ts
================================================
import { angularOutputTarget } from '@stencil/angular-output-target';
import { Config } from '@stencil/core';
import { reactOutputTarget } from '@stencil/react-output-target';
import { sass } from '@stencil/sass';


export const config: Config = {

  namespace: 'SuperTabs',
  bundles: [
    { components: ['super-tabs', 'super-tabs-container', 'super-tab'] },
    { components: ['super-tabs-toolbar', 'super-tab-button'] },
    { components: ['super-tab-indicator'] },
  ],
  plugins: [
    sass(),
  ],
  outputTargets: [
    {
      type: 'dist',
      esmLoaderPath: '../loader',
      copy: [{ src: '**/*.scss' }],
    },
    {
      type: 'docs-readme',
      strict: true,
    },
    {
      type: 'dist-hydrate-script',
    },
    angularOutputTarget({
      componentCorePackage: '@ionic-super-tabs/core',
      directivesProxyFile: '../angular/src/directives/proxies.ts',
      directivesUtilsFile: '../angular/src/directives/proxies-utils.ts',
      directivesArrayFile: '../angular/src/directives/proxies-list.txt',
      excludeComponents: [
        'super-tab-indicator',
      ],
    }),
    reactOutputTarget({
      componentCorePackage: '@ionic-super-tabs/core',
      proxiesFile: '../react/src/components.ts',
      excludeComponents: [
        'super-tab-indicator',
      ],
    }),
  ],
  validateTypes: true,
};


================================================
FILE: core/tsconfig.json
================================================
{
  "compilerOptions": {
    "strict": true,
    "alwaysStrict": true,
    "allowSyntheticDefaultImports": true,
    "allowUnreachableCode": false,
    "declaration": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "jsxFactory": "h",
    "lib": [
      "dom",
      "es2017"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "outDir": ".tmp",
    "pretty": true,
    "removeComments": false,
    "target": "es2017"
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "stencil.config.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}


================================================
FILE: doc-pages/configuration.md
================================================
# Configuration

Configuring ***Super Tabs*** can be done by setting the `config` property on a `<super-tab>` element.

Example:
```html
<!-- home.page.html -->
<super-tabs [config]="config">
```
```ts
<!-- home.page.ts -->
  ...
  
  config: SuperTabsConfig = {
    sideMenu: 'left',
    shortSwipeDuration: 180,
  };
```

## Defaults
```ts
export const DEFAULT_CONFIG: SuperTabsConfig = {
  dragThreshold: 10,
  allowElementScroll: false,
  maxDragAngle: 40,
  sideMenuThreshold: 50,
  transitionDuration: 300,
  shortSwipeDuration: 300,
  debug: false,
  avoidElements: false,
};
```

## Reference
```ts
/**
   * Max drag angle in degrees.
   *
   * Defaults to `40`
   */
  maxDragAngle?: number;

  /**
   * Drag threshold in pixels.
   *
   * This value defines how far the user have to swipe for the swipe to be treated as a swipe gesture.
   *
   * Defaults to `20`
   */
  dragThreshold?: number;

  /**
   * Allows elements inside tabs to be dragged or scrolled through.
   *
   * Setting this value to `true` will allow touch events to be propagated to child components.
   *
   * Defaults to `false`.
   */
  allowElementScroll?: boolean;

  /**
   * Transition duration in milliseconds.
   *
   * This value is used for all transitions and animations.
   *
   * Defaults to `150`.
   */
  transitionDuration?: number;

  /**
   * Side menu location.
   *
   * If this value is set to `right` or `left`, the super tabs component will avoid listening to swipe events
   * in the specified region(s) to avoid interfering with a side menu event listeners.
   *
   * Defaults to `undefined`.
   */
  sideMenu?: 'left' | 'right' | 'both';

  /**
   * Side menu threshold in pixels.
   *
   * Defaults to `50`.
   */
  sideMenuThreshold?: number;

  /**
   * Short swipe duration in milliseconds.
   *
   * Short swipe is when a user quickly swipes between tabs. If the swipe duration is less than or equal to this
   * configured value, then we assume that the user wants to switch tabs.
   * To disable this behaviour set this value to `0`.
   *
   * Defaults to `300`
   */
  shortSwipeDuration?: number;

  /**
   * Enable debug mode.
   * Defaults to `false`.
   */
  debug?: boolean;

  /**
   * Whether the container should look and avoid elements with avoid-super-tabs attribute
   */
  avoidElements?: boolean;
```


================================================
FILE: doc-pages/getting-started/angular.md
================================================
# Getting Started with Angular

## Installation

#### 1. Install the module
```shell
npm i --save @ionic-super-tabs/angular
```
#### 2. Import the module
You must import `SuperTabsModule.forRoot()` once only. This is usually imported in your app's root module (e.g `AppModule`), 
but it can be imported in other modules depending on your app structure.

For lazy loaded app you must also import `SuperTabsModule` to have access to the provided components.

```typescript
import { SuperTabsModule } from '@ionic-super-tabs/angular';

// Root module import example
@NgModule({
  ...
  imports: [
    ...
    SuperTabsModule.forRoot(),
  ],
  ...
})
export class AppModule {}

// Child module import example
@NgModule({
  ...
  imports: [
    ...
    SuperTabsModule,
  ],
  ...
})
export class HomePageModule {}
```   


See the [Angular Usage Guide](usage/angular) for examples on how to setup ***Super Tabs***.


================================================
FILE: doc-pages/home.md
================================================
# Super Tabs
Swipeable tabs for Ionic apps

## Introduction
***Super Tabs*** is a set of web components to build swipe-able views in <a href="https://ionicframework.com" target="_blank">Ionic</a> apps.
 The module was designed based on <a href="https://material.io/components/tabs/" target="_blank">Material Design Guidelines</a> 
 to provide a simple and familiar user experience.
 
 
## Support

#### Community support
Having some trouble? search existing [issues](https://github.com/zyra/ionic-super-tabs/issues) on Github, or [submit a bug report](https://github.com/zyra/ionic-super-tabs/issues/new?assignees=&labels=&template=bug_report.md&title=).

## Contributing
To request a feature create a new issue. Pull requests are welcome. 

Features with minimal impact on performance or complexity have a higher probability of being implemented/merged.

## License
This project is licensed under the [MIT License](https://github.com/zyra/ionic-super-tabs/blob/master/LICENSE.md).


================================================
FILE: doc-pages/usage/angular.md
================================================
# Angular Usage Guide

* [Basic usage](usage/angular/#basic-usage)
* [Scrollable toolbar](usage/angular/#scrollable-toolbar)
* [Toolbar positioning](usage/angular/#toolbar-positioning)
* [Routing](usage/angular/#routing)
* [Theming](usage/angular/#theming)

## Basic usage
```html
<ion-header class="ion-no-border">
  <ion-toolbar>
    <ion-title>Super Tabs</ion-title>
  </ion-toolbar>
</ion-header>

<super-tabs>
  <super-tabs-toolbar slot="top">
    <super-tab-button>
      <ion-icon name="home"></ion-icon>
      <ion-label>Page #1</ion-label>    
    </super-tab-button>
    <super-tab-button>
      <ion-icon name="home"></ion-icon>
      <ion-label>Page #2</ion-label>    
    </super-tab-button>
    <super-tab-button>
      <ion-icon name="home"></ion-icon>
      <ion-label>Page #3</ion-label>    
    </super-tab-button>
  </super-tabs-toolbar>
  <super-tabs-container>
    <super-tab>
      <ion-content>
        Page #1
      </ion-content>
    </super-tab>
    <super-tab>
      <ion-content>
        Page #2
      </ion-content>
    </super-tab>
    <super-tab>
      <ion-content>
        Page #3
      </ion-content>
    </super-tab>
  </super-tabs-container>
</super-tabs>
```

## Scrollable toolbar
Enabling toolbar scrolling is recommended if the toolbar gets crowded with many tabs.

To enable this feature, set the `scrollable` attribute on `<super-tabs-toolbar>`.

Example:
```html
<super-tabs>
  <super-tab-toolbar slot="top" scrollable>
    <!-- ... -->  
  </super-tab-toolbar>
  <!-- ... -->
</super-tabs>
```

## Toolbar positioning
To position the toolbar below the tabs, set the `slot` attribute to `bottom`.

Example:
```html
<super-tabs>
  <super-tab-toolbar slot="bottom">
    <!-- ... -->  
  </super-tab-toolbar>
  <!-- ... -->
</super-tabs>
```

## Routing
To use external pages inside a `<super-tab>` you can use `<ion-nav>` *<small>(instead of `<ion-content>` in basic usage example)</small>*.

Note that lazy loading is not supported yet, so you must pass the target page as a variable.

Example:
```html
<super-tabs>
  <!-- ... -->
  <super-tabs-container>
     <!-- ... -->
     <super-tab>
       <ion-nav [root]="myPage" [rootParams]="{ hello: 'world' }"></ion-nav>
     </super-tab>
  </super-tabs-container>
</super-tabs>
``` 

```ts
import { MyPage } from '../path/to/my.page';

@Component({
  ...
})
export class HomePage {
  myPage = MyPage;
}
```

## Theming
Styling ***Super Tabs*** can be done by setting the available CSS variables. To see the available variables check the 
documentation for the specific element.

You can set variables in your page:
```scss
// home.page.scss
:host {  
  --super-tabs-toolbar-background: black;
  --st-indicator-color: yellow;
}
```

or in your root variables:
```scss
// variables.scss
:root {
  --st-base-color-inactive: rgba(255, 255, 255, 0.6);
  --st-base-color-active: rgba(255, 255, 255, 0.99);
}
```


================================================
FILE: lerna.json
================================================
{
  "lerna": "2.11.0",
  "packages": [
    "angular",
    "core",
    "react"
  ],
  "version": "7.0.8"
}


================================================
FILE: package.json
================================================
{
  "name": "@ionic-super-tabs/source",
  "version": "0.0.0",
  "description": "",
  "scripts": {
    "bootstrap": "lerna bootstrap",
    "build": "lerna run build --concurrency 1",
    "test": "lerna run test"
  },
  "author": "Zyra Media Inc. <info@zyra.ca>",
  "license": "MIT",
  "devDependencies": {
    "lerna": "latest",
    "tslint": "latest"
  }
}


================================================
FILE: react/.gitignore
================================================
dist
dist-transpiled
node_modules


================================================
FILE: react/package.json
================================================
{
  "name": "@ionic-super-tabs/react",
  "version": "7.0.8",
  "description": "Ionic Super Tabs bindings for React applications",
  "author": "Zyra Media Inc. <info@zyra.ca>",
  "license": "MIT",
  "scripts": {
    "build": "npm run clean && npm run compile",
    "clean": "rm -rf dist && rm -rf dist-transpiled",
    "compile": "npm run tsc && rollup -c",
    "tsc": "tsc -p ."
  },
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/types/index.d.ts",
  "files": [
    "dist/"
  ],
  "keywords": [
    "ionic",
    "swipeable",
    "tabs",
    "module",
    "component",
    "react"
  ],
  "dependencies": {
    "@ionic-super-tabs/core": "^7.0.8",
    "tslib": "*"
  },
  "devDependencies": {
    "@types/node": "^12.12.14",
    "@types/react": "^16.9.2",
    "@types/react-dom": "^16.9.0",
    "fs-extra": "^8.1.0",
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-testing-library": "^7.0.0",
    "rollup": "^1.18.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-sourcemaps": "^0.4.2",
    "rollup-plugin-virtual": "^1.0.1",
    "typescript": "^3.7.2"
  }
}


================================================
FILE: react/rollup.config.js
================================================
// borrowed from https://github.com/ionic-team/ionic/blob/930b271a4abf680b08e6755644cece4b95053f15/packages/react/rollup.config.js

import resolve from 'rollup-plugin-node-resolve';
import sourcemaps from 'rollup-plugin-sourcemaps';

export default {
  input: 'dist-transpiled/index.js',
  output: [
    {
      file: 'dist/index.esm.js',
      format: 'es',
      sourcemap: true
    },
    {
      file: 'dist/index.js',
      format: 'commonjs',
      preferConst: true,
      sourcemap: true
    }
  ],
  external: (id) => !/^(\.|\/)/.test(id),
  plugins: [
    resolve(),
    sourcemaps()
  ]
};


================================================
FILE: react/src/components.ts
================================================
/* eslint-disable */
/* tslint:disable */
/* auto-generated react proxies */
import { createReactComponent } from './react-component-lib';

import { JSX } from '@ionic-super-tabs/core';

import { defineCustomElements, applyPolyfills } from '@ionic-super-tabs/core/loader';

applyPolyfills().then(() => defineCustomElements());
export const SuperTab = /*@__PURE__*/createReactComponent<JSX.SuperTab, HTMLSuperTabElement>('super-tab');
export const SuperTabButton = /*@__PURE__*/createReactComponent<JSX.SuperTabButton, HTMLSuperTabButtonElement>('super-tab-button');
export const SuperTabs = /*@__PURE__*/createReactComponent<JSX.SuperTabs, HTMLSuperTabsElement>('super-tabs');
export const SuperTabsContainer = /*@__PURE__*/createReactComponent<JSX.SuperTabsContainer, HTMLSuperTabsContainerElement>('super-tabs-container');
export const SuperTabsToolbar = /*@__PURE__*/createReactComponent<JSX.SuperTabsToolbar, HTMLSuperTabsToolbarElement>('super-tabs-toolbar');


================================================
FILE: react/src/index.ts
================================================
export * from './components';


================================================
FILE: react/src/react-component-lib/createComponent.tsx
================================================
import React from 'react';

import {
  attachEventProps,
  createForwardRef,
  dashToPascalCase,
  isCoveredByReact,
} from './utils/index';

interface IonicReactInternalProps<ElementType> extends React.HTMLAttributes<ElementType> {
  forwardedRef?: React.Ref<ElementType>;
  ref?: React.Ref<any>;
}

export const createReactComponent = <PropType, ElementType>(tagName: string) => {
  const displayName = dashToPascalCase(tagName);
  const ReactComponent = class extends React.Component<IonicReactInternalProps<ElementType>> {
    
    private ref: React.RefObject<HTMLElement>;
    
    constructor(props: IonicReactInternalProps<ElementType>) {
      super(props);
      this.ref = React.createRef<HTMLElement>();
    }

    componentDidMount() {
      this.componentDidUpdate(this.props);
    }

    componentDidUpdate(prevProps: IonicReactInternalProps<ElementType>) {
      const node = this.ref.current;
      attachEventProps(node, this.props, prevProps);
    }

    render() {
      const { children, forwardedRef, style, className, ref, ...cProps } = this.props;

      const propsToPass = Object.keys(cProps).reduce((acc, name) => {
        const isEventProp = name.indexOf('on') === 0 && name[2] === name[2].toUpperCase();
        const isDataProp = name.indexOf('data-') === 0;
        const isAriaProp = name.indexOf('aria-') === 0;

        if (isEventProp) {
          const eventName = name.substring(2).toLowerCase();
          if (typeof document !== "undefined" && isCoveredByReact(eventName)) {
            (acc as any)[name] = (cProps as any)[name];
          }
        } else if (isDataProp || isAriaProp) {
          (acc as any)[name] = (cProps as any)[name];
        }
        return acc;
      }, {});

      const newProps: any = {
        ...propsToPass,
        ref: this.ref,
        style,
        className,
      };

      return React.createElement(tagName, newProps, children);
    }

    static get displayName() {
      return displayName;
    }
  };
  return createForwardRef<PropType, ElementType>(ReactComponent, displayName);
};


================================================
FILE: react/src/react-component-lib/createControllerComponent.tsx
================================================
import React from 'react';
import { attachEventProps } from './utils/attachEventProps';

interface LoadingElement {
  present: () => any;
  dismiss: () => any;
}

interface ReactControllerProps<E> {
  isOpen: boolean;
  onDidDismiss: (event: CustomEvent<E>) => void;
}

export function createControllerComponent<
  OptionsType extends object,
  LoadingElementType extends LoadingElement,
  OverlayEventDetail
>(displayName: string, controller: { create: (options: any) => Promise<LoadingElementType> }) {
  const dismissEventName = `on${displayName}DidDismiss`;

  type Props = OptionsType & ReactControllerProps<OverlayEventDetail>;

  return class ReactControllerComponent extends React.Component<Props> {
    controller?: LoadingElementType;

    constructor(props: Props) {
      super(props);
    }

    static get displayName() {
      return displayName;
    }

    async componentDidMount() {
      const { isOpen } = this.props;
      if (isOpen) {
        this.present();
      }
    }

    async componentDidUpdate(prevProps: Props) {
      if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
        this.present(prevProps);
      }
      if (
        this.controller &&
        prevProps.isOpen !== this.props.isOpen &&
        this.props.isOpen === false
      ) {
        await this.controller.dismiss();
      }
    }

    async present(prevProps?: Props) {
      const { isOpen, onDidDismiss, ...cProps } = this.props;
      const elementProps = {
        ...cProps,
        [dismissEventName]: onDidDismiss,
      };
      this.controller = await controller.create({
        ...elementProps,
      });
      attachEventProps(this.controller as any, elementProps, prevProps);
      this.controller.present();
    }

    render(): null {
      return null;
    }
  };
}


================================================
FILE: react/src/react-component-lib/createOverlayComponent.tsx
================================================
import React from 'react';
import ReactDOM from 'react-dom';
import { attachEventProps } from './utils/attachEventProps';

interface LoadingElement {
  present: () => any;
  dismiss: () => any;
}
interface ReactOverlayProps<E> {
  children?: React.ReactNode;
  isOpen: boolean;
  onDidDismiss?: (event: CustomEvent<E>) => void;
}

export function createOverlayComponent<
  T extends object,
  LoadingElementType extends LoadingElement,
  OverlayEventDetail
>(displayName: string, controller: { create: (options: any) => Promise<LoadingElementType> }) {
  const dismissEventName = `on${displayName}DidDismiss`;

  type Props = T & ReactOverlayProps<OverlayEventDetail>;

  return class ReactOverlayComponent extends React.Component<Props> {
    controller?: LoadingElementType;
    el: HTMLDivElement;

    constructor(props: Props) {
      super(props);
      this.el = document.createElement('div');
    }

    static get displayName() {
      return displayName;
    }

    componentDidMount() {
      if (this.props.isOpen) {
        this.present();
      }
    }

    async componentDidUpdate(prevProps: Props) {
      if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen === true) {
        this.present(prevProps);
      }
      if (
        this.controller &&
        prevProps.isOpen !== this.props.isOpen &&
        this.props.isOpen === false
      ) {
        await this.controller.dismiss();
      }
    }

    async present(prevProps?: Props) {
      // tslint:disable-next-line:no-empty
      const { children, isOpen, onDidDismiss = () => {}, ...cProps } = this.props;
      const elementProps = {
        ...cProps,
        [dismissEventName]: onDidDismiss,
      };

      this.controller = await controller.create({
        ...elementProps,
        component: this.el,
        componentProps: {},
      });

      attachEventProps(this.controller as any, elementProps, prevProps);

      this.controller.present();
    }

    render() {
      return ReactDOM.createPortal(this.props.children, this.el);
    }
  };
}


================================================
FILE: react/src/react-component-lib/index.ts
================================================
export { createReactComponent } from './createComponent';
export { createControllerComponent } from './createControllerComponent';
export { createOverlayComponent } from './createOverlayComponent';


================================================
FILE: react/src/react-component-lib/utils/attachEventProps.ts
================================================
export function attachEventProps(node: HTMLElement, newProps: any, oldProps: any = {}) {
  const className = getClassName(node.classList, newProps, oldProps);
  if (className) {
    node.className = className;
  }

  Object.keys(newProps).forEach(name => {
    if (name === 'children' || name === 'style' || name === 'ref' || name === 'className') {
      return;
    }
    if (name.indexOf('on') === 0 && name[2] === name[2].toUpperCase()) {
      const eventName = name.substring(2);
      const eventNameLc = eventName[0].toLowerCase() + eventName.substring(1);

      if (!isCoveredByReact(eventNameLc)) {
        syncEvent(node, eventNameLc, newProps[name]);
      }
    } else {
      (node as any)[name] = newProps[name];
    }
  });
}

export function getClassName(classList: DOMTokenList, newProps: any, oldProps: any) {
  // map the classes to Maps for performance
  const currentClasses = arrayToMap(classList);
  const incomingPropClasses = arrayToMap(newProps.className ? newProps.className.split(' ') : []);
  const oldPropClasses = arrayToMap(oldProps.className ? oldProps.className.split(' ') : []);
  const finalClassNames: string[] = [];
  // loop through each of the current classes on the component
  // to see if it should be a part of the classNames added
  currentClasses.forEach(currentClass => {
    if (incomingPropClasses.has(currentClass)) {
      // add it as its already included in classnames coming in from newProps
      finalClassNames.push(currentClass);
      incomingPropClasses.delete(currentClass);
    } else if (!oldPropClasses.has(currentClass)) {
      // add it as it has NOT been removed by user
      finalClassNames.push(currentClass);
    }
  });
  incomingPropClasses.forEach(s => finalClassNames.push(s));
  return finalClassNames.join(' ');
}

/**
 * Checks if an event is supported in the current execution environment.
 * @license Modernizr 3.0.0pre (Custom Build) | MIT
 */
export function isCoveredByReact(eventNameSuffix: string, doc: Document = document) {
  const eventName = 'on' + eventNameSuffix;
  let isSupported = eventName in doc;

  if (!isSupported) {
    const element = doc.createElement('div');
    element.setAttribute(eventName, 'return;');
    isSupported = typeof (element as any)[eventName] === 'function';
  }

  return isSupported;
}

export function syncEvent(node: Element, eventName: string, newEventHandler: (e: Event) => any) {
  const eventStore = (node as any).__events || ((node as any).__events = {});
  const oldEventHandler = eventStore[eventName];

  // Remove old listener so they don't double up.
  if (oldEventHandler) {
    node.removeEventListener(eventName, oldEventHandler);
  }

  if (newEventHandler != null) {
    // Bind new listener.
    node.addEventListener(
      eventName,
      (eventStore[eventName] = function handler(e: Event) {
        newEventHandler.call(this, e);
      }),
    );
  }
}

function arrayToMap(arr: string[] | DOMTokenList) {
  const map = new Map<string, string>();
  (arr as string[]).forEach((s: string) => map.set(s, s));
  return map;
}


================================================
FILE: react/src/react-component-lib/utils/index.tsx
================================================
import React from 'react';

export const dashToPascalCase = (str: string) =>
  str
    .toLowerCase()
    .split('-')
    .map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))
    .join('');

export interface ReactProps {
  class?: string;
}

export type IonicReactExternalProps<PropType, ElementType> = PropType & React.HTMLAttributes<ElementType> & ReactProps;

export const createForwardRef = <PropType, ElementType>(
  ReactComponent: any,
  displayName: string,
) => {
  const forwardRef = (
    props: IonicReactExternalProps<PropType, ElementType>,
    ref: React.Ref<ElementType>,
  ) => {
    return <ReactComponent {...props} forwardedRef={ref} />;
  };
  forwardRef.displayName = displayName;

  return React.forwardRef(forwardRef);
};

export * from './attachEventProps';


================================================
FILE: react/tsconfig.json
================================================
{
  "compilerOptions": {
    "strict": false,
    "allowUnreachableCode": false,
    "allowSyntheticDefaultImports": true,
    "declaration": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "lib": ["dom", "es2015"],
    "importHelpers": true,
    "module": "es2015",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "outDir": "dist-transpiled",
    "declarationDir": "dist/types",
    "removeComments": false,
    "inlineSources": true,
    "sourceMap": true,
    "jsx": "react",
    "target": "es2017"
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "compileOnSave": false,
  "buildOnSave": false
}


================================================
FILE: super-tabs.sh
================================================
#!/bin/bash

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
WORK_DIR=${TMP:-$DIR}
WS_DIR="${WORK_DIR}/.super-tabs-tmp"
EXAMPLE_PROJECT_DIR_DEFAULT="$(cd "${DIR}/../" >/dev/null 2>&1 && pwd)/ionic-super-tabs-example"
EXAMPLE_PROJECT_DIR=${EXAMPLE_PROJECT_DIR:-${EXAMPLE_PROJECT_DIR_DEFAULT}}

trap '_cleanWorkspace' EXIT
trap 'exit' SIGINT SIGTERM

declare -a _cmd_setup=("setup" "Installs node modules for all packages")
declare -a _cmd_build=("build" "Builds core and angular projects" '--only <core|angular>')
declare -a _cmd_copy=("copy" "Copies built packages as NPM modules to \`${EXAMPLE_PROJECT_DIR}\`")
declare -a _cmd_dev=("dev" 'Runs build and then copy')
declare -a _cmd_publish=("publish" 'Runs build and publishes package to npm' '--npm-args <additional npm arguments>')

_formatArgs() {
  _args=$(printf "%s" "$2")
  for arg in "${@:3}"; do
    _args=$(printf "%s\n\t\t\e[37m%s\e[0m" "${_args}" "${arg}")
  done
  printf "%s" "${_args}"
}

_printUsage() {
  declare -a args=(
    "$(basename "${0}")"
    "${_cmd_setup[0]}" "$(_formatArgs "${_cmd_setup[@]}")"
    "${_cmd_build[0]}" "$(_formatArgs "${_cmd_build[@]}")"
    "${_cmd_copy[0]}" "$(_formatArgs "${_cmd_copy[@]}")"
    "${_cmd_dev[0]}" "$(_formatArgs "${_cmd_dev[@]}")"
    "${_cmd_publish[0]}" "$(_formatArgs "${_cmd_publish[@]}")"
  )

  printf "\e[1m\e[94m................................................................
..............                               ...................
..............    Ionic Super Tabs Helper    ...................
..............                               ...................
................................................................
\e[0m

\e[1m\e[36mUsage\e[0m: %s <command> [options]

\e[1m\e[36mCommands:\e[0m
* \e[1m%10s:\e[0m %s
* \e[1m%10s:\e[0m %s
* \e[1m%10s:\e[0m %s
* \e[1m%10s:\e[0m %s
* \e[1m%10s:\e[0m %s
" "${args[@]}"
}

errExit() {
  echo -e "\e[1m\e[91m${*}\e[0m"
  exit 1
}

_exec() {
#   s=$(date +%s%N | cut -b1-13)
  "$@" || errExit "Failed to execute command"
#  e=$(date +%s%N | cut -b1-13)
#  d=$((e - s))
#  _logv "executed ${*} in ${d}ms"
}

_execSilent() {
  "$@" &>/dev/null
}

_setupWorkspace() {
  _execSilent cd "${DIR}"
  _cleanWorkspace
  mkdir -p "${WS_DIR}" >/dev/null || errExit 'unable to setup workspace'
}

_cleanWorkspace() {
  if [ -d "${WS_DIR}" ]; then
    rm -rf "${WS_DIR}" >/dev/null || errExit 'unable to clean workspace'
  fi
}

_logv() {
  echo -e "\e[33m${*}\e[0m"
}

_log() {
  echo -e "\e[36m${*}\e[0m"
}

_build() {
  local _only

  for ((i = 1; i <= $#; i++)); do
    case "${!i}" in
    "--only")
      local _next="$((i + 1))"
      _only="${!_next}"
      ;;
    esac
  done

  case "${_only}" in
  "angular")
    _log "Building angular module"
    _exec npx lerna run build --scope=@ionic-super-tabs/angular --stream --no-progress --loglevel=silent
    ;;

  "core")
    _log "Building core module"
    _exec npx lerna run build --scope=@ionic-super-tabs/core --stream --no-progress --loglevel=silent
    ;;

  "react")
    _log "Building react module"
    _exec npx lerna run build --scope=@ionic-super-tabs/react --stream --no-progress --loglevel=silent
    ;;

  *)
    _log "Building all modules"
    _exec npx lerna run build --concurrency=1 --stream --no-progress --loglevel=silent
    ;;
  esac
}

_copy() {
  if [ ! -d "${EXAMPLE_PROJECT_DIR}" ]; then
    errExit "Example project does not exists in ${EXAMPLE_PROJECT_DIR}"
  fi

  _log "Copying built modules to example app"
  cd core || exit 1

  _logv "Packing core..."
  core_tgz=$(npm pack 2>&1 | tail -1)
  mv "${core_tgz}" "${WS_DIR}"
  cd ../angular/dist || exit 1

  _logv "Packing angular..."
  ng_tgz=$(npm pack 2>&1 | tail -1)
  mv "${ng_tgz}" "${WS_DIR}"
  cd ../../

  local extractDest="${EXAMPLE_PROJECT_DIR}/node_modules/@ionic-super-tabs/"
  _logv "Extracting packages to ${extractDest}"

  tar xf "${WS_DIR}/${core_tgz}" -C "${extractDest}"
  cp -a "${extractDest}package/." "${extractDest}/core/"
  rm -rf "${extractDest}package"

  tar xf "${WS_DIR}/${ng_tgz}" -C "${extractDest}"
  cp -a "${extractDest}package/." "${extractDest}/angular/"
  rm -rf "${extractDest}package"

  _log "Good luck!"
}

_publish() {
  _log "Publishing all packages to npm"
  cd "${DIR}/core" || exit 1
  npm publish --access public || exit 1
  cd "${DIR}/angular/dist" || exit 1
  npm publish --access public || exit 1
  cd "${DIR}/react" || exit 1
  npm publish --access public || exit 1
}

_setupWorkspace

case $1 in
"setup")
  _exec npx lerna bootstrap
  ;;

"build")
  _build "${@:2}"
  ;;

"copy")
  _copy "${@:2}"
  ;;

"dev")
  _build --only core
  _build --only angular
  _copy
  ;;

"publish")
  _publish "${@:2}"
  ;;

"docs")
  find "${DIR}/core/src" -type f -name '*.md' | awk 'match($0, /([a-z-]+)\/readme.md/,m) { print m[1] }' | xargs -I@ cp "${DIR}/core/src/@/readme.md" "${DIR}/docs/@.md"
  ;;

"exec")
  cd "${DIR}" && _exec "${@:2}"
  ;;
*)
  _printUsage
  ;;
esac
Download .txt
gitextract_r57jfzom/

├── .dockerignore
├── .docs.yaml
├── .doctemplate
├── .drone.yml
├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .gitignore
├── CHANGELOG.md
├── Dockerfile
├── LICENSE.md
├── README.md
├── angular/
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── angular.json
│   ├── ng-package.json
│   ├── package.json
│   ├── rollup.config.js
│   ├── rollup.config.legacy.js
│   ├── src/
│   │   ├── app-init.ts
│   │   ├── directives/
│   │   │   ├── proxies-list.txt
│   │   │   ├── proxies-utils.ts
│   │   │   └── proxies.ts
│   │   ├── public-api.ts
│   │   └── super-tabs.module.ts
│   ├── tsconfig.json
│   ├── tsconfig.legacy.json
│   ├── tsconfig.lib.json
│   ├── tsconfig.lib.prod.json
│   └── tslint.json
├── core/
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── package.json
│   ├── src/
│   │   ├── components.d.ts
│   │   ├── index.ts
│   │   ├── interface.d.ts
│   │   ├── mixins.scss
│   │   ├── super-tab/
│   │   │   ├── readme.md
│   │   │   ├── super-tab.component.scss
│   │   │   └── super-tab.component.tsx
│   │   ├── super-tab-button/
│   │   │   ├── readme.md
│   │   │   ├── super-tab-button.component.scss
│   │   │   └── super-tab-button.component.tsx
│   │   ├── super-tab-indicator/
│   │   │   ├── readme.md
│   │   │   ├── super-tab-indicator.component.scss
│   │   │   └── super-tab-indicator.component.tsx
│   │   ├── super-tabs/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs.component.scss
│   │   │   └── super-tabs.component.tsx
│   │   ├── super-tabs-container/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs-container.component.scss
│   │   │   └── super-tabs-container.component.tsx
│   │   ├── super-tabs-toolbar/
│   │   │   ├── readme.md
│   │   │   ├── super-tabs-toolbar.component.scss
│   │   │   └── super-tabs-toolbar.component.tsx
│   │   ├── utils.ts
│   │   └── variables.scss
│   ├── stencil.config.ts
│   └── tsconfig.json
├── doc-pages/
│   ├── configuration.md
│   ├── getting-started/
│   │   └── angular.md
│   ├── home.md
│   └── usage/
│       └── angular.md
├── lerna.json
├── package.json
├── react/
│   ├── .gitignore
│   ├── package.json
│   ├── rollup.config.js
│   ├── src/
│   │   ├── components.ts
│   │   ├── index.ts
│   │   └── react-component-lib/
│   │       ├── createComponent.tsx
│   │       ├── createControllerComponent.tsx
│   │       ├── createOverlayComponent.tsx
│   │       ├── index.ts
│   │       └── utils/
│   │           ├── attachEventProps.ts
│   │           └── index.tsx
│   └── tsconfig.json
└── super-tabs.sh
Download .txt
SYMBOL INDEX (153 symbols across 18 files)

FILE: angular/src/app-init.ts
  function appInit (line 7) | function appInit(doc: Document, zone: NgZone) {

FILE: angular/src/directives/proxies-utils.ts
  method get (line 8) | get() { return this.el[item]; }
  method set (line 9) | set(val: any) { this.z.runOutsideAngular(() => (this.el[item] = val)); }
  function ProxyCmp (line 29) | function ProxyCmp(opts: { inputs?: any; methods?: any }) {

FILE: angular/src/directives/proxies.ts
  type SuperTab (line 8) | interface SuperTab extends Components.SuperTab {}
    method constructor (line 13) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  class SuperTab (line 11) | class SuperTab {
    method constructor (line 13) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  type SuperTabButton (line 19) | interface SuperTabButton extends Components.SuperTabButton {}
    method constructor (line 24) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  class SuperTabButton (line 22) | class SuperTabButton {
    method constructor (line 24) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  type SuperTabs (line 30) | interface SuperTabs extends Components.SuperTabs {}
    method constructor (line 36) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  class SuperTabs (line 33) | class SuperTabs {
    method constructor (line 36) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  type SuperTabsContainer (line 43) | interface SuperTabsContainer extends Components.SuperTabsContainer {}
    method constructor (line 50) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  class SuperTabsContainer (line 46) | class SuperTabsContainer {
    method constructor (line 50) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  type SuperTabsToolbar (line 57) | interface SuperTabsToolbar extends Components.SuperTabsToolbar {}
    method constructor (line 63) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
  class SuperTabsToolbar (line 60) | class SuperTabsToolbar {
    method constructor (line 63) | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {

FILE: angular/src/super-tabs.module.ts
  constant DECLARATIONS (line 6) | const DECLARATIONS = [
  class SuperTabsModule (line 19) | class SuperTabsModule {
    method forRoot (line 20) | static forRoot(): ModuleWithProviders<SuperTabsModule> {

FILE: core/src/components.d.ts
  type SuperTab (line 10) | interface SuperTab {
  type SuperTabButton (line 22) | interface SuperTabButton {
  type SuperTabIndicator (line 31) | interface SuperTabIndicator {
  type SuperTabs (line 37) | interface SuperTabs {
  type SuperTabsContainer (line 61) | interface SuperTabsContainer {
  type SuperTabsToolbar (line 88) | interface SuperTabsToolbar {
  type HTMLSuperTabElement (line 112) | interface HTMLSuperTabElement extends Components.SuperTab, HTMLStencilEl...
  type HTMLSuperTabButtonElement (line 118) | interface HTMLSuperTabButtonElement extends Components.SuperTabButton, H...
  type HTMLSuperTabIndicatorElement (line 124) | interface HTMLSuperTabIndicatorElement extends Components.SuperTabIndica...
  type HTMLSuperTabsElement (line 130) | interface HTMLSuperTabsElement extends Components.SuperTabs, HTMLStencil...
  type HTMLSuperTabsContainerElement (line 136) | interface HTMLSuperTabsContainerElement extends Components.SuperTabsCont...
  type HTMLSuperTabsToolbarElement (line 142) | interface HTMLSuperTabsToolbarElement extends Components.SuperTabsToolba...
  type HTMLElementTagNameMap (line 148) | interface HTMLElementTagNameMap {
  type SuperTab (line 158) | interface SuperTab {
  type SuperTabButton (line 166) | interface SuperTabButton {
  type SuperTabIndicator (line 175) | interface SuperTabIndicator {
  type SuperTabs (line 181) | interface SuperTabs {
  type SuperTabsContainer (line 197) | interface SuperTabsContainer {
  type SuperTabsToolbar (line 216) | interface SuperTabsToolbar {
  type IntrinsicElements (line 239) | interface IntrinsicElements {
  type IntrinsicElements (line 251) | interface IntrinsicElements {

FILE: core/src/interface.d.ts
  type SuperTabsConfig (line 6) | interface SuperTabsConfig {
  type SuperTabChangeEventDetail (line 89) | interface SuperTabChangeEventDetail {

FILE: core/src/super-tab-button/super-tab-button.component.tsx
  class SuperTabButtonComponent (line 11) | class SuperTabButtonComponent implements ComponentInterface {
    method componentDidLoad (line 33) | componentDidLoad() {
    method initCmp (line 38) | private initCmp() {
    method indexChildren (line 56) | private indexChildren() {
    method render (line 61) | render() {

FILE: core/src/super-tab-indicator/super-tab-indicator.component.tsx
  class SuperTabIndicatorComponent (line 9) | class SuperTabIndicatorComponent implements ComponentInterface {
    method render (line 17) | render() {

FILE: core/src/super-tab/super-tab.component.tsx
  class SuperTabComponent (line 10) | class SuperTabComponent implements ComponentInterface {
    method componentDidLoad (line 27) | componentDidLoad() {
    method componentDidUpdate (line 31) | componentDidUpdate() {
    method checkIonContent (line 40) | private checkIonContent() {
    method getRootScrollableEl (line 54) | async getRootScrollableEl(): Promise<HTMLElement | null> {
    method render (line 72) | render() {

FILE: core/src/super-tabs-container/super-tabs-container.component.tsx
  class SuperTabsContainerComponent (line 22) | class SuperTabsContainerComponent implements ComponentInterface {
    method componentDidLoad (line 74) | async componentDidLoad() {
    method onSlotChange (line 82) | private async onSlotChange() {
    method componentDidRender (line 88) | async componentDidRender() {
    method reindexTabs (line 96) | async reindexTabs() {
    method moveContainerByIndex (line 109) | moveContainerByIndex(index: number, animate?: boolean): Promise<void> {
    method moveContainer (line 127) | moveContainer(scrollX: number, animate?: boolean): Promise<void> {
    method setActiveTabIndex (line 139) | async setActiveTabIndex(index: number, moveContainer: boolean = true, ...
    method scrollToTop (line 161) | async scrollToTop() {
    method updateActiveTabIndex (line 182) | private updateActiveTabIndex(index: number, emit: boolean = true) {
    method updateSelectedTabIndex (line 191) | private updateSelectedTabIndex(index: number) {
    method onTouchStart (line 201) | async onTouchStart(ev: TouchEvent) {
    method onClick (line 238) | async onClick(ev: TouchEvent) {
    method onTouchMove (line 246) | async onTouchMove(ev: TouchEvent) {
    method onTouchEnd (line 293) | async onTouchEnd(ev: TouchEvent) {
    method updateWidth (line 320) | private updateWidth() {
    method indexTabs (line 325) | private async indexTabs() {
    method lazyLoadTabs (line 372) | private lazyLoadTabs() {
    method calcSelectedTab (line 409) | private calcSelectedTab(): number {
    method positionToIndex (line 414) | private positionToIndex(scrollX: number) {
    method indexToPosition (line 419) | private indexToPosition(tabIndex: number) {
    method normalizeSelectedTab (line 423) | private normalizeSelectedTab(index: number): number {
    method debug (line 431) | private debug(...vals: any[]) {
    method render (line 435) | render() {

FILE: core/src/super-tabs-toolbar/super-tabs-toolbar.component.tsx
  class SuperTabsToolbarComponent (line 24) | class SuperTabsToolbarComponent implements ComponentInterface {
    method componentDidLoad (line 99) | async componentDidLoad() {
    method componentWillUpdate (line 112) | componentWillUpdate() {
    method componentDidRender (line 117) | componentDidRender() {
    method updateWidth (line 121) | private updateWidth() {
    method setActiveTab (line 129) | setActiveTab(index: number, align?: boolean, animate?: boolean): Promi...
    method setSelectedTab (line 146) | setSelectedTab(index: number, animate?: boolean): Promise<void> {
    method moveContainer (line 153) | moveContainer(scrollX: number, animate?: boolean): Promise<void> {
    method getButtonFromEv (line 163) | private getButtonFromEv(ev: any): HTMLSuperTabButtonElement | undefined {
    method onClick (line 180) | onClick(ev: any) {
    method onButtonClick (line 199) | private onButtonClick(button: HTMLSuperTabButtonElement) {
    method onTouchStart (line 206) | async onTouchStart(ev: TouchEvent) {
    method onTouchMove (line 227) | async onTouchMove(ev: TouchEvent) {
    method onTouchEnd (line 284) | async onTouchEnd(ev: TouchEvent) {
    method onColorUpdate (line 304) | async onColorUpdate() {
    method setHostCls (line 308) | private setHostCls() {
    method onSlotChange (line 318) | private async onSlotChange() {
    method queryButtons (line 325) | private async queryButtons() {
    method updateThresholds (line 346) | private updateThresholds() {
    method markButtonActive (line 360) | private markButtonActive(button: HTMLSuperTabButtonElement) {
    method setButtonsContainerEl (line 374) | private setButtonsContainerEl(el: HTMLDivElement) {
    method adjustContainerScroll (line 380) | private adjustContainerScroll(animate: boolean) {
    method alignIndicator (line 423) | private async alignIndicator(index: number, animate: boolean = false) {
    method debug (line 477) | private debug(...vals: any[]) {
    method render (line 481) | render() {

FILE: core/src/super-tabs/super-tabs.component.tsx
  class SuperTabsComponent (line 30) | class SuperTabsComponent implements ComponentInterface {
    method constructor (line 68) | constructor() {
    method setConfig (line 79) | async setConfig(config: SuperTabsConfig) {
    method propagateConfig (line 83) | private propagateConfig() {
    method selectTab (line 96) | async selectTab(index: number, animate: boolean = true, emit: boolean ...
    method onConfigChange (line 119) | async onConfigChange(config: SuperTabsConfig) {
    method onWindowResize (line 124) | onWindowResize() {
    method componentWillLoad (line 130) | async componentWillLoad() {
    method componentDidLoad (line 136) | componentDidLoad() {
    method initComponent (line 159) | private initComponent() {
    method setupEventListeners (line 190) | private async setupEventListeners() {
    method onContainerSelectedTabChange (line 207) | private async onContainerSelectedTabChange(ev: any) {
    method emitTabChangeEvent (line 215) | private emitTabChangeEvent(newIndex: number, oldIndex?: number) {
    method onContainerActiveTabChange (line 230) | private onContainerActiveTabChange(ev: any) {
    method onToolbarButtonClick (line 241) | private onToolbarButtonClick(ev: any) {
    method indexChildren (line 253) | private indexChildren() {
    method onSlotchange (line 270) | private async onSlotchange() {
    method debug (line 281) | private debug(...vals: any[]) {
    method render (line 285) | render() {

FILE: core/src/utils.ts
  constant DEFAULT_CONFIG (line 4) | const DEFAULT_CONFIG: SuperTabsConfig = {
  type STCoord (line 17) | type STCoord = {
  function pointerCoord (line 22) | function pointerCoord(ev: any): STCoord {
  function getScrollCoord (line 52) | function getScrollCoord(start: number, dest: number, startTime: number, ...
  function scroll (line 58) | function scroll(el: Element, startX: number, x: number, startTime: numbe...
  function checkGesture (line 94) | function checkGesture(newCoords: STCoord, initialCoords: STCoord, config...
  function getNormalizedScrollX (line 116) | function getNormalizedScrollX(el: HTMLElement, width: number, delta: num...
  function debugLog (line 123) | function debugLog(config: SuperTabsConfig, tag: string, vals: any[]) {

FILE: react/src/react-component-lib/createComponent.tsx
  type IonicReactInternalProps (line 10) | interface IonicReactInternalProps<ElementType> extends React.HTMLAttribu...
  method constructor (line 21) | constructor(props: IonicReactInternalProps<ElementType>) {
  method componentDidMount (line 26) | componentDidMount() {
  method componentDidUpdate (line 30) | componentDidUpdate(prevProps: IonicReactInternalProps<ElementType>) {
  method render (line 35) | render() {
  method displayName (line 64) | static get displayName() {

FILE: react/src/react-component-lib/createControllerComponent.tsx
  type LoadingElement (line 4) | interface LoadingElement {
  type ReactControllerProps (line 9) | interface ReactControllerProps<E> {
  function createControllerComponent (line 14) | function createControllerComponent<

FILE: react/src/react-component-lib/createOverlayComponent.tsx
  type LoadingElement (line 5) | interface LoadingElement {
  type ReactOverlayProps (line 9) | interface ReactOverlayProps<E> {
  function createOverlayComponent (line 15) | function createOverlayComponent<

FILE: react/src/react-component-lib/utils/attachEventProps.ts
  function attachEventProps (line 1) | function attachEventProps(node: HTMLElement, newProps: any, oldProps: an...
  function getClassName (line 24) | function getClassName(classList: DOMTokenList, newProps: any, oldProps: ...
  function isCoveredByReact (line 50) | function isCoveredByReact(eventNameSuffix: string, doc: Document = docum...
  function syncEvent (line 63) | function syncEvent(node: Element, eventName: string, newEventHandler: (e...
  function arrayToMap (line 83) | function arrayToMap(arr: string[] | DOMTokenList) {

FILE: react/src/react-component-lib/utils/index.tsx
  type ReactProps (line 10) | interface ReactProps {
  type IonicReactExternalProps (line 14) | type IonicReactExternalProps<PropType, ElementType> = PropType & React.H...
Condensed preview — 77 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (147K chars).
[
  {
    "path": ".dockerignore",
    "chars": 250,
    "preview": ".git\n.idea\nDockerfile\n.docs.yaml\n.drone.yml\n.gitignore\nREADME.md\nsuper-tabs.sh\ndocs\nnode_modules\ncore/node_modules\ncore/"
  },
  {
    "path": ".docs.yaml",
    "chars": 1424,
    "preview": "siteTitle: Super Tabs\ndescription: Swipeable tabs for Ionic apps\nrepo: https://github.com/zyra/ionic-super-tabs\noutDir: "
  },
  {
    "path": ".doctemplate",
    "chars": 6815,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>{{- .Title }}</title>\n    {{ if .Descripti"
  },
  {
    "path": ".drone.yml",
    "chars": 1384,
    "preview": "---\nkind: pipeline\ntype: docker\nname: default\n\nclone:\n  depth: 1\n\nvolumes:\n- name: dockersock\n  host:\n    path: /var/run"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".gitignore",
    "chars": 34,
    "preview": "node_modules\n.idea\n.DS_STORE\ndocs\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 424,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "Dockerfile",
    "chars": 81,
    "preview": "FROM node:12-alpine\nCOPY . .\nRUN npm i\nRUN npx lerna bootstrap\nRUN npm run build\n"
  },
  {
    "path": "LICENSE.md",
    "chars": 1072,
    "preview": "MIT License\n\nCopyright (c) 2019 Zyra Media Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a"
  },
  {
    "path": "README.md",
    "chars": 2021,
    "preview": "# Super Tabs\nSwipeable tabs module for Ionic apps.\n\n* [Packages](#packages)\n  * [Ionic 4](#ionic-4)\n  * [Ionic 2 / Ionic"
  },
  {
    "path": "angular/.gitignore",
    "chars": 24,
    "preview": "build\nnode_modules\ndist\n"
  },
  {
    "path": "angular/CHANGELOG.md",
    "chars": 324,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "angular/angular.json",
    "chars": 676,
    "preview": "{\n  \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n  \"version\": 1,\n  \"newProjectRoot\": \"projects\",\n  \""
  },
  {
    "path": "angular/ng-package.json",
    "chars": 214,
    "preview": "{\n  \"$schema\": \"./node_modules/ng-packagr/ng-package.schema.json\",\n  \"dest\": \"./dist/\",\n  \"lib\": {\n    \"entryFile\": \"src"
  },
  {
    "path": "angular/package.json",
    "chars": 1280,
    "preview": "{\n  \"name\": \"@ionic-super-tabs/angular\",\n  \"version\": \"7.0.8\",\n  \"description\": \"Ionic Super Tabs bindings for Angular a"
  },
  {
    "path": "angular/rollup.config.js",
    "chars": 457,
    "preview": "import resolve from 'rollup-plugin-node-resolve';\n\nexport default {\n  input: 'build/es2015/core.js',\n  output: [\n    {\n "
  },
  {
    "path": "angular/rollup.config.legacy.js",
    "chars": 274,
    "preview": "import config from './rollup.config';\n\nconst newConfig = {\n  ...config,\n  input: 'build/es5/core.js',\n};\n\nnewConfig.outp"
  },
  {
    "path": "angular/src/app-init.ts",
    "chars": 1258,
    "preview": "import { NgZone } from '@angular/core';\nimport { applyPolyfills, defineCustomElements } from '@ionic-super-tabs/core/loa"
  },
  {
    "path": "angular/src/directives/proxies-list.txt",
    "chars": 157,
    "preview": "\nimport * as d from './proxies';\n\nexport const DIRECTIVES = [\nd.SuperTab,\n  d.SuperTabButton,\n  d.SuperTabs,\n  d.SuperTa"
  },
  {
    "path": "angular/src/directives/proxies-utils.ts",
    "chars": 1161,
    "preview": "/* tslint:disable */\nimport { fromEvent } from 'rxjs';\n\nexport const proxyInputs = (Cmp: any, inputs: string[]) => {\n  c"
  },
  {
    "path": "angular/src/directives/proxies.ts",
    "chars": 3233,
    "preview": "/* tslint:disable */\n/* auto-generated angular directive proxies */\nimport { ChangeDetectionStrategy, ChangeDetectorRef,"
  },
  {
    "path": "angular/src/public-api.ts",
    "chars": 93,
    "preview": "export * from './directives/proxies';\nexport { SuperTabsModule } from './super-tabs.module';\n"
  },
  {
    "path": "angular/src/super-tabs.module.ts",
    "chars": 839,
    "preview": "import { CommonModule, DOCUMENT } from '@angular/common';\nimport { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZon"
  },
  {
    "path": "angular/tsconfig.json",
    "chars": 706,
    "preview": "{\n  \"compileOnSave\": false,\n  \"compilerOptions\": {\n    \"baseUrl\": \"./\",\n    \"outDir\": \"./dist/out-tsc\",\n    \"sourceMap\":"
  },
  {
    "path": "angular/tsconfig.legacy.json",
    "chars": 145,
    "preview": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"declarationDir\": \"build/es5\",\n    \"ou"
  },
  {
    "path": "angular/tsconfig.lib.json",
    "chars": 427,
    "preview": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./out-tsc/lib\",\n    \"target\": \"es2015\",\n    \"dec"
  },
  {
    "path": "angular/tsconfig.lib.prod.json",
    "chars": 97,
    "preview": "{\n  \"extends\": \"./tsconfig.lib.json\",\n  \"angularCompilerOptions\": {\n    \"enableIvy\": false\n  }\n}\n"
  },
  {
    "path": "angular/tslint.json",
    "chars": 1761,
    "preview": "{\n  \"extends\": \"tslint:recommended\",\n  \"rulesDirectory\": [\n    \"codelyzer\"\n  ],\n  \"rules\": {\n    \"array-type\": false,\n  "
  },
  {
    "path": "core/.gitignore",
    "chars": 53,
    "preview": "node_modules\ndist\nstats.json\n.stencil\nloader\nhydrate\n"
  },
  {
    "path": "core/CHANGELOG.md",
    "chars": 424,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "core/package.json",
    "chars": 860,
    "preview": "{\n  \"name\": \"@ionic-super-tabs/core\",\n  \"version\": \"7.0.8\",\n  \"description\": \"\",\n  \"main\": \"dist/index.js\",\n  \"module\": "
  },
  {
    "path": "core/src/components.d.ts",
    "chars": 11011,
    "preview": "/* eslint-disable */\n/* tslint:disable */\n/**\n * This is an autogenerated file created by the Stencil compiler.\n * It co"
  },
  {
    "path": "core/src/index.ts",
    "chars": 89,
    "preview": "export { DEFAULT_CONFIG } from './utils';\nexport { SuperTabsConfig } from './interface';\n"
  },
  {
    "path": "core/src/interface.d.ts",
    "chars": 2218,
    "preview": "export * from './components';\n\n/**\n * Configuration object for the `super-tabs` component.\n */\nexport interface SuperTab"
  },
  {
    "path": "core/src/mixins.scss",
    "chars": 1239,
    "preview": "@import \"./variables\";\n\n@mixin st-button-variables() {\n  --st-base-color-active: #{$st-button-base-color-active};\n  --st"
  },
  {
    "path": "core/src/super-tab/readme.md",
    "chars": 2286,
    "preview": "# super-tab\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property                | Attribute   | Description     "
  },
  {
    "path": "core/src/super-tab/super-tab.component.scss",
    "chars": 855,
    "preview": "@import \"../variables\";\n\n:host {\n  /**\n  * @prop --super-tab-width: Width of the tab. Defaults to `100vw`.\n  * @prop --s"
  },
  {
    "path": "core/src/super-tab/super-tab.component.tsx",
    "chars": 1902,
    "preview": "import { Component, ComponentInterface, Element, h, Host, Method, Prop } from '@stencil/core';\n\n\n@Component({\n  tag: 'su"
  },
  {
    "path": "core/src/super-tab-button/readme.md",
    "chars": 2326,
    "preview": "# super-tab-button\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property   | Attribute  | Description            "
  },
  {
    "path": "core/src/super-tab-button/super-tab-button.component.scss",
    "chars": 4039,
    "preview": "@import \"../variables\";\n\n@mixin labelIcon {\n  ion-label, ion-icon, ::slotted(ion-label), ::slotted(ion-icon) {\n    @cont"
  },
  {
    "path": "core/src/super-tab-button/super-tab-button.component.tsx",
    "chars": 2029,
    "preview": "import { Component, ComponentInterface, Element, h, Host, Prop, State } from '@stencil/core';\n\n\nconst maxRetryAttempts ="
  },
  {
    "path": "core/src/super-tab-indicator/readme.md",
    "chars": 817,
    "preview": "# super-tab-indicator\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property          | Attribute          | Descr"
  },
  {
    "path": "core/src/super-tab-indicator/super-tab-indicator.component.scss",
    "chars": 755,
    "preview": "@import \"../variables\";\n\n:host {\n  display: block;\n  height: var(--st-indicator-height, $st-indicator-height);\n  width: "
  },
  {
    "path": "core/src/super-tab-indicator/super-tab-indicator.component.tsx",
    "chars": 609,
    "preview": "import { Component, ComponentInterface, h, Host, Prop } from '@stencil/core';\n\n\n@Component({\n  tag: 'super-tab-indicator"
  },
  {
    "path": "core/src/super-tabs/readme.md",
    "chars": 2444,
    "preview": "# super-tabs\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property         | Attribute          | Description    "
  },
  {
    "path": "core/src/super-tabs/super-tabs.component.scss",
    "chars": 437,
    "preview": ":host {\n  height: 100%;\n  max-height: 100%;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n  z-index: 1;"
  },
  {
    "path": "core/src/super-tabs/super-tabs.component.tsx",
    "chars": 7774,
    "preview": "import {\n  Component,\n  ComponentInterface,\n  Element,\n  Event,\n  EventEmitter,\n  h,\n  Host,\n  Listen,\n  Method,\n  Prop,"
  },
  {
    "path": "core/src/super-tabs-container/readme.md",
    "chars": 2414,
    "preview": "# super-tabs-container\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property        | Attribute         | Descrip"
  },
  {
    "path": "core/src/super-tabs-container/super-tabs-container.component.scss",
    "chars": 579,
    "preview": "@import \"../variables\";\n\n:host {\n  display: flex;\n  flex-flow: row nowrap;\n  min-width: 100%;\n  flex: 1 1 auto;\n  positi"
  },
  {
    "path": "core/src/super-tabs-container/super-tabs-container.component.tsx",
    "chars": 11691,
    "preview": "import {\n  Component,\n  ComponentInterface,\n  Element,\n  Event,\n  EventEmitter,\n  h,\n  Listen,\n  Method,\n  Prop,\n  Queue"
  },
  {
    "path": "core/src/super-tabs-toolbar/readme.md",
    "chars": 3320,
    "preview": "# super-tabs-toolbar\n\n\n\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property            | Attribute            | De"
  },
  {
    "path": "core/src/super-tabs-toolbar/super-tabs-toolbar.component.scss",
    "chars": 1878,
    "preview": "@import \"../variables\";\n\n:host {\n  /**\n   * @prop --super-tabs-toolbar-background: Toolbar background color. Defaults to"
  },
  {
    "path": "core/src/super-tabs-toolbar/super-tabs-toolbar.component.tsx",
    "chars": 13056,
    "preview": "import {\n  Component,\n  ComponentInterface,\n  Element,\n  Event,\n  EventEmitter,\n  h,\n  Host,\n  Listen,\n  Method,\n  Prop,"
  },
  {
    "path": "core/src/utils.ts",
    "chars": 3965,
    "preview": "import { SuperTabsConfig } from './interface';\n\n\nexport const DEFAULT_CONFIG: SuperTabsConfig = {\n  dragThreshold: 20,\n "
  },
  {
    "path": "core/src/variables.scss",
    "chars": 1375,
    "preview": "/**\n * super-tab-button variables\n */\n\n/// @prop - Active color of a toolbar button\n$st-button-base-color-active: #{var("
  },
  {
    "path": "core/stencil.config.ts",
    "chars": 1336,
    "preview": "import { angularOutputTarget } from '@stencil/angular-output-target';\nimport { Config } from '@stencil/core';\nimport { r"
  },
  {
    "path": "core/tsconfig.json",
    "chars": 743,
    "preview": "{\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"alwaysStrict\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"al"
  },
  {
    "path": "doc-pages/configuration.md",
    "chars": 2330,
    "preview": "# Configuration\n\nConfiguring ***Super Tabs*** can be done by setting the `config` property on a `<super-tab>` element.\n\n"
  },
  {
    "path": "doc-pages/getting-started/angular.md",
    "chars": 911,
    "preview": "# Getting Started with Angular\n\n## Installation\n\n#### 1. Install the module\n```shell\nnpm i --save @ionic-super-tabs/angu"
  },
  {
    "path": "doc-pages/home.md",
    "chars": 982,
    "preview": "# Super Tabs\nSwipeable tabs for Ionic apps\n\n## Introduction\n***Super Tabs*** is a set of web components to build swipe-a"
  },
  {
    "path": "doc-pages/usage/angular.md",
    "chars": 2896,
    "preview": "# Angular Usage Guide\n\n* [Basic usage](usage/angular/#basic-usage)\n* [Scrollable toolbar](usage/angular/#scrollable-tool"
  },
  {
    "path": "lerna.json",
    "chars": 106,
    "preview": "{\n  \"lerna\": \"2.11.0\",\n  \"packages\": [\n    \"angular\",\n    \"core\",\n    \"react\"\n  ],\n  \"version\": \"7.0.8\"\n}\n"
  },
  {
    "path": "package.json",
    "chars": 357,
    "preview": "{\n  \"name\": \"@ionic-super-tabs/source\",\n  \"version\": \"0.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"bootstrap\": \"lern"
  },
  {
    "path": "react/.gitignore",
    "chars": 34,
    "preview": "dist\ndist-transpiled\nnode_modules\n"
  },
  {
    "path": "react/package.json",
    "chars": 1119,
    "preview": "{\n  \"name\": \"@ionic-super-tabs/react\",\n  \"version\": \"7.0.8\",\n  \"description\": \"Ionic Super Tabs bindings for React appli"
  },
  {
    "path": "react/rollup.config.js",
    "chars": 601,
    "preview": "// borrowed from https://github.com/ionic-team/ionic/blob/930b271a4abf680b08e6755644cece4b95053f15/packages/react/rollup"
  },
  {
    "path": "react/src/components.ts",
    "chars": 965,
    "preview": "/* eslint-disable */\n/* tslint:disable */\n/* auto-generated react proxies */\nimport { createReactComponent } from './rea"
  },
  {
    "path": "react/src/index.ts",
    "chars": 30,
    "preview": "export * from './components';\n"
  },
  {
    "path": "react/src/react-component-lib/createComponent.tsx",
    "chars": 2070,
    "preview": "import React from 'react';\n\nimport {\n  attachEventProps,\n  createForwardRef,\n  dashToPascalCase,\n  isCoveredByReact,\n} f"
  },
  {
    "path": "react/src/react-component-lib/createControllerComponent.tsx",
    "chars": 1810,
    "preview": "import React from 'react';\nimport { attachEventProps } from './utils/attachEventProps';\n\ninterface LoadingElement {\n  pr"
  },
  {
    "path": "react/src/react-component-lib/createOverlayComponent.tsx",
    "chars": 2045,
    "preview": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { attachEventProps } from './utils/attachEventProps'"
  },
  {
    "path": "react/src/react-component-lib/index.ts",
    "chars": 198,
    "preview": "export { createReactComponent } from './createComponent';\nexport { createControllerComponent } from './createControllerC"
  },
  {
    "path": "react/src/react-component-lib/utils/attachEventProps.ts",
    "chars": 3070,
    "preview": "export function attachEventProps(node: HTMLElement, newProps: any, oldProps: any = {}) {\n  const className = getClassNam"
  },
  {
    "path": "react/src/react-component-lib/utils/index.tsx",
    "chars": 798,
    "preview": "import React from 'react';\n\nexport const dashToPascalCase = (str: string) =>\n  str\n    .toLowerCase()\n    .split('-')\n  "
  },
  {
    "path": "react/tsconfig.json",
    "chars": 784,
    "preview": "{\n  \"compilerOptions\": {\n    \"strict\": false,\n    \"allowUnreachableCode\": false,\n    \"allowSyntheticDefaultImports\": tru"
  },
  {
    "path": "super-tabs.sh",
    "chars": 4947,
    "preview": "#!/bin/bash\n\nDIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" >/dev/null 2>&1 && pwd)\"\nWORK_DIR=${TMP:-$DIR}\nWS_DIR=\"${WORK_DI"
  }
]

About this extraction

This page contains the full source code of the zyra/ionic2-super-tabs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 77 files (133.4 KB), approximately 36.1k tokens, and a symbol index with 153 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!