hypi_tink_api 0.1.0 copy "hypi_tink_api: ^0.1.0" to clipboard
hypi_tink_api: ^0.1.0 copied to clipboard

A package containing public API definitions for building Hypi Tink Editor extensions

Hypi Tink #

This package provides the APIs needed to develop extenstions (Widgets or Actions) for Hypi's nocode platform.

Basics #

The platform supports two types of extensions:

  1. Widgets
  2. Actions

Widgets are any Flutter Stateful or Stateless widgets that you'd like to use in Hypi's editor.

Actions are any piece of code you'd like to use to provide custom behaviour for an app. An action can literally be made to do anything that's possible in a standard Flutter app.

Widget extension #

Developing a Widget extension involves building the widget itself and providing Hypi Tink with a handler implementation for this widget. A handler is a class which mixes in the HypiTinkWidgetHandler mixin AND has the @TinkEditorHandler annotation.

For example:

//here, this handler will be used to manage the `MyWidget` widget
//MyWidget must be unique and should not conflict with any existing widget in the editor
//Use a prefix/suffix e.g. MyCompanyWidget
@TinkEditorHandler(['MyWidget'])
class MyWidgetHandler with TinkWidgetHandler {
  String? myField;
  //here you can override any of the methods from TinkWidgetHandler to customise how your widget is handled in the editor
  //You MUST have a constructor which accepts a single parameter of type TinkWidgetHandler
  MyWidgetHandler(TinkWidgetHandler delegate) {
    //you MUST call initDelegate and pass the delegate and this to it - best practice is to call this as the first thing in the constructor of your handler   
    initDelegate(delegate, this);
    //if your widget has properties that need to be persisted then you declare them e.g.
    //As well as TSimpleField there are TDoubleField, EntityField, ListEntityField and MapEntityField
    //the value returned MUST be int, double, float, Map, List or some combination of them
    fields.add(TSimpleField('myField', (value) => myField = value, () => myField));
  }

  @override
  Widget showWidgetProperties(BuildContext context, StateSetter setState) {
    //override this to provide the widget that is displayed in the right side bar of editor
    //it is typically used to show options for customising the widget that this handler is for
    //if it is not provided the editor displays a message saying the widget does not support customisations
    return _MyWidgetPanelProperties(handler: this);
  }
}

class _MyWidgetPanelProperties extends StatefulWidget {
  final MyWidgetEditorHandler handler;

  const _MyWidgetPanelProperties({Key? key, required this.handler})
      : super(key: key);

  @override
  State<_MyWidgetPanelProperties> createState() =>
      _MyWidgetPanelPropertiesState();
}

class _MyWidgetPanelPropertiesState extends State<_MyWidgetPanelProperties> {
  @override
  Widget build(BuildContext context) {
    return Text('This is where I would provide options to configure my widget');
  }
}

class MyWidget extends StatelessWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Text('This is my widget');
  }
}

The above is a simple if useless widget but demonstrates the minimum required code for developing a custom Hypi Tink widget extension.

Once you've finished developing your widget extension, provide the git repository URL in the editor and it will discover and load your widget from your repo (public or private).

Action extension #

An action extension is a class which mixes in the TinkActionLike mixin.

For example:

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:hypi_tink_api/hypi_tink_api.dart';

class HttpGetAction with TinkActionLike {
  //uniquely identifies this action
  @override
  String id = 'http.get';
  //The editor puts all actions with the same group under a single dropdown
  @override
  String groupId = 'http';
  //The name shown to the user in the editor
  @override
  String label = 'GET request';
  //A set of parameters that the action requires
  @override
  List<TinkParam>? inputs = [
    const TinkParam('url', TinkVariableType.text),
    const TinkParam('headers', TinkVariableType.json),
  ];
  //Any variable/value that the action will output, MUST be primitive, Map or List
  @override
  List<TinkParam> outputs = [
    const TinkParam('responseCode', TinkVariableType.int),
    const TinkParam('contentLength', TinkVariableType.int, required: false),
    const TinkParam('responseHeaders', TinkVariableType.json),
    const TinkParam('responseBody', TinkVariableType.text),
    const TinkParam('isRedirect', TinkVariableType.bool),
  ];

  //Shown to the user to allow them to customise the action
  //By default, delegate.config shows a UI that allows the user to bind a variable to each of the action's inputs
  @override
  Widget config(
      ActionEnv<
              TinkApplicationState<
                  TinkWidgetInputBinding<ScreenModel, TinkWidgetHandler>,
                  TinkWidgetOutputBinding<EventModel, TinkWidgetHandler>,
                  TinkWorkflowBinding<EventModel, WorkflowModel,
                      TinkWidgetHandler>,
                  TinkVariable>,
              ScreenModel>
          env,
      WorkflowModel workflow,
      String screenId,
      TinkWorkflowBinding<EventModel, WorkflowModel, TinkWidgetHandler>
          binding) {
    return delegate.config(env, workflow, screenId, binding);
  }

  //Called when the action is executed, put your action's implementation here...it can do anything and use any library from pub.dev
  @override
  void next(ActionChain chain) async {
    String value = chain.getState(this, 'url')?.value;
    Map<String, String>? hdrs = chain.getState(this, 'headers')?.value;
    Response response = await http.get(Uri.parse(value), headers: hdrs ?? {});
    chain.emitState(this, TinkIntVariable('responseCode', response.statusCode));
    if (response.contentLength != null) {
      chain.emitState(
          this, TinkIntVariable('contentLength', response.contentLength!));
    }
    chain.emitState(this, TinkBoolVariable('isRedirect', response.isRedirect));
    chain.emitState(
        this, TinkJsonVariable('responseHeaders', response.headers));
    chain.emitState(this, TinkTextVariable('responseBody', response.body));
    chain.next();
  }
}

Extensions are automatically discovered and registered in the editor as long as they are annotated (for widget extensions) or mixes in TinkActionLike.

2
likes
120
points
34
downloads

Publisher

verified publisherhypi.io

Weekly Downloads

A package containing public API definitions for building Hypi Tink Editor extensions

Homepage

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, flutter_svg, ulid, yaml_edit

More

Packages that depend on hypi_tink_api