JSPM

qml-themedui-raub

0.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q17271F
  • License MIT

Themed UI components for QML

Package Exports

  • qml-themedui-raub
  • qml-themedui-raub/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (qml-themedui-raub) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Themed UI for QML

This is a part of Node3D project.

NPM

npm i -s qml-themedui-raub

Example

Web-like flex layout with themed colors, shapes, "shadows", fonts, etc.

Features

  • Global context to control themes and access utils.
  • Containers behave similar to flex boxes in web.
  • Themes are defined in JSON.
  • Pluggable icon component.
  • Basic components: TuiText, TuiFlex, TuiIcon.
  • Extra components: TuiButton, TuiListItem, TuiDivider.

Basic Components

TuiText {
    property int lines: 0 // if > 0, limit lines
    property string size: "md" // xxsm xsm sm md lg xlg xxlg
    property string fontName: "regular" // "regular" "semi" "bold" "mono"
    property string align: "left" // "left" | "right" | "center" | "justify"
    property string shadow: "none" // "none" | "sm" | "md"
    property int flex: 0 // -1 0 1 2 3...
    property string padding: "" // e.g: "", "10", "5 15", "20 10 5", "5 4 3 2"
    property string margin: "" // e.g: "", "10", "5 15", "20 10 5", "5 4 3 2"
    property var colors: "primarytext" // string | ColorSet
    property bool isDisabled: false
    property real opacityDisabled: 0.4
    property string state: "" // "hover" | "active" | ""
}
TuiFlex {
    property var abs: undefined // Item { anchors.fill: parent; ... }
    property real w: -1 // force width
    property real h: -1 // force height
    property string shape: "none" // "sm" | "md" | "lg" | "xlg" | "round" + [".top" | ".bottom" | ".left" | ".right"]
    property string border: "none" // "sm" | "md" | "lg" | "xlg"
    property string href: "" // string
    property string direction: "column" // "row" | "column" | "row-rtl" | "column-rtl"
    property string justify: "flex-start" // "flex-start" | "flex-end" | "center" | "stretch"
    property string align: "flex-start" // "flex-start" | "flex-end" | "center" | "stretch"
    property string shadow: "" // "none" | "sm" | "md" | "lg"
    property int flex: 0 // number
    property string padding: "" // css string
    property string margin: "" // css string
    property var colors: "none" // string | {}
    property bool isDisabled: false // boolean
    property real opacityDisabled: 0.4 // number
    property string state: "" // "hover" | "active" | ""
}
TuiIcon {
    // extends TuiFlex
    property int sizeIcon: 0 // icon size override, pixels
    property real rotation: 0
    property string name: "" // depends on user-provided icon set
    property string size: "md" // xxsm xsm sm md lg xlg xxlg (keyof TSpecSizes)
    property string shadowIcon: "none" // "none" | "sm" | "md"
}

Pluggable Icons

This component library does not provide any icon glyphs. The user is expected to implement an adapter to render glyphs.

// somewhere on startup
TuiContext.iconDelegate = Qt.createComponent("Icon.qml");
// Icon.qml
import ThemedUi
import FontAwesome

IconAwesome {
    property string shadow: "none"
    
    property var _shadowText: TuiContext.getShadowText(shadow)
    style: _shadowText ? _shadowText.style : Text.Normal
    styleColor: _shadowText ? _shadowText.styleColor : "#000000"
}

This would work with module qml-fontawesome-raub as per example. Failing to set iconDelegate will result in all icons appearing as red boxes.

Theming

// define a theme
import "themes/my-themes.js" as MyThemes

// somewhere on startup
TuiContext.theme = MyThemes.theme1;

Theme structure:

