@malilion/block-ui-themes 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Block UI Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @malilion/block-ui-themes
2
+
3
+ The five [Block UI](https://github.com/malilion/BlockUI) themes — `grassland`, `cave`, `deepslate`, `nether`, `end` — as typed `BlockTheme` objects and as `[data-theme]` CSS variables.
4
+
5
+ ```bash
6
+ pnpm add @malilion/block-ui-themes
7
+ ```
8
+
9
+ ```ts
10
+ import { themes, themeNames, type BlockThemeName } from "@malilion/block-ui-themes";
11
+ import "@malilion/block-ui-themes/themes.css";
12
+ ```
13
+
14
+ ```html
15
+ <body data-theme="nether">
16
+ …
17
+ </body>
18
+ ```
19
+
20
+ `@malilion/block-ui-react` already includes this stylesheet and applies themes through `<BlockUIProvider theme="…">`.
21
+
22
+ MIT License
package/dist/css.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { BlockTheme } from "./types.js";
2
+ /** CSS variable name for a theme role. `background` maps to the PRD's `--block-bg`. */
3
+ export declare function themeVar(role: keyof BlockTheme): string;
4
+ export declare function themeEntries(theme: BlockTheme): Array<[string, string]>;
5
+ /** Generates `themes.css`. The default theme also applies to `:root`. */
6
+ export declare function generateThemesCss(): string;
7
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../src/css.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAC;AAE7D,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,UAAU,GAAG,MAAM,CAIvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAMvE;AASD,yEAAyE;AACzE,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C"}
package/dist/css.js ADDED
@@ -0,0 +1,32 @@
1
+ import { toKebab } from "@malilion/block-ui-tokens";
2
+ import { defaultThemeName, themes } from "./themes.js";
3
+ /** CSS variable name for a theme role. `background` maps to the PRD's `--block-bg`. */
4
+ export function themeVar(role) {
5
+ if (role === "background")
6
+ return "--block-bg";
7
+ if (role === "texture")
8
+ return "--block-texture";
9
+ return `--block-${toKebab(role)}`;
10
+ }
11
+ export function themeEntries(theme) {
12
+ return Object.keys(theme).map((role) => {
13
+ const value = theme[role];
14
+ if (role === "texture")
15
+ return [themeVar(role), `var(--block-texture-${toKebab(value)})`];
16
+ return [themeVar(role), value.startsWith("#") ? value.toLowerCase() : value];
17
+ });
18
+ }
19
+ function block(selector, theme) {
20
+ const body = themeEntries(theme)
21
+ .map(([name, value]) => ` ${name}: ${value};`)
22
+ .join("\n");
23
+ return `${selector} {\n color-scheme: dark;\n${body}\n}`;
24
+ }
25
+ /** Generates `themes.css`. The default theme also applies to `:root`. */
26
+ export function generateThemesCss() {
27
+ const blocks = Object.keys(themes).map((name) => {
28
+ const selector = name === defaultThemeName ? `:root,\n[data-theme="${name}"]` : `[data-theme="${name}"]`;
29
+ return block(selector, themes[name]);
30
+ });
31
+ return `/* Generated by @malilion/block-ui-themes — do not edit by hand. Run \`pnpm generate\`. */\n${blocks.join("\n\n")}\n`;
32
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./themes.js";
3
+ export { generateThemesCss, themeEntries, themeVar } from "./css.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export * from "./themes.js";
3
+ export { generateThemesCss, themeEntries, themeVar } from "./css.js";
@@ -0,0 +1,9 @@
1
+ import type { BlockTheme, BlockThemeName } from "./types.js";
2
+ export declare const grassland: BlockTheme;
3
+ export declare const cave: BlockTheme;
4
+ export declare const deepslate: BlockTheme;
5
+ export declare const nether: BlockTheme;
6
+ export declare const end: BlockTheme;
7
+ export declare const themes: Record<BlockThemeName, BlockTheme>;
8
+ export declare const defaultThemeName: BlockThemeName;
9
+ //# sourceMappingURL=themes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../src/themes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS7D,eAAO,MAAM,SAAS,EAAE,UAkBvB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,UAmBlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,UAkBvB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,UAmBpB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,UAmBjB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,UAAU,CAMrD,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAA4B,CAAC"}
package/dist/themes.js ADDED
@@ -0,0 +1,113 @@
1
+ import { colors } from "@malilion/block-ui-tokens";
2
+ const shared = {
3
+ border: colors.outline,
4
+ text: colors.textPrimary,
5
+ focus: colors.gold,
6
+ overlay: "rgba(8, 9, 11, 0.72)",
7
+ };
8
+ export const grassland = {
9
+ ...shared,
10
+ background: "#1B1E22",
11
+ surface: "#34373C",
12
+ surfaceAlt: "#26292D",
13
+ surfaceHeader: "#2A2D31",
14
+ slot: "#1E2024",
15
+ slotHover: "#2C2F34",
16
+ textMuted: colors.textSecondary,
17
+ primary: colors.grass,
18
+ primaryLight: colors.grassLight,
19
+ primaryDark: colors.grassDark,
20
+ onPrimary: colors.onGrass,
21
+ secondary: colors.wood,
22
+ secondaryLight: colors.woodLight,
23
+ secondaryDark: colors.woodDark,
24
+ onSecondary: colors.onWood,
25
+ texture: "stone",
26
+ };
27
+ export const cave = {
28
+ ...shared,
29
+ background: "#121417",
30
+ surface: "#2A2C30",
31
+ surfaceAlt: "#1E2023",
32
+ surfaceHeader: "#232528",
33
+ slot: "#16181A",
34
+ slotHover: "#25272B",
35
+ textMuted: "#BFC4CA",
36
+ primary: colors.gold,
37
+ primaryLight: colors.goldLight,
38
+ primaryDark: colors.goldDark,
39
+ onPrimary: colors.onGold,
40
+ secondary: colors.stone,
41
+ secondaryLight: colors.stoneLight,
42
+ secondaryDark: colors.stoneDark,
43
+ onSecondary: colors.onStone,
44
+ focus: colors.diamond,
45
+ texture: "stone",
46
+ };
47
+ export const deepslate = {
48
+ ...shared,
49
+ background: colors.background,
50
+ surface: colors.deepslate,
51
+ surfaceAlt: "#1F1F21",
52
+ surfaceHeader: "#232325",
53
+ slot: "#18181A",
54
+ slotHover: "#2A2A2D",
55
+ textMuted: colors.textSecondary,
56
+ primary: colors.diamond,
57
+ primaryLight: colors.diamondLight,
58
+ primaryDark: colors.diamondDark,
59
+ onPrimary: colors.onDiamond,
60
+ secondary: colors.stone,
61
+ secondaryLight: colors.stoneLight,
62
+ secondaryDark: colors.stoneDark,
63
+ onSecondary: colors.onStone,
64
+ texture: "deepslate",
65
+ };
66
+ export const nether = {
67
+ ...shared,
68
+ background: "#190C0C",
69
+ surface: "#3A1818",
70
+ surfaceAlt: "#281010",
71
+ surfaceHeader: "#2F1313",
72
+ slot: "#1E0B0B",
73
+ slotHover: "#331616",
74
+ textMuted: "#E8C9C5",
75
+ primary: colors.lava,
76
+ primaryLight: colors.lavaLight,
77
+ primaryDark: colors.lavaDark,
78
+ onPrimary: colors.onLava,
79
+ secondary: colors.gold,
80
+ secondaryLight: colors.goldLight,
81
+ secondaryDark: colors.goldDark,
82
+ onSecondary: colors.onGold,
83
+ focus: colors.goldLight,
84
+ texture: "netherrack",
85
+ };
86
+ export const end = {
87
+ ...shared,
88
+ background: "#0E0A14",
89
+ surface: colors.obsidian,
90
+ surfaceAlt: "#1A1324",
91
+ surfaceHeader: "#1E1629",
92
+ slot: "#120D19",
93
+ slotHover: "#2A1F38",
94
+ textMuted: "#D2C8E0",
95
+ primary: colors.amethyst,
96
+ primaryLight: colors.amethystLight,
97
+ primaryDark: colors.amethystDark,
98
+ onPrimary: colors.onAmethyst,
99
+ secondary: colors.sand,
100
+ secondaryLight: colors.sandLight,
101
+ secondaryDark: colors.sandDark,
102
+ onSecondary: colors.onSand,
103
+ focus: colors.diamond,
104
+ texture: "endStone",
105
+ };
106
+ export const themes = {
107
+ grassland,
108
+ cave,
109
+ deepslate,
110
+ nether,
111
+ end,
112
+ };
113
+ export const defaultThemeName = "grassland";
@@ -0,0 +1,37 @@
1
+ import type { TextureToken } from "@malilion/block-ui-tokens";
2
+ export declare const themeNames: readonly ["grassland", "cave", "deepslate", "nether", "end"];
3
+ export type BlockThemeName = (typeof themeNames)[number];
4
+ /**
5
+ * Semantic theme contract (PRD §53) plus the extra roles components need to
6
+ * stay fully themeable without hard-coded colors.
7
+ */
8
+ export interface BlockTheme {
9
+ background: string;
10
+ surface: string;
11
+ surfaceAlt: string;
12
+ primary: string;
13
+ secondary: string;
14
+ border: string;
15
+ text: string;
16
+ textMuted: string;
17
+ /** Text/icon color on top of `primary`. */
18
+ onPrimary: string;
19
+ primaryLight: string;
20
+ primaryDark: string;
21
+ /** Text/icon color on top of `secondary`. */
22
+ onSecondary: string;
23
+ secondaryLight: string;
24
+ secondaryDark: string;
25
+ /** Raised panel header strip. */
26
+ surfaceHeader: string;
27
+ /** Inventory slot / input well background. */
28
+ slot: string;
29
+ slotHover: string;
30
+ /** Focus ring color (≥ 3:1 against surfaces). */
31
+ focus: string;
32
+ /** Modal backdrop. */
33
+ overlay: string;
34
+ /** Texture tiled behind panels and the page. */
35
+ texture: TextureToken;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,eAAO,MAAM,UAAU,8DAA+D,CAAC;AAEvF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAElB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,YAAY,CAAC;CACvB"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export const themeNames = ["grassland", "cave", "deepslate", "nether", "end"];
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@malilion/block-ui-themes",
3
+ "version": "0.1.0",
4
+ "description": "Themes (grassland, cave, deepslate, nether, end) for Block UI.",
5
+ "license": "MIT",
6
+ "author": "Block UI Contributors",
7
+ "homepage": "https://malilion.github.io/BlockUI/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/malilion/BlockUI.git",
11
+ "directory": "packages/themes"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/malilion/BlockUI/issues"
15
+ },
16
+ "type": "module",
17
+ "sideEffects": [
18
+ "*.css"
19
+ ],
20
+ "exports": {
21
+ ".": {
22
+ "@block-ui/source": "./src/index.ts",
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ },
26
+ "./themes.css": "./themes.css",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "themes.css",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "keywords": [
39
+ "block-ui",
40
+ "themes",
41
+ "pixel"
42
+ ],
43
+ "dependencies": {
44
+ "@malilion/block-ui-tokens": "^0.1.0"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc -p tsconfig.build.json && node scripts/generate-css.mjs",
48
+ "generate": "tsc -p tsconfig.build.json && node scripts/generate-css.mjs",
49
+ "typecheck": "tsc -p tsconfig.json"
50
+ }
51
+ }
package/themes.css ADDED
@@ -0,0 +1,121 @@
1
+ /* Generated by @malilion/block-ui-themes — do not edit by hand. Run `pnpm generate`. */
2
+ :root,
3
+ [data-theme="grassland"] {
4
+ color-scheme: dark;
5
+ --block-border: #17191c;
6
+ --block-text: #ffffff;
7
+ --block-focus: #f2c94c;
8
+ --block-overlay: rgba(8, 9, 11, 0.72);
9
+ --block-bg: #1b1e22;
10
+ --block-surface: #34373c;
11
+ --block-surface-alt: #26292d;
12
+ --block-surface-header: #2a2d31;
13
+ --block-slot: #1e2024;
14
+ --block-slot-hover: #2c2f34;
15
+ --block-text-muted: #c9cdd2;
16
+ --block-primary: #5d9b3d;
17
+ --block-primary-light: #7ebe55;
18
+ --block-primary-dark: #356b28;
19
+ --block-on-primary: #0f230a;
20
+ --block-secondary: #8a5a2b;
21
+ --block-secondary-light: #aa7843;
22
+ --block-secondary-dark: #5e3c1c;
23
+ --block-on-secondary: #ffffff;
24
+ --block-texture: var(--block-texture-stone);
25
+ }
26
+
27
+ [data-theme="cave"] {
28
+ color-scheme: dark;
29
+ --block-border: #17191c;
30
+ --block-text: #ffffff;
31
+ --block-focus: #52d9d0;
32
+ --block-overlay: rgba(8, 9, 11, 0.72);
33
+ --block-bg: #121417;
34
+ --block-surface: #2a2c30;
35
+ --block-surface-alt: #1e2023;
36
+ --block-surface-header: #232528;
37
+ --block-slot: #16181a;
38
+ --block-slot-hover: #25272b;
39
+ --block-text-muted: #bfc4ca;
40
+ --block-primary: #f2c94c;
41
+ --block-primary-light: #fce48c;
42
+ --block-primary-dark: #b88a1b;
43
+ --block-on-primary: #2a1a05;
44
+ --block-secondary: #737373;
45
+ --block-secondary-light: #959595;
46
+ --block-secondary-dark: #414141;
47
+ --block-on-secondary: #ffffff;
48
+ --block-texture: var(--block-texture-stone);
49
+ }
50
+
51
+ [data-theme="deepslate"] {
52
+ color-scheme: dark;
53
+ --block-border: #17191c;
54
+ --block-text: #ffffff;
55
+ --block-focus: #f2c94c;
56
+ --block-overlay: rgba(8, 9, 11, 0.72);
57
+ --block-bg: #1d2025;
58
+ --block-surface: #292929;
59
+ --block-surface-alt: #1f1f21;
60
+ --block-surface-header: #232325;
61
+ --block-slot: #18181a;
62
+ --block-slot-hover: #2a2a2d;
63
+ --block-text-muted: #c9cdd2;
64
+ --block-primary: #52d9d0;
65
+ --block-primary-light: #a5f3ee;
66
+ --block-primary-dark: #1e9b93;
67
+ --block-on-primary: #0b1f1e;
68
+ --block-secondary: #737373;
69
+ --block-secondary-light: #959595;
70
+ --block-secondary-dark: #414141;
71
+ --block-on-secondary: #ffffff;
72
+ --block-texture: var(--block-texture-deepslate);
73
+ }
74
+
75
+ [data-theme="nether"] {
76
+ color-scheme: dark;
77
+ --block-border: #17191c;
78
+ --block-text: #ffffff;
79
+ --block-focus: #fce48c;
80
+ --block-overlay: rgba(8, 9, 11, 0.72);
81
+ --block-bg: #190c0c;
82
+ --block-surface: #3a1818;
83
+ --block-surface-alt: #281010;
84
+ --block-surface-header: #2f1313;
85
+ --block-slot: #1e0b0b;
86
+ --block-slot-hover: #331616;
87
+ --block-text-muted: #e8c9c5;
88
+ --block-primary: #e8772e;
89
+ --block-primary-light: #ffae4a;
90
+ --block-primary-dark: #a8461a;
91
+ --block-on-primary: #200c03;
92
+ --block-secondary: #f2c94c;
93
+ --block-secondary-light: #fce48c;
94
+ --block-secondary-dark: #b88a1b;
95
+ --block-on-secondary: #2a1a05;
96
+ --block-texture: var(--block-texture-netherrack);
97
+ }
98
+
99
+ [data-theme="end"] {
100
+ color-scheme: dark;
101
+ --block-border: #17191c;
102
+ --block-text: #ffffff;
103
+ --block-focus: #52d9d0;
104
+ --block-overlay: rgba(8, 9, 11, 0.72);
105
+ --block-bg: #0e0a14;
106
+ --block-surface: #251b31;
107
+ --block-surface-alt: #1a1324;
108
+ --block-surface-header: #1e1629;
109
+ --block-slot: #120d19;
110
+ --block-slot-hover: #2a1f38;
111
+ --block-text-muted: #d2c8e0;
112
+ --block-primary: #9a6bd6;
113
+ --block-primary-light: #be9bec;
114
+ --block-primary-dark: #6a44a0;
115
+ --block-on-primary: #160c24;
116
+ --block-secondary: #d8c78e;
117
+ --block-secondary-light: #ede1b4;
118
+ --block-secondary-dark: #a8955c;
119
+ --block-on-secondary: #1f1a0b;
120
+ --block-texture: var(--block-texture-end-stone);
121
+ }