Settings API
chevron down
 

Settings API

Overview

Fitbit developers can make their application configurable by users, by creating application settings.

Application settings are written using JSX.

A compiled settings.js file is registered into the Fitbit mobile application during the application installation process.

General Tips

settingsKey will manage the settings storage and retrieval for you, but you can still manage them yourself. The following are equivalent:

<ColorSelect
  settingsKey="color"
/>
<ColorSelect
  value={props.settings.color}
  onChange={value => props.settingsStorage.setItem('color', value)}
/>

Components

The Settings API provides a number of predefined components.

Section

Creates an element which can be used as a container section for other elements.

Basic Usage

<Section
  description={<Text> Description <Link source="/">here</Link></Text>}
  title={<Text bold align="center">Demo Settings</Text>}>
  <Text>
    This is a very basic demo settings page to show off some of the current
    capabilities of the Companion Settings library.
  </Text>
</Section>

Properties

  • title takes a string, the text that appears above the content block.

  • description takes a string, the subtext that appears below the content block.

Create a hyperlink to an anchor or URL.

Basic Usage

<Link source="...">InnerHTML</Link>

Properties

  • source takes a string, the web address to link to.

Example Use Cases

External links, must be HTTP/HTTPS:

<Link source="https://www.google.com">Google</Link>

Tip: Use with the <Text> element for additional formatting options.

Text

Create a paragraph of text. Supports rich formatting.

Basic Usage

<Text>Your Text Here</Text>

Properties

  • bold if present, the inner text will appear bold.

  • italic if present, the inner text will appear italic.

  • align: left | center | right, sets the horizontal alignment of text.

Example Use Cases

<Text align="right">This text will align to the right side</Text>
<Text italic>This text is italicized.</Text>
<Text align="center">This text will be centered and <Text bold>bold</Text></Text>

Tip: Text is intended to appear inside a <Section> or <List>.

TextImageRow

Creates a row containing a label, sublabel, and optional icon image.

Basic Usage

<TextImageRow
  label="Example"
  sublabel="here it is"
/>

Properties

  • label takes a string, appears as the main text.

  • sublabel takes a string, appears as the gray subtext under the label.

  • icon takes a string, URL for the icon image

Example Use Cases

<TextImageRow
  label="San Francisco"
  sublabel="CA"
  icon="https://tinyurl.com/ybbmpxxq"
/>

Tip: Intended for use in a <List> or <Select>.

Button

Creates a simple button, similar to the

Basic Usage

<Button
  label="Button"
  onClick={() => console.log("Clicked!")}
/>

