{"id":25511289,"url":"https://github.com/node-3d/qml-themedui-raub","last_synced_at":"2026-02-25T18:36:01.196Z","repository":{"id":276968653,"uuid":"912395370","full_name":"node-3d/qml-themedui-raub","owner":"node-3d","description":"Themed flex-like UI primitives for QML","archived":false,"fork":false,"pushed_at":"2025-02-12T08:37:51.000Z","size":462,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-24T18:12:44.949Z","etag":null,"topics":["flex","qml","qt","qtquick","themes","ui-components"],"latest_commit_sha":null,"homepage":"https://github.com/node-3d/node-3d","language":"QML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/node-3d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-05T13:10:48.000Z","updated_at":"2025-02-12T08:37:06.000Z","dependencies_parsed_at":"2025-05-20T21:33:16.188Z","dependency_job_id":null,"html_url":"https://github.com/node-3d/qml-themedui-raub","commit_stats":null,"previous_names":["node-3d/qml-themedui-raub"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/node-3d/qml-themedui-raub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-3d%2Fqml-themedui-raub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-3d%2Fqml-themedui-raub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-3d%2Fqml-themedui-raub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-3d%2Fqml-themedui-raub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/node-3d","download_url":"https://codeload.github.com/node-3d/qml-themedui-raub/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/node-3d%2Fqml-themedui-raub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29834631,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T17:57:15.019Z","status":"ssl_error","status_checked_at":"2026-02-25T17:56:11.472Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flex","qml","qt","qtquick","themes","ui-components"],"created_at":"2025-02-19T10:31:44.248Z","updated_at":"2026-02-25T18:36:01.179Z","avatar_url":"https://github.com/node-3d.png","language":"QML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Themed UI for QML\n\nThis is a part of [Node3D](https://github.com/node-3d) project.\n\n[![NPM](https://badge.fury.io/js/qml-themedui-raub.svg)](https://badge.fury.io/js/qml-themedui-raub)\n\n```console\nnpm i -s qml-themedui-raub\n```\n\n![Example](examples/screenshot.png)\n\nWeb-like flex layout with themed colors, shapes, \"shadows\", fonts, etc.\n\n## Features\n\n* Global context to control themes and access utils.\n* Containers behave similar to **flex** boxes in web.\n* Themes are defined in JSON.\n* Pluggable icon component.\n* Basic components: `TuiText, TuiFlex, TuiIcon`.\n* Extra components: `TuiButton, TuiListItem, TuiDivider`.\n\n\n## Basic Components\n\n```ts\nTuiText {\n\tproperty int lines: 0 // if \u003e 0, limit lines\n\tproperty string size: \"md\" // xxsm xsm sm md lg xlg xxlg\n\tproperty string fontName: \"regular\" // \"regular\" \"semi\" \"bold\" \"mono\"\n\tproperty string align: \"left\" // \"left\" | \"right\" | \"center\" | \"justify\"\n\tproperty string shadow: \"none\" // \"none\" | \"sm\" | \"md\"\n\tproperty int flex: 0 // -1 0 1 2 3...\n\tproperty string padding: \"\" // e.g: \"\", \"10\", \"5 15\", \"20 10 5\", \"5 4 3 2\"\n\tproperty string margin: \"\" // e.g: \"\", \"10\", \"5 15\", \"20 10 5\", \"5 4 3 2\"\n\tproperty var colors: \"primarytext\" // string | ColorSet\n\tproperty bool isDisabled: false\n\tproperty real opacityDisabled: 0.4\n\tproperty string state: \"\" // \"hover\" | \"active\" | \"\"\n}\n```\n\n```ts\nTuiFlex {\n\tproperty var abs: undefined // Item { anchors.fill: parent; ... }\n\tproperty real w: -1 // force width\n\tproperty real h: -1 // force height\n\tproperty string shape: \"none\" // \"sm\" | \"md\" | \"lg\" | \"xlg\" | \"round\" + [\".top\" | \".bottom\" | \".left\" | \".right\"]\n\tproperty string border: \"none\" // \"sm\" | \"md\" | \"lg\" | \"xlg\"\n\tproperty string href: \"\" // string\n\tproperty string direction: \"column\" // \"row\" | \"column\" | \"row-rtl\" | \"column-rtl\"\n\tproperty string justify: \"flex-start\" // \"flex-start\" | \"flex-end\" | \"center\" | \"stretch\"\n\tproperty string align: \"flex-start\" // \"flex-start\" | \"flex-end\" | \"center\" | \"stretch\"\n\tproperty string shadow: \"\" // \"none\" | \"sm\" | \"md\" | \"lg\"\n\tproperty int flex: 0 // number\n\tproperty string padding: \"\" // css string\n\tproperty string margin: \"\" // css string\n\tproperty var colors: \"none\" // string | {}\n\tproperty bool isDisabled: false // boolean\n\tproperty real opacityDisabled: 0.4 // number\n\tproperty string state: \"\" // \"hover\" | \"active\" | \"\"\n}\n```\n\n```ts\nTuiIcon {\n\t// extends TuiFlex\n\tproperty int sizeIcon: 0 // icon size override, pixels\n\tproperty real rotation: 0\n\tproperty string name: \"\" // depends on user-provided icon set\n\tproperty string size: \"md\" // xxsm xsm sm md lg xlg xxlg (keyof TSpecSizes)\n\tproperty string shadowIcon: \"none\" // \"none\" | \"sm\" | \"md\"\n}\n```\n\n\n## Pluggable Icons\n\nThis component library does not provide any icon glyphs. The user is expected to implement\nan adapter to render glyphs.\n\n```ts\n// somewhere on startup\nTuiContext.iconDelegate = Qt.createComponent(\"Icon.qml\");\n```\n\n```ts\n// Icon.qml\nimport ThemedUi\nimport FontAwesome\n\nIconAwesome {\n\tproperty string shadow: \"none\"\n\t\n\tproperty var _shadowText: TuiContext.getShadowText(shadow)\n\tstyle: _shadowText ? _shadowText.style : Text.Normal\n\tstyleColor: _shadowText ? _shadowText.styleColor : \"#000000\"\n}\n```\n\nThis would work with module `qml-fontawesome-raub` as per example.\nFailing to set `iconDelegate` will result in all icons appearing as red boxes.\n\n## Theming\n\n```ts\n// define a theme\nimport \"themes/my-themes.js\" as MyThemes\n\n// somewhere on startup\nTuiContext.theme = MyThemes.theme1;\n```\n\n### Theme structure:\n\n```ts\n{\n\tname: string,\n\tcolors: {\n\t\tspec: { [id]: string },\n\t\ttext: {\n\t\t\tprimary: string,\n\t\t\tprimaryplus: string,\n\t\t\tprimaryminus: string,\n\t\t\t[id]: string,\n\t\t}, // TColorSlots\n\t\tbg: TColorSlots,\n\t},\n\tfonts: {\n\t\tregular: {\n\t\t\tfamily: string,\n\t\t\tweight: number,\n\t\t}, // TFont\n\t\tregular: TFont,\n\t\t[id]: TFont,\n\t},\n\tsizes: {\n\t\tfont: {\n\t\t\txxsm: number,\n\t\t\txsm: number,\n\t\t\tsm: number,\n\t\t\tmd: number,\n\t\t\tlg: number,\n\t\t\txlg: number,\n\t\t\txxlg: number,\n\t\t\tauto: number,\n\t\t}, // TSpecSizes\n\t\tbutton: TSpecSizes,\n\t\ticon: TSpecSizes,\n\t\tglyph: TSpecSizes,\n\t\titem: TSpecSizes,\n\t\tdivider: TSpecSizes,\n\t},\n\tshadows: {\n\t\tnone: null,\n\t\tsm: { size: number, color: '#55000000' }, // TBoxShadow | null\n\t\tmd: TBoxShadow,\n\t\tlg: TBoxShadow,\n\t},\n\tshadowsText: {\n\t\tnone: null,\n\t\tsm: { style: QtQuick.Text.Outline, styleColor: '#55000000' }, // TTextShadow | null\n\t\tmd: TTextShadow,\n\t},\n\tshapes: {\n\t\tround: {\n\t\t\tall: [number, number, number, number],\n\t\t\ttop: [number, number, 0, 0],\n\t\t\tbottom: [0, 0, number, number],\n\t\t\tleft: [number, 0, 0, number],\n\t\t\tright: [0, number, number, 0],\n\t\t}, // TShapeRadii\n\t\tsm: TShapeRadii,\n\t\tmd: TShapeRadii,\n\t\tlg: TShapeRadii,\n\t\txlg: TShapeRadii,\n\t},\n\tborders: {\n\t\tsm: number,\n\t\tmd: number,\n\t\tlg: number,\n\t\txlg: number,\n\t},\n\tcolorSets: {\n\t\tnone: {\n\t\t\ttext: TColorRef, // \"spec.NAME\" | \"bg.NAME\" | \"text.NAME\" | \"#ff00ff\" | \"red\"\n\t\t\ttextHover: TColorRef,\n\t\t\ttextActive: TColorRef,\n\t\t\tbg: TColorRef,\n\t\t\tbgHover: TColorRef,\n\t\t\tbgActive: TColorRef,\n\t\t\tborder: TColorRef,\n\t\t\tborderHover: TColorRef,\n\t\t\tborderActive: TColorRef,\n\t\t}, // TColorSet\n\t\tprimary: TColorSet,\n\t\t[id]: TColorSet,\n\t},\n}\n```\n\n\n## TuiContext\n\nThis is a singleton, available after importing the module.\n\n\n`TuiContext.themeUtils` - (readonly) helpers to create some theme-related items:\n\n```ts\n{\n\thashIntoColor: (str: string) =\u003e string,\n\tcreateFlatColorset: (\n\t\ttext: string, textHover: string, textActive: string, bg: string, bgHover: string, bgActive: string,\n\t) =\u003e TColorSet,\n\tcreateGhostColorset: (text: string, textHover: string, textActive: string) =\u003e TColorSet,\n\tcreateTextColorset: (text: string, textHover: string, textActive: string) =\u003e TColorSet,\n\tcreateStateColorsetTriplet: (name: keyof TColorSlots) =\u003e {\n\t\t`${name}`: TColorSet,\n\t\t`${name}ghost`: TColorSet,\n\t\t`${name}text`: TColorSet,\n\t}\n\tmapShapes: (sm, md, lg, xlg) =\u003e TShapeRadii,\n\tauxSides: (source: string) =\u003e [number, number, number, number]\n}\n```\n\n`TuiContext.defaultTheme` - (readonly) the default theme object that may be used\nto inherit some of the fields.\n\n`TuiContext.theme` - assign your theme object here.\nThe initial value is `TuiContext.defaultTheme`.\n\n`TuiContext.iconDelegate` - assign your icon adapter (component) here.\nThe initial value is `FakeIcon {}` (red box).\n\nThe helpers below will fetch named values from the current theme:\n\n```ts\nTuiContext.getShape(name: string): TShapeRadii | null;\nTuiContext.getBorder(name): number | null;\nTuiContext.getSize(name, prefix): number;\nTuiContext.getFont(name): TFont | null;\nTuiContext.getShadow(name): TBoxShadow | null;\nTuiContext.getShadowText(name): TTextShadow | null;\nTuiContext.getColor(name): string;\nTuiContext.getColorBg(state, colors): string;\nTuiContext.getColorText(state, colors): string;\nTuiContext.getColorBorder(state, colors): string;\n```\n\n\n## Extra Components\n\n```ts\nTuiDivider {\n\t// extends TuiFlex\n\tproperty string size: \"sm\"\n\tproperty bool isVertical: false\n}\n```\n\n```ts\nTuiButton {\n\t// extends TuiFlex\n\t\n\tsignal pressed(name: string)\n\tsignal clicked(name: string)\n\t\n\tproperty string name: \"\"\n\tproperty string size: \"md\"\n\tproperty string sizeText: \"\"\n\tproperty string sizeIcons: \"md\"\n\tproperty var icons: null\n\tproperty var iconsActive: null\n\tproperty string label: \"\"\n\tproperty string labelActive: \"\"\n\tproperty int lines: 0\n\tproperty string fontName: \"semi\"\n\tproperty string fontActive: \"\"\n\tproperty int flexText: 0\n\tproperty string alignText: \"\"\n\tproperty string shadowText: \"\"\n\tproperty var colorsActive: null\n\tproperty bool isActive: false\n\tproperty bool isPressable: true\n}\n```\n\n```ts\nTuiListItem {\n\t// extends Button, but:\n\t\n\t// fontName: \"regular\"\n\t// shape: \"none\"\n\t// shadow: \"none\"\n\t// colors: \"primarytext\"\n\t// justify: \"flex-start\"\n\t// isPressable: false\n\t\n\t// and the size is based on `theme.sizes.item`\n}\n```\n\n\n## Importing\n\nThe `./ThemedUi` directory should be visible to QML engine for importing.\n\n```qml\nimport ThemedUi\n```\n\n### C++ import path\n\n```cpp\nqmlEngine-\u003eaddImportPath(\"path to qml-themedui-raub\");\n```\n\n### Node.js qml-raub\n\n```js\nView.libs(require('qml-themedui-raub').absPath);\n```\n\n### Manual\n\nCopy this repo or even specifically the `./ThemedUi` folder to wherever your QML is\nready to grab it. Or use this repo as a submodule if you wish.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-3d%2Fqml-themedui-raub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnode-3d%2Fqml-themedui-raub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnode-3d%2Fqml-themedui-raub/lists"}