0.9.5 • Published 4 years ago

newton-component-utils v0.9.5

Weekly downloads
-
License
Apache 2.0
Repository
github
Last release
4 years ago

Newton Component Utils

A series of extras and helper components and utilities that can be used to ease implementing a number of services.

Feature Flags

newton-component-utils provides a FeaturesObserver, this is a subclass of MutationObserver that automates HTMLElement visibility based upon a loaded configuration file.

You can have multiple FeatureObservers if you like, each one can have it's own FeatureSet and root Element, this can be useful for larger, more modular applications and sites that might want more fine-grain control over what scope a single 'FeatureSet' might have.

It's important to note that currently, the FeatureObserver works by applying / removing an Elements hidden attribute, a consuming application should implement a CSS override to ensure this attribute is respected and not overridden, i.e.:

[hidden] {
   display: none !important;
}

Configuration

ANY DOM element could be considered a 'Feature', in order to mark it so that the FeaturesObserver can find it, you should add a data-feature="feature-name" attribute to the Features' outer HTML container, i.e:

<div data-feature="some-awesome-feature">
  <p>I'm an awesome feature...but am I enabled?
</div>

You can have nested features, or multiples of the same identifier. If you nest features and turn the parent feature off, all child features will be hidden too.

A number of options are supported, including either platform-ignorant or platform-specific availability, a meta-description of a 'Feature', simple versioning and status indication are also present (though the latter two are currently simply for developer awareness), these are provided via a configuration object, a typical example would look something like this:

{
  "featureset": {
    "version": "1",
    "status": "most_recent",
    "features": [
      {
        "id": "testfeature-android-tablet",
        "active": ["android", "tablet"],
        "description":
          "Sample component to illustrate active only on android tablet"
      },
      {
        "id": "testfeature-android-phone",
        "active": ["android", "mobile"],
        "description":
          "Sample component to illustrate active only on android mobile"
      },
      {
        "id": "testfeature-ios",
        "active": "ios",
        "description": "Sample component to illustrate active only on iOS"
      },
      {
        "id": "health-connector-fitbit",
        "active": true,
        "description":
          "OAuth Connector Component to trigger authentication workflow for Fitbit"
      },
      {
        "id": "health-connector-googlefit",
        "active": "android",
        "description":
          "OAuth Connector Component to trigger authentication workflow for Google Fit"
      },
      {
        "id": "health-connector-applehealth",
        "active": "iphone",
        "description":
          "Connector Component to trigger authentication workflow for Apple Health App"
      }
    ]
  }
}

The interface for this configuration object is:

FeatureSet {
  version: string;
  status: FeatureSetStatus;
  features: Feature[];
}

Where status can be one of: 'SUPPORTED' | 'DEPRECATED'| 'MOST_RECENT'

A Feature looks like this:

Feature {
  id: string;
  active: boolean | FeaturePlatform | FeaturePlatform[];
  description?: string;
}

Where FeaturePlatform can be any one or combination of the following: 'ios' | 'android' | 'tablet' | 'mobile' | 'iphone' | 'ipad'

If you specifiy a boolean true|false instead, platform type is ignored and the feature is globablly either available or hidden.

Beyond the configuration object, the observer instance is configured on instantiation using the following object interface:

FeaturesObserverConfig {
  root: Element;
  displayAllOnNoFeatureSet?: boolean;
}

This gives the defaulting-to-false option of disabling all Features if no configuration object can be loaded - reasoning is that it gives maximum safety in a mainline development environment and should only be overridden in local development, unless there is a project-specific requirement.