npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dark-engine/platform-native

v1.4.2

Published

Dark renderer to native platforms like Android and iOS via NativeScript

Downloads

40

Readme

@dark-engine/platform-native 🌖

Dark renderer to mobile platforms like Android and iOS via NativeScript.

NativeScript is a free and open-source framework for building native mobile apps using JavaScript, or any other language that can transpile to JavaScript, for iOS and Android platforms. It allows developers to write a single codebase for both platforms, resulting in native performance and access to device-specific APIs, while still leveraging familiar web development tools and paradigms.

More about Dark

app.webm

Installation

Install NativeScript according to the instructions here

from template:

npx degit github:atellmer/dark/templates/native app
cd app
npm i
npm start

npm:

npm install @nativescript/core @dark-engine/core @dark-engine/animations @dark-engine/platform-native

yarn:

yarn add @nativescript/core @dark-engine/core @dark-engine/animations @dark-engine/platform-native

Usage

import { component, useState } from '@dark-engine/core';
import { FlexboxLayout, Button } from '@dark-engine/platform-native';

const App = component(() => {
  const [count, setCount] = useState(0);

  return (
    <FlexboxLayout justifyContent='center' alignItems='center'>
      <Button
        backgroundColor='purple'
        padding={16}
        onTap={() => setCount(count + 1)}>
        Fired {count} times
      </Button>
    </FlexboxLayout>
  );
});

Also you can write any code without JSX:

import { component, useState } from '@dark-engine/core';
import { FlexboxLayout, Button } from '@dark-engine/platform-native';

const App = component(() => {
  const [count, setCount] = useState(0);

  return FlexboxLayout({
    justifyContent: 'center',
    alignItems: 'center',
    slot: [
      Button({
        backgroundColor: 'purple',
        padding: 16,
        text: `Fired ${count} times`,
        onTap: () => setCount(count + 1),
      }),
    ],
  });
});

Environment Setup

Full working examples with environment setup you can find here or just install it from template.

API

import {
  type SyntheticEvent,
  run,
  registerElement,
  factory,
  View,
  Text,
  Image,
  Button,
  ScrollView,
  TouchableOpacity,
  TextField,
  Modal,
  ActionBar,
  ActionItem,
  NavigationButton,
  ActivityIndicator,
  RootLayout,
  AbsoluteLayout,
  StackLayout,
  FlexboxLayout,
  GridLayout,
  DockLayout,
  WrapLayout,
  ContentView,
  HtmlView,
  WebView,
  Slider,
  Switch,
  Placeholder,
  ListView,
  ListPicker,
  DatePicker,
  TimePicker,
  Label,
  TextView,
  FormattedString,
  Span,
  TabView,
  TabViewItem,
  Frame,
  Page,
  VERSION,
} from '@dark-engine/platform-native';

Mounting to native platform

To mount you app you need to use run function:

import { run } from '@dark-engine/platform-native';

import App from './components/app';

run(App());

Layout system

The system for placing elements in the layout includes the following components:

import {
  RootLayout,
  AbsoluteLayout,
  StackLayout,
  FlexboxLayout,
  GridLayout,
  DockLayout,
  WrapLayout,
} from '@dark-engine/platform-native';

To learn more about how they work, you can visit the NativeScript documentation.

Conditional rendering

You can use conditional rendering, but be aware that NativeScript is sensitive to frequent insertions and removals from the element tree. Therefore, whenever possible, an alternative approach should be used - the hidden and visible attributes, more about which can be found in the NativeScript documentation.

// variant 1
return (
  <>
    {
      isFetching
      ? <FlexboxLayout
          height='100%'
          justifyContent='center'
          alignItems='center'>
          <ActivityIndicator busy />
        </FlexboxLayout>
      : <StackLayout>
          <Label>Hello 🥰</Label>
        </StackLayout>
    }
  </>
);
// variant 2
return (
  <>
    <FlexboxLayout
      hidden={!isFetching}
      height='100%'
      justifyContent='center'
      alignItems='center'>
      <ActivityIndicator busy />
    </FlexboxLayout>
    <StackLayout hidden={isFetching}>
      <Label>Hello 🥰</Label>
    </StackLayout>
  </>
);

