1.5.0 • Published 3 years ago

@apollo-elements/interfaces v1.5.0

Weekly downloads
48
License
ISC
Repository
github
Last release
3 years ago

Maintained with Lerna Contributions Welcome Actions Status Test Coverage Demo Online

📓 Contents

📑 API Docs

If you just want to see the API Docs, check them out for all our packages at apolloelements.dev

🤖 Demo

#leeway is a progressive web app that uses lit-apollo to make it easier for you to avoid doing actual work. Check out the source repo for an example of how to build apps with Apollo Elements. The demo includes:

  • SSR
  • Code Splitting
  • Aggressive minification, including lit-html template literals
  • CSS-in-CSS ( e.g. import shared from '../shared-styles.css';)
  • GQL-in-GQL ( e.g. import query from './my-component-query.graphql';)
  • GraphQL Subscriptions over websocket

Lighthouse Scores: 98 (performance), 100 (accessibility), 93 (best practises), 100 (SEO), 12/12 (PWA)

📦 Packages

Apollo Elements offers packages based on a variety of underlying web component authoring libraries. You can pick the one that suits your project in order to keep your app sizes small.

🔥 lit-apollo

These base classes extend from LitElement, so you can quickly get up and running creating declarative front-ends with Apollo GraphQL.

npm i -S @apollo-elements/lit-apollo
<!-- index.html -->
<script type="module" src="app.bundle.js"></script>
<script nomodule src="app.bundle.system.js"></script>
<apollo-app>
  <script type="application/graphql">
    query {
      helloWorld {
        greeting
        name
      }
    }
  </script>
</apollo-app>
// app.js
import gql from 'graphql-tag'
import { ApolloQuery, html } from '@apollo-elements/lit-apollo';
import { client } from './apollo-client';
import { render } from ''

customElements.define('apollo-app', class ApolloApp extends ApolloQuery {
  render() {
    const { data, error, loading } = this;
    return (
        loading ? html`<what-spin></what-spin>`
      : error ? html` <h1>😢 Such Sad, Very Error! 😰</h1> <div>${error.message}</div>`
      : html`<div>${data.helloWorld.greeting}, ${helloWorld.name}</div>`
    );
   }
});

👩‍🔬 gluon

These base classes extend from GluonElement, a simplified wc library that uses lit-html for templating while keeping component state and lifecycle concerns 'close to the metal'.

npm i -S @apollo-elements/gluon
import gql from 'graphql-tag'
import { ApolloQuery, html } from '@apollo-elements/gluon';
import { client } from './apollo-client';

customElements.define('apollo-app', class ApolloApp extends ApolloQuery {
  get template() {
    const { data, error, loading } = this;
    return (
        loading ? html`<what-spin></what-spin>`
      : error ? html` <h1>😢 Such Sad, Very Error! 😰</h1> <div>${error.message}</div>`
      : html`<div>${data.helloWorld.greeting}, ${helloWorld.name}</div>`
    );
   }
});

🦄 hybrids

A set of objects you can roll into your hybrids to make it easier to connect to your Apollo cache.

npm i -S @apollo-elements/hybrids
import { ApolloQuery, queryFactory, define, html } from '@apollo-elements/hybrids';
import gql from 'graphql-tag';

export const ConnectedElement = {
  ...ApolloQuery,
  query: queryFactory(gql`query { hello }`),
  render: ({data}) => html`<div>${data.hello}</div>`
};

define('connected-element', ConnectedElement);

🧱 polymer

These custom elements fire polymer-style *-changed events when the Apollo cache updates their state. They extend directly from HTMLElement so they're small in size, and their notifying properties make them perfect for use in Polymer templates.

npm i -S @apollo-elements/polymer
// app.js
import { client } from './apollo-client.js'
import '@apollo-elements/polymer/apollo-query.js';
window.__APOLLO_CLIENT__ = client
import { PolymerElement, html } from '@polymer/polymer';
import '@apollo-elements/polymer/apollo-query.js';
import '@polymer/paper-card/paper-card.js';

customElements.define('my-app', class MyTemplate extends PolymerElement {
  static get template() {
    return html`
    <apollo-query data="{{data}}" variables="[[variables]]">
      <script type="application/graphql">
        query User($id: ID!)
          user(id: $id) {
            name
            picture
          }
        }
      </script>
    </apollo-query>

    <paper-card heading="[[data.name]]" image="[[data.picture]]"></paper-card>
    `;
  }

  static get properties() {
    return {
      variables: {
        type: Object,
        value: () => ({id: ''});
      }
    }
  }

  async connectedCallback() {
    super.connectedCallback();
    const { id = '' } = await getToken();
    this.variables = { id };
  }
}

🍸 mixins

These custom element class mixins give you all the features you need to connect your components to your Apollo cache without imposing a specific component library.

npm i -S @apollo-elements/mixins
import { ApolloQueryMixin } from '@apollo-elements/mixins/apollo-query-mixin.js';

customElements.define('vanilla-query', class VanillaQuery extends ApolloQueryMixin(HTMLElement) {
  get data() {
    return this.__data;
  }

  set data(data) {
    this.__data = data;
    this.shadowRoot.innerText = `${data.helloWorld.greeting}, ${data.helloWorld.name}`;
  }
});

🗞 Bundling

Apollo Elements uses Object.fromEntries and object spread syntax, so you may need to transpile and polyfill those features in these packages.

Since Apollo client cannot be imported directly into the browser, you must transpile and bundle apollo-client in order to use it in your app. We recommend using Rollup for this. Your rollup.config.js might look something like this:

// necessary for apollo
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
// optional, but nice
import litcss from 'rollup-plugin-lit-css';
import graphql from '@kocal/rollup-plugin-graphql';

export default {
  input: [
    'src/components/app-shell/app-shell.js',
    'src/components/app-view1/app-view1.js',
    'src/components/app-view2/app-view2.js',
    'src/components/app-view404/app-view404.js',
  ],

  output: [{
    dir: 'build',
    format: 'es',
    sourcemap: true,
  }, {
    dir: 'build/nomodule',
    format: 'system',
    sourcemap: true,
  }],

  plugins: [
    resolve(),
    commonjs(),
  ]
}

Alternatively, you might bundle and export your Apollo client separately, then import it into your browser-friendly component modules.

😎 Cool Tricks

📜 Inline Query Scripts

You can provide a GraphQL query string in your markup by appending a GraphQL script element to your connected element, like so:

<apollo-app>
  <script type="application/graphql">
    query {
      helloWorld {
        name
        greeting
      }
    }
  </script>
</apollo-app>

👷‍♂️ Maintainers

apollo-elements is a community project maintained by Benny Powers.

Contact me on Codementor

1.5.0-alpha.0

3 years ago

1.5.0

3 years ago

1.4.3

3 years ago

1.4.2

3 years ago

1.4.1

3 years ago

1.4.0

3 years ago

1.4.0-alpha.2

3 years ago

1.4.0-alpha.1

3 years ago

1.4.0-alpha.0

3 years ago

1.3.0

3 years ago

1.2.0

4 years ago

1.1.0

4 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

1.0.0-alpha.8

4 years ago

1.0.0-alpha.7

4 years ago

1.0.0-alpha.6

4 years ago

1.0.0-alpha.4

4 years ago

1.0.0-alpha.3

4 years ago

1.0.0-alpha.1

4 years ago

1.0.0-alpha.0

4 years ago