Properties

  • label takes a string, the text that appears inside the button

  • list if present, the button will be styled to fit into a List

  • onClick a function that is called every time the button is clicked. Passes the SyntheticEvent(https://facebook.github.io/react/docs/events.html) as the first argument.

Example Use Cases

<Button
  list
  label="Clear Settings Storage"
  onClick={() => props.settingsStorage.clear()}
/>

Toggle

Creates a simple toggle on/off button.

Basic Usage

<Toggle
  settingsKey="toggle"
  label="example"
/>

Properties

  • label takes a string, the text that appears to the left of the toggle.

  • settingsKey takes a string, the key associated with this setting.

  • onChange a function that is called every time the toggle is changed. Passes the new value of the toggle as the first argument (the boolean true for on, false for off).

Example Use Cases

<Toggle
  settingsKey="toggle"
/>
<Toggle
  settingsKey="toggle"
  label={`Toggle Switch: ${settings.toggle === 'true' ? 'on' : 'off'}`}
/>
<Toggle
  settingsKey="toggle"
  label="Toggle Switch"
/>

{ JSON.parse(settings.toggle || 'false') && <Toggle settingsKey="hiddenToggle" /> }

Slider

Creates a range slider control.

Basic Usage

<Slider
  label="Example"
  settingsKey="slider"
  min="0"
  max="60"
/>

Properties

  • label takes a string, the text that appears above the slider.

  • settingsKey takes a string, the key associated with this setting.

  • min takes a string representation of a number, the minimum value for the slider.

  • max takes a string representation of a number, the maximum value for the slider.

  • step takes a string representation of a number, the interval for slider values.

  • onChange a function that is called every time the slider value is changed. Passes the new value of the toggle as the first argument (the string representation of the numerical value).

TextInput

Basic Usage
  <TextInput
    label="example"
    settingsKey="text"
  />

Properties

  • title takes a string, the text that appears above the section and in the navbar title

  • label takes a string, the text that appears on the TextInput button as well above the text input box

  • placeholder takes a string, the text that appears inside the text input box when no value is present, defaults to label

  • action takes a string, the text that appears in the save button if present

  • type takes a string, the type of input field, defaults to "text"

  • disabled if present, the textInput is disabled and cannot be clicked on

  • settingsKey takes a string, the key associated with this setting

  • onChange a function that is called every time the text value is saved by the user. Takes the new value of the text as an argument

  • renderItem a function that takes in the value of one option and returns the JSX to render that item in a list. By default, the name field is wrapped in a <Text> component.

  • onAutocomplete a function that is called every time the text value is changed by the user. Takes the new value of the text as an argument and returns a list of autocomplete options to render. Each option is rendered using renderItem and must include a name field.

  • renderAutocomplete a function that takes in one option and the input value and returns the JSX to render that item in a list. By default uses renderItem.

Example use cases

<TextInput
  label="Example"
  title="Text Input"
  settingsKey="textInput"
  disabled={!(props.settings.toggleTextInput === "true")}
/>
<Toggle
  label="Enable Text Input"
  settingsKey="toggleTextInput"
/>
<TextInput
  title="Add List Item"
  label="Item Name"
  placeholder="Type something"
  action="Add Item"
  onAutocomplete={(value) => {
    const autoValues = [
      { name: "red", value: "1" },
      { name: "orange", value: "2" },
      { name: "yellow", value: "3" },
      { name: "green", value: "4" },
      { name: "blue", value: "5" },
      { name: "purple", value: "6" }];
    return autoValues.filter((option) => option.name.startsWith(value));
  }}
/>

Tip: This component is still being developed and will soon include support for autocomplete

ColorSelect

Basic Usage

<ColorSelect
  settingsKey="color"
  colors={[
    {color: 'tomato'},
    {color: 'sandybrown'},
    {color: 'gold'},
    {color: 'aquamarine'},
    {color: 'deepskyblue'},
    {color: 'plum'}
  ]}
/>

Properties

  • settingsKey takes a string, the key associated with this setting.

  • colors takes an array of objects. Each object must have a field named color, whose value is a valid string representation of a CSS color. For examples, see https://www.w3schools.com/cssref/css_colors_legal.asp. Each object can also include an optional value field, which is what will be stored in settings and passed to onSelection. If value is not defined, the value of color will be used by default.

  • centered if present, the color circles will be center aligned. Otherwise, they are left aligned.

  • onSelection a function that is called every time a color is selected. Passes the new value of the selected color as the first argument (the string representation of the value).

Example Use Cases

<ColorSelect
  centered={true}
  settingsKey="color"
  colors={[
    {color: 'tomato',     value: '1'},
    {color: 'sandybrown', value: '2'},
    {color: 'gold',       value: '3'},
    {color: 'aquamarine', value: '4'},
    {color: 'deepskyblue',value: '5'},
    {color: 'plum',       value: '6'},
    {color: 'tomato',     value: '7'},
    {color: 'sandybrown', value: '12'},
    {color: 'gold',       value: '13'},
    {color: 'aquamarine', value: '14'},
    {color: 'deepskyblue',value: '15'}
  ]}
  onSelection={(value) => console.log(value)}
/>
<ColorSelect
  settingsKey="color"
  colors={[
    {color: 'tomato',     value: {align: 'left', number: '1'}},
    {color: 'sandybrown', value: {align: 'right', number: '2'}}
  ]}
/>

Tip: If you specify fewer than 6 colors, the circles will stretch to fill the row

Select

Creates a selection picker.

Basic Usage

<Select
  label={`Selection`}
  settingsKey="selection"
  options={[
    {name:"One"},
    {name:"Two"},
    {name:"Three"}
  ]}
/>

Properties

  • title takes a string, the text that appears above the List block.

  • selectViewTitle takes a string, the text that appears as the title of the select view or modal.

  • label takes a string, the text that appears on the select button.

  • settingsKey takes a string, the key associated with this setting.

  • options takes an array of objects. Each object must have a field named name, whose value is a string. Each object can also include an optional value field, which will be stored in settings along with name.

  • multiple if present, the user can select multiple items from the list, toggling them on and off by selecting them.

  • disabled if present, the select element will be disabled.

  • renderItem a function that takes in the value of one option and returns the JSX to render that item in a list. By default, the name field is wrapped in a <Text> component.

  • onSelection a function that is called every time an option is selected. Passes an object as an argument: {selected: Array, values: Array}, where selected is an array of indices that map to the selected options, and values is an array of the values of those selected options.

Note that the selected option within a <Select> is recalled by the option's index in the options array, not by the option's name or value. If you update your application to rearrange or remove options within a <Select>, you must manually migrate the corresponding settingsKey in your companion code. Otherwise, existing users will see their selections changed or cleared unexpectedly during the update. Alternatively, you may manually manage the value of the <Select> via the onSelection event and selected property.

Example Use Cases

<Select
  label={`Multi-Selection`}
  multiple
  settingsKey="multiselection"
  options={[
    {name:"One",   value:"1"},
    {name:"Two",   value:"2"},
    {name:"Three", value:"3"},
    {name:"Four", value:"4"},
    {name:"Five", value:"5"},
    {name:"Six", value:"6"},
    {name:"Seven", value:"7"},
    {name:"Eight", value:"8"},
    {name:"Nine", value:"9"},
    {name:"Ten", value:"10"},
    {name:"Eleven", value:"11"},
    {name:"Twelve", value:"12"},
    {name:"Thirteen", value:"13"},
    {name:"Fourteen", value:"14"},
    {name:"Fifteen", value:"15"}
  ]}
  renderItem={
    (option) =>
      <TextImageRow
        label={option.name}
        sublabel="Sub-Label"
        icon="https://tinyurl.com/ybbmpxxq"
      />
  }
  onSelection={(selection) => console.log(selection)}
/>

Tip: We recommend using <TextImageRow>as the rendering function for renderItem when including icons or sublabels. For a simple text item, use <Text>.

Additive List

Creates a list which users can add items to by selecting from a list of options.

Basic Usage

Additive List with a Text Input:

<AdditiveList
  settingsKey="additive"
/>

Additive List with a Select Input:

<AdditiveList
  settingsKey="additive"
  addAction={
      <Select
      label="Add Item"
      options={[
        { name: 'Label1'},
        { name: 'Label2'},
        { name: 'Label3'},
        { name: 'Label4'},
        { name: 'Label5'}
      ]}
    />
  }
/>

Properties

  • title takes a string, the text that appears above the List block.

  • description takes a string, the subtext that appears below the List block.

  • settingsKey takes a string, the key associated with this setting.

  • minItems the minimum number of items allowed in the list.

  • maxItems the maximum number of items allowed in the list.

  • renderItem a function that takes in the value of one option and returns the JSX to render that item in a list. By default, the name field is wrapped in a <Text> component.

  • addAction a component that will be used to render the input style for this list. Should be a component that allows for input, such as Select or TextInput.

  • onListChange a function that is called every time the list is changed from adding, deleting or reordering. Passes an array as an argument containing all the items in the list in their current order

Example Use Cases

<AdditiveList
  title="A list of TextImageRow"
  settingsKey="select-list"
  maxItems="5"
  renderItem={
    ({ name, value }) =>
      <TextImageRow
        label={name}
        sublabel={value.location}
        icon={value.icon}
      />
  }
  addAction={
    <Select
      label="Add Item"
      options={[
        { name: 'Label1', required: true,  value: {location: 'Sub-Label', icon: 'https://tinyurl.com/ybbmpxxq'} },
        { name: 'Label2',                  value: {location: 'Sub-Label', icon: 'https://tinyurl.com/ybbmpxxq'} },
        { name: 'Label3', required: true,  value: {location: 'Sub-Label', icon: 'https://tinyurl.com/ybbmpxxq'} },
        { name: 'Label4',                  value: {location: 'Sub-Label', icon: 'https://tinyurl.com/ybbmpxxq'} },
        { name: 'Label5', required: false, value: {location: 'Sub-Label', icon: 'https://tinyurl.com/ybbmpxxq'} }
      ]}
    />
  }
/>
<AdditiveList
  title="A list with Autocomplete"
  settingsKey="autocomplete-list"
  maxItems="5"
  addAction={
    <TextInput
      title="Add List Item"
      label="Item Name"
      placeholder="Type something"
      action="Add Item"
      onAutocomplete={(value) => {
        const autoValues = [
          { name: "red", value: "1" },
          { name: "orange", value: "2" },
          { name: "yellow", value: "3" },
          { name: "green", value: "4" },
          { name: "blue", value: "5" },
          { name: "purple", value: "6" }];
        return autoValues.filter((option) => option.name.startsWith(value));
      }}
    />
  }
/>

OAuth Button

Creates a generic OAuth button that provides two stage authorization code flow by default.

Note: Most OAuth providers require you to specify the redirect_url domain or full path that you will be using with their service. We have provided a special URL to automatically handle the redirection. Please use: https://app-settings.fitbitdevelopercontent.com/simple-redirect.html

Basic Usage

<Oauth
  settingsKey="oauth"
  title="OAuth Login"
  label="OAuth"
  status="Login"
  authorizeUrl="https://accounts.google.com/o/oauth2/v2/auth"
  requestTokenUrl="https://www.googleapis.com/oauth2/v4/token"
  clientId="11111"
  clientSecret="asdfxxx"
  scope="profile"
  pkce
/>

Properties

  • title takes a string, the text that appears above the List block.

  • label takes a string, the text that appears on the left of the Button.

  • status takes a string, the text that appears on the right of the Button.

  • description takes a string, the subtext that appears below the List block.

  • settingsKey takes a string, the key associated with this setting.

  • authorizeUrl takes a string, the user authorization grant url.

  • requestTokenUrl takes a string, the request token url.

  • clientId takes a string, the clientId specified on your OAuth provider account.

  • clientSecret takes a string, the clientSecret specified on your OAuth prvoder account.

  • scope takes a string, the scopes that are being requested.

  • pkce takes a boolean, enables Proof Key for Code Exchange for OAuth providers that support PKCE.

  • onAccessToken a function that receives the accessToken and anything the OAuth provides with it like refresh token and expiration.

Example Use Cases

<Oauth
  settingsKey="oauth"
  title="Fitbit Login"
  label="Fitbit"
  status="Login"
  authorizeUrl="https://www.fitbit.com/oauth2/authorize"
  requestTokenUrl="https://api.fitbit.com/oauth2/token"
  clientId="11111"
  clientSecret="asdfxxx"
  scope="profile"
  onAccessToken={async (data) => {
    console.log(data);
  }}
/>

Strava Login Button

Creates a Strava login button that takes in Strava OAuth options and allows the user to log in.

Note: For Strava API Application registration you need to set the domain that is used redirect to after a user authenticates at Strava. That domain currently should be: fitbitdevelopercontent.com and is likely to change in the future when we provide a more robust redirect OAuth service.

Basic Usage

<StravaLogin
  title="Strava Login"
  settingsKey="strava"
  clientId="11111"
  clientSecret="asdfxxx"
/>

Properties

  • title takes a string, the text that appears above the List block.

  • description takes a string, the subtext that appears below the List block.

  • settingsKey takes a string, the key associated with this setting.

  • clientId takes a string, the clientId specified on your Strava account.

  • clientSecret takes a string, the clientSecret specified on your Strava account.

  • onAccessToken a function that receives the accessToken and Strava userInfo when the auth flow returns with a valid code. It will only run once after coming back from the auth flow.

Example Use Cases

<StravaLogin
  title="Strava Login"
  settingsKey="strava"
  clientId="11111"
  clientSecret="asdfxxx"
  onAccessToken={async (accessToken, userInfo) => {
    const profile = await getProfile(accessToken);

    settingsStorage.setItem('user', JSON.stringify(profile));
  }}
/>

Image Picker

Creates a component that facilitates the user picking a photo from their phone to be used within your application. Once an image is picked, it will be either stored and/or passed to your handler function as a base64 encoded string.

Basic Usage

<ImagePicker
  title="Image Picker"
  description="Pick an image to use in this app"
  label="Pick an Image"
  sublabel="Settings image picker"
  settingsKey="image"
  imageWidth="300"
  imageHeight="300"
/>

Properties

  • title takes a string, the text that appears above the List block.

  • description takes a string, the subtext that appears below the List block.

  • label takes a string, the text that appears as the main action the Button.

  • sublabel takes a string, the text that appears under the label on the Button.

  • pickerTitle takes a string, the title of the image picker page.

  • pickerImageTitle takes a string, the title above the already picked image.

  • pickerLabel takes a string, the text that appears as the main action on the picker page.

  • settingsKey takes a string, the key associated with this setting. Note: If you provide a settingsKey the image data will be stored and available under the key name you provide as JSON serialized as a string. Stored as a JSON serialized string with the following properties: imageUri - base64 data URI imageSize.width - defined imageWidth imageSize.height - defined imageHeight

  • imageWidth takes a string or integer, set to 348 by default, the desired width of the picked image.

  • imageHeight takes a string, set to 250 by default, the desired height of the picked image.

  • showIcon takes a boolean, set to true by default, if set to false it will not show the picked image as an icon next to the button.

  • disabled takes a boolean, disable the button.

  • onImagePicked takes a function, when an image is picked the image data is passed to the defined onImagePicked handler. Passes an object with the following properties: imageUri - base64 data URI image.imageString - base64 string image data image.type - image mime-type imageSize.width - defined imageWidth imageSize.height - defined imageHeight

Example Use Cases

<ImagePicker
  title="Image Picker"
  description="Pick an image to use in this app"
  label="Pick an Image"
  sublabel="Settings image picker"
  imageWidth="300"
  imageHeight="300"
  onImagePicked={({ image, imageSize }) => doSomethingWithImage(image, imageSize)}
/>