List rendering

In order to display lists of items, it is recommended to use the ListView component, which implements the virtual list behavior when only those items that are inside the viewport are rendered. Of course, you can also use normal rendering via map, however, in terms of performance, NativeScript is very sensitive to the number of elements in the application, as well as inserting and removing them from the tree. Therefore, virtualization should be used as much as possible.

import { ListView } from '@dark-engine/platform-native';
return (
  <ListView
    height='100%'
    items={items}
    onItemTap={() => console.log('tapped!')}>
    {({ item, idx }) => {
      return (
        <StackLayout backgroundColor={idx % 2 ? 'red' : 'yellow'}>
          <Label color={idx % 2 ? 'white' : 'black'}>item #{item}</Label>
        </StackLayout>
      );
    }}
  </ListView>
);

Connecting 3rd party plugins

In modern development, we can rarely do without third-party packages written by other developers. Therefore, we should always be able to include such plugins in our project.

Suppose you want to connect a third party carousel plugin @nstudio/nativescript-carousel

First of all you must install it in your app from npm:

npm i @nstudio/nativescript-carousel

Further, to register a new element, you need to use the registerElement function:

import { component } from '@dark-engine/core';
import { registerElement, factory } from '@dark-engine/platform-native';

registerElement('ns:carousel', () => require('@nstudio/nativescript-carousel').Carousel);
registerElement('ns:carousel-item', () => require('@nstudio/nativescript-carousel').CarouselItem);

type CarouselProps = {};
type CarouselItemProps = {};

const carousel = factory('ns:carousel');
const Carousel = component<CarouselProps>(props => carousel(props));

const carouselItem = factory('ns:carousel-item');
const CarouselItem = component<CarouselItemProps>(props => carouselItem(props));

export { Carousel, CarouselItem };

After all this, a new plugin can be used like this::

import { Label } from '@dark-engine/platform-native';
import { Carousel, CarouselItem } from '@my-ui-kit';

return (
  <Carousel height='100%' width='100%'>
    <CarouselItem id='slide1' backgroundColor='red'>
      <Label text='Slide 1' />
    </CarouselItem>
    <CarouselItem id='slide2' backgroundColor='blue'>
      <Label text='Slide 2' />
    </CarouselItem>
    <CarouselItem id='slide3' backgroundColor='green'>
      <Label text='Slide 3' />
    </CarouselItem>
  </Carousel>
);

Modals

To insert content in modal window you need to use a special component Modal:

import { Modal } from '@dark-engine/platform-native';
const [isOpen, setIsOpen] = useState(false);

return (
  <Modal isOpen={isOpen} animated onRequestClose={() => setIsOpen(false)}>
    <StackLayout padding={32}>
      <Label>Hello from Modal</Label>
    </StackLayout>
  </Modal>
);

Additional components

Dark includes additional components of type View, Text, TouchableOpacity, so that you can write an application in a almost similar to React Native style.

import { component } from '@dark-engine/core';
import { View, Text, TouchableOpacity } from '@dark-engine/platform-native';

const App = component(() => {
  return (
    <View justifyContent='center'>
      <TouchableOpacity padding={32} backgroundColor='#4caf50' onPress={() => console.log('press')}>
        <Text textAlignment='center'>Press me</Text>
      </TouchableOpacity>
    </View>
  );
});

Navigation

Any more or less complex application needs to be divided into several pages and navigate between them. Dark provides a package for this called @dark-engine/native-navigation, which implements navigation using StackNavigator and TabNavigator. This router also supports animated transitions, nested navigation and parameter passing.

import { NavigationContainer, StackNavigator } from '@dark-engine/native-navigation';

const App = component(() => {
  return (
    <NavigationContainer defaultPathname='/Feed'>
      <StackNavigator.Root>
        <StackNavigator.Screen name='Feed' component={Feed} />
        <StackNavigator.Screen name='Friends' component={Friends} />
        <StackNavigator.Screen name='Profile' component={Profile} />
        <StackNavigator.Screen name='Settings' component={Settings} />
      </StackNavigator.Root>
    </NavigationContainer>
  );
});

Full documentation about this package you can find here.

LICENSE

MIT © Alex Plex