{
    name: string,
    colors: {
        spec: { [id]: string },
        text: {
            primary: string,
            primaryplus: string,
            primaryminus: string,
            [id]: string,
        }, // TColorSlots
        bg: TColorSlots,
    },
    fonts: {
        regular: {
            family: string,
            weight: number,
        }, // TFont
        regular: TFont,
        [id]: TFont,
    },
    sizes: {
        font: {
            xxsm: number,
            xsm: number,
            sm: number,
            md: number,
            lg: number,
            xlg: number,
            xxlg: number,
            auto: number,
        }, // TSpecSizes
        button: TSpecSizes,
        icon: TSpecSizes,
        glyph: TSpecSizes,
        item: TSpecSizes,
        divider: TSpecSizes,
    },
    shadows: {
        none: null,
        sm: { size: number, color: '#55000000' }, // TBoxShadow | null
        md: TBoxShadow,
        lg: TBoxShadow,
    },
    shadowsText: {
        none: null,
        sm: { style: QtQuick.Text.Outline, styleColor: '#55000000' }, // TTextShadow | null
        md: TTextShadow,
    },
    shapes: {
        round: {
            all: [number, number, number, number],
            top: [number, number, 0, 0],
            bottom: [0, 0, number, number],
            left: [number, 0, 0, number],
            right: [0, number, number, 0],
        }, // TShapeRadii
        sm: TShapeRadii,
        md: TShapeRadii,
        lg: TShapeRadii,
        xlg: TShapeRadii,
    },
    borders: {
        sm: number,
        md: number,
        lg: number,
        xlg: number,
    },
    colorSets: {
        none: {
            text: TColorRef, // "spec.NAME" | "bg.NAME" | "text.NAME" | "#ff00ff" | "red"
            textHover: TColorRef,
            textActive: TColorRef,
            bg: TColorRef,
            bgHover: TColorRef,
            bgActive: TColorRef,
            border: TColorRef,
            borderHover: TColorRef,
            borderActive: TColorRef,
        }, // TColorSet
        primary: TColorSet,
        [id]: TColorSet,
    },
}

TuiContext

This is a singleton, available after importing the module.

TuiContext.themeUtils - (readonly) helpers to create some theme-related items:

{
    hashIntoColor: (str: string) => string,
    createFlatColorset: (
        text: string, textHover: string, textActive: string, bg: string, bgHover: string, bgActive: string,
    ) => TColorSet,
    createGhostColorset: (text: string, textHover: string, textActive: string) => TColorSet,
    createTextColorset: (text: string, textHover: string, textActive: string) => TColorSet,
    createStateColorsetTriplet: (name: keyof TColorSlots) => {
        `${name}`: TColorSet,
        `${name}ghost`: TColorSet,
        `${name}text`: TColorSet,
    }
    mapShapes: (sm, md, lg, xlg) => TShapeRadii,
    auxSides: (source: string) => [number, number, number, number]
}

TuiContext.defaultTheme - (readonly) the default theme object that may be used to inherit some of the fields.

TuiContext.theme - assign your theme object here. The initial value is TuiContext.defaultTheme.

TuiContext.iconDelegate - assign your icon adapter (component) here. The initial value is FakeIcon {} (red box).

The helpers below will fetch named values from the current theme:

TuiContext.getShape(name: string): TShapeRadii | null;
TuiContext.getBorder(name): number | null;
TuiContext.getSize(name, prefix): number;
TuiContext.getFont(name): TFont | null;
TuiContext.getShadow(name): TBoxShadow | null;
TuiContext.getShadowText(name): TTextShadow | null;
TuiContext.getColor(name): string;
TuiContext.getColorBg(state, colors): string;
TuiContext.getColorText(state, colors): string;
TuiContext.getColorBorder(state, colors): string;

Extra Components

TuiDivider {
    // extends TuiFlex
    property string size: "sm"
    property bool isVertical: false
}
TuiButton {
    // extends TuiFlex
    
    signal pressed(name: string)
    signal clicked(name: string)
    
    property string name: ""
    property string size: "md"
    property string sizeText: ""
    property string sizeIcons: "md"
    property var icons: null
    property var iconsActive: null
    property string label: ""
    property string labelActive: ""
    property int lines: 0
    property string fontName: "semi"
    property string fontActive: ""
    property int flexText: 0
    property string alignText: ""
    property string shadowText: ""
    property var colorsActive: null
    property bool isActive: false
    property bool isPressable: true
}
TuiListItem {
    // extends Button, but:
    
    // fontName: "regular"
    // shape: "none"
    // shadow: "none"
    // colors: "primarytext"
    // justify: "flex-start"
    // isPressable: false
    
    // and the size is based on `theme.sizes.item`
}

Importing

The ./ThemedUi directory should be visible to QML engine for importing.

import ThemedUi

C++ import path

qmlEngine->addImportPath("path to qml-themedui-raub");

Node.js qml-raub

View.libs(require('qml-themedui-raub').absPath);

Manual

Copy this repo or even specifically the ./ThemedUi folder to wherever your QML is ready to grab it. Or use this repo as a submodule if you wish.