moulify 0.0.1

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 Mouli Bheemaneti
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,190 @@
1
+ <!--
2
+ Get your module up and running quickly.
3
+
4
+ Find and replace all on all files (CMD+SHIFT+F):
5
+ - Name: My Module
6
+ - Package name: moulify
7
+ - Description: My new Nuxt module
8
+ -->
9
+
10
+ # moulify
11
+
12
+ [![npm version][npm-version-src]][npm-version-href]
13
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
14
+ [![License][license-src]][license-href]
15
+ [![Nuxt][nuxt-src]][nuxt-href]
16
+
17
+ moulify is a Nuxt module that provides a small, opinionated UI layer with:
18
+
19
+ - Auto-registered Vue components (Button, Icon)
20
+ - A Fantasticon-generated icon font wired into Nuxt via a plugin
21
+ - Simple theming via color configuration and component prefixing
22
+
23
+ - [✨ &nbsp;Release Notes](/CHANGELOG.md)
24
+ <!-- - [🏀 Online playground](https://stackblitz.com/github/moulibheemaneti/moulify?file=playground%2Fapp.vue) -->
25
+ <!-- - [📖 &nbsp;Documentation](https://example.com) -->
26
+
27
+ ## Features
28
+
29
+ - Auto-imports components from the module:
30
+ - `<moulify-button>` (or with your own prefix)
31
+ - `<moulify-icon>`
32
+ - Configurable prefix for auto-registered components
33
+ - Simple color theming exposed as module options
34
+ - Icon component backed by a generated icon font with type-safe icon names
35
+ - Nuxt plugin that automatically injects the icon CSS
36
+
37
+ ## Quick setup
38
+
39
+ Install the module to your Nuxt application with:
40
+
41
+ ```bash
42
+ npx nuxt module add moulify
43
+ ```
44
+
45
+ This will install `moulify` and add it to the `modules` section of your `nuxt.config`.
46
+
47
+ ### Manual installation
48
+
49
+ If you prefer to wire things up yourself:
50
+
51
+ ```bash
52
+ npm install moulify
53
+ # or
54
+ pnpm add moulify
55
+ # or
56
+ yarn add moulify
57
+ ```
58
+
59
+ Then enable the module in `nuxt.config.ts`:
60
+
61
+ ```ts
62
+ export default defineNuxtConfig({
63
+ modules: ['moulify'],
64
+
65
+ moulify: {
66
+ // Optional: override defaults
67
+ prefix: 'moulify',
68
+ colors: {
69
+ primary: '#0076ff',
70
+ secondary: '#000000',
71
+ tertiary: '#888888',
72
+ },
73
+ },
74
+ })
75
+ ```
76
+
77
+ The module will:
78
+
79
+ - Register a Nuxt plugin that imports the generated icon CSS
80
+ - Auto-register all Vue components from the module using the configured `prefix`
81
+
82
+ ## Configuration
83
+
84
+ Module options are available under the `moulify` key in your `nuxt.config`:
85
+
86
+ ```ts
87
+ interface ModuleOptions {
88
+ prefix?: string
89
+ colors?: {
90
+ primary?: string
91
+ secondary?: string
92
+ tertiary?: string
93
+ }
94
+ }
95
+ ```
96
+
97
+ - `prefix` (default: `'moulify'`): controls the tag names of auto-imported components.
98
+ - For example, with `prefix: 'nc'` you will use `<nc-button>` instead of `<moulify-button>`.
99
+ - `colors`: simple color tokens you can use in your own styling or future theme extensions.
100
+
101
+ ## Components
102
+
103
+ ### `<moulify-button>`
104
+
105
+ A simple, flex-centered button that can render icons on the left and/or right.
106
+
107
+ With the default prefix:
108
+
109
+ ```vue
110
+ <template>
111
+ <moulify-button icon-left="home" icon-right="arrow-right">
112
+ Get started
113
+ </moulify-button>
114
+ </template>
115
+ ```
116
+
117
+ Props:
118
+
119
+ - `iconLeft?: IconsId` – optional icon name rendered before the button content.
120
+ - `iconRight?: IconsId` – optional icon name rendered after the button content.
121
+
122
+ These icon names are derived from the generated icon font (`IconsId` union type). The corresponding icons are rendered via `<moulify-icon>`.
123
+
124
+ ### `<moulify-icon>`
125
+
126
+ A lightweight icon component backed by the Fantasticon-generated font family.
127
+
128
+ With the default prefix:
129
+
130
+ ```vue
131
+ <template>
132
+ <moulify-icon name="home" :size="32" color="#00DC82" />
133
+ </template>
134
+ ```
135
+
136
+ Props:
137
+
138
+ - `name: IconsId` – required icon name, type-safe union of all available icons.
139
+ - `size?: number` (default: `24`) – font size in pixels.
140
+ - `color?: string` (default: `'currentColor'`) – CSS color to apply.
141
+
142
+ If an invalid icon name is passed, the component will fall back to rendering the `name` as uppercase text so you can easily spot configuration issues in the UI.
143
+
144
+ The required CSS for the icon font is automatically imported by the module’s Nuxt plugin, so you don’t need to manually include any styles.
145
+
146
+
147
+ ## Contribution
148
+
149
+ <details>
150
+ <summary>Local development</summary>
151
+
152
+ ```bash
153
+ # Install dependencies
154
+ npm install
155
+
156
+ # Generate type stubs
157
+ npm run dev:prepare
158
+
159
+ # Develop with the playground
160
+ npm run dev
161
+
162
+ # Build the playground
163
+ npm run dev:build
164
+
165
+ # Run ESLint
166
+ npm run lint
167
+
168
+ # Run Vitest
169
+ npm run test
170
+ npm run test:watch
171
+
172
+ # Release new version
173
+ npm run release
174
+ ```
175
+
176
+ </details>
177
+
178
+
179
+ <!-- Badges -->
180
+ [npm-version-src]: https://img.shields.io/npm/v/moulify/latest.svg?style=flat&colorA=020420&colorB=00DC82
181
+ [npm-version-href]: https://npmjs.com/package/moulify
182
+
183
+ [npm-downloads-src]: https://img.shields.io/npm/dm/moulify.svg?style=flat&colorA=020420&colorB=00DC82
184
+ [npm-downloads-href]: https://npm.chart.dev/moulify
185
+
186
+ [license-src]: https://img.shields.io/npm/l/moulify.svg?style=flat&colorA=020420&colorB=00DC82
187
+ [license-href]: https://npmjs.com/package/moulify
188
+
189
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt
190
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,3 @@
1
+ const version = "0.0.1";
2
+
3
+ export { version };
@@ -0,0 +1,50 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ /**
5
+ * Prefix used for auto-registered components.
6
+ *
7
+ * Example:
8
+ * - prefix: 'nc' -> <nc-button>, <nc-header>
9
+ * - prefix: 'moulify' (default) -> <moulify-button>, <moulify-header>
10
+ */
11
+ prefix?: string;
12
+ /**
13
+ * Colors used for the module.
14
+ *
15
+ * Example:
16
+ * - colors: { primary: '#000', secondary: '#fff', tertiary: '#000' }
17
+ * - colors: { primary: '#000', secondary: '#fff', tertiary: '#000' }
18
+ */
19
+ colors?: MoulifyModuleColors;
20
+ }
21
+ interface MoulifyModuleColors {
22
+ /**
23
+ * Primary color used for the module.
24
+ *
25
+ * Example:
26
+ * - primary: '#000'
27
+ * - primary: '#000'
28
+ */
29
+ primary?: string;
30
+ /**
31
+ * Secondary color used for the module.
32
+ *
33
+ * Example:
34
+ * - secondary: '#fff'
35
+ * - secondary: '#fff'
36
+ */
37
+ secondary?: string;
38
+ /**
39
+ * Tertiary color used for the module.
40
+ *
41
+ * Example:
42
+ * - tertiary: '#000'
43
+ * - tertiary: '#000'
44
+ */
45
+ tertiary?: string;
46
+ }
47
+
48
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
49
+
50
+ export { _default as default };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "moulify",
3
+ "configKey": "moulify",
4
+ "version": "0.0.1",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "unknown"
8
+ }
9
+ }
@@ -0,0 +1,37 @@
1
+ import { defineNuxtModule, createResolver, addPlugin, addComponentsDir } from '@nuxt/kit';
2
+
3
+ const versionFromPackageJson = (await import('./chunks/package.mjs')).version;
4
+ const module$1 = defineNuxtModule({
5
+ meta: {
6
+ name: "moulify",
7
+ configKey: "moulify",
8
+ version: versionFromPackageJson
9
+ },
10
+ defaults: {
11
+ prefix: "moulify",
12
+ colors: {
13
+ primary: "#0076ff",
14
+ // little element plus default blue
15
+ secondary: "#000",
16
+ // black
17
+ tertiary: "#888"
18
+ // grey
19
+ }
20
+ },
21
+ setup(options, _nuxt) {
22
+ const resolver = createResolver(import.meta.url);
23
+ addPlugin(resolver.resolve("./runtime/plugin"));
24
+ addComponentsDir({
25
+ // points to src/runtime/app/components
26
+ path: resolver.resolve("runtime/app/components"),
27
+ // optional: control naming
28
+ pathPrefix: false,
29
+ // prefix controls auto-imported component names, e.g. <nc-button>, <moulify-button>
30
+ prefix: options.prefix,
31
+ // optional: restrict to .vue files (types.ts will be ignored anyway)
32
+ extensions: [".vue"]
33
+ });
34
+ }
35
+ });
36
+
37
+ export { module$1 as default };
@@ -0,0 +1,17 @@
1
+ import type { ButtonProps } from './types.js';
2
+ declare var __VLS_6: {};
3
+ type __VLS_Slots = {} & {
4
+ default?: (props: typeof __VLS_6) => any;
5
+ };
6
+ declare const __VLS_base: import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{}>, {
7
+ iconLeft: import("../../../../assets/generated/fonts/icons.js").IconsId;
8
+ iconRight: import("../../../../assets/generated/fonts/icons.js").IconsId;
9
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ type __VLS_WithSlots<T, S> = T & {
14
+ new (): {
15
+ $slots: S;
16
+ };
17
+ };
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <button class="moulify-btn">
3
+ <moulify-icon v-if="props.iconLeft" :name="props.iconLeft" />
4
+ <slot />
5
+ <moulify-icon v-if="props.iconRight" :name="props.iconRight" />
6
+ </button>
7
+ </template>
8
+
9
+ <script setup>
10
+ const props = defineProps({
11
+ iconLeft: { type: String, required: false, default: void 0 },
12
+ iconRight: { type: String, required: false, default: void 0 }
13
+ });
14
+ </script>
15
+
16
+ <style>
17
+ .moulify-btn {
18
+ background-color: black;
19
+ align-items: center;
20
+ color: #fff;
21
+ padding: 10px;
22
+ border-radius: 5px;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ gap: 8px;
27
+ }
28
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { ButtonProps } from './types.js';
2
+ declare var __VLS_6: {};
3
+ type __VLS_Slots = {} & {
4
+ default?: (props: typeof __VLS_6) => any;
5
+ };
6
+ declare const __VLS_base: import("vue").DefineComponent<ButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ButtonProps> & Readonly<{}>, {
7
+ iconLeft: import("../../../../assets/generated/fonts/icons.js").IconsId;
8
+ iconRight: import("../../../../assets/generated/fonts/icons.js").IconsId;
9
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ type __VLS_WithSlots<T, S> = T & {
14
+ new (): {
15
+ $slots: S;
16
+ };
17
+ };
@@ -0,0 +1,5 @@
1
+ import type { IconsId } from '../../../../assets/generated/fonts/icons.js';
2
+ export interface ButtonProps {
3
+ iconLeft?: IconsId;
4
+ iconRight?: IconsId;
5
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <header class="moulify-header">
3
+ Header component
4
+ </header>
5
+ </template>
6
+
7
+ <style>
8
+ .moulify-header{background-color:#000;border-radius:5px;color:#fff;padding:10px}
9
+ </style>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import type { IconProps } from './types.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<IconProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IconProps> & Readonly<{}>, {
3
+ size: number;
4
+ color: string;
5
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <i v-if="isIconValid" :class="`icon icon--${name}`" />
3
+
4
+ <!-- Fallback: Showing uppercase text -->
5
+ <span v-else class="icon-fallback"> {{ props.name }}</span>
6
+ </template>
7
+
8
+ <script setup>
9
+ import { computed } from "vue";
10
+ import { ALL_ICONS } from "../../../../utils/constants";
11
+ defineOptions({ name: "NcIcon" });
12
+ const props = defineProps({
13
+ name: { type: String, required: true },
14
+ size: { type: Number, required: false, default: 24 },
15
+ color: { type: String, required: false, default: "white" }
16
+ });
17
+ const isIconValid = computed(() => ALL_ICONS.includes(props.name));
18
+ const iconStyle = computed(() => ({
19
+ // fontSize: pixelToRem(props.size),
20
+ fontSize: `${props.size}px`,
21
+ color: props.color
22
+ }));
23
+ </script>
24
+
25
+ <style>
26
+ .icon {
27
+ display: inline-block;
28
+ line-height: 0;
29
+ color: v-bind("iconStyle.color");
30
+ font-size: v-bind("iconStyle.fontSize");
31
+ }
32
+
33
+ .icon-fallback {
34
+ text-transform: uppercase;
35
+ }
36
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { IconProps } from './types.js';
2
+ declare const __VLS_export: import("vue").DefineComponent<IconProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IconProps> & Readonly<{}>, {
3
+ size: number;
4
+ color: string;
5
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import type { IconsId } from '~/src/assets/generated/fonts/icons';
2
+ /**
3
+ * Props for the Icon component.
4
+ *
5
+ * Defines the properties required to render an icon from the Fantasticon-generated font family,
6
+ * including the icon's name, optional size, and optional color.
7
+ */
8
+ export interface IconProps {
9
+ /** Icon name from the Fantasticon-generated font family. */
10
+ name: IconsId;
11
+ /**
12
+ * Font size for the icon.
13
+ *
14
+ * @default 24
15
+ */
16
+ size?: number;
17
+ /**
18
+ * Color of the icon.
19
+ *
20
+ * @default "currentColor" - Depending on SVG color.
21
+ */
22
+ color?: string;
23
+ }
File without changes
@@ -0,0 +1,3 @@
1
+ import '../assets/generated/fonts/icons.css.js';
2
+ declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
3
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { defineNuxtPlugin } from "#app";
2
+ import "../assets/generated/fonts/icons.css";
3
+ export default defineNuxtPlugin((_nuxtApp) => {
4
+ console.log("Plugin injected by moulify!");
5
+ });
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../../../.nuxt/tsconfig.server.json",
3
+ }
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module.mjs'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "moulify",
3
+ "version": "0.0.1",
4
+ "description": "My new Nuxt module",
5
+ "repository": "https://github.com/moulibheemaneti/moulify",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types.d.mts",
11
+ "import": "./dist/module.mjs"
12
+ }
13
+ },
14
+ "main": "./dist/module.mjs",
15
+ "typesVersions": {
16
+ "*": {
17
+ ".": [
18
+ "./dist/types.d.mts"
19
+ ]
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "workspaces": [
26
+ "playground"
27
+ ],
28
+ "scripts": {
29
+ "build:icons": "bun run scripts/generate-icon-fonts.ts",
30
+ "prepare": "husky",
31
+ "prepack": "nuxt-module-build build",
32
+ "clean": "rm -rf playground/node_modules .nuxt dist node_modules bun.lock playground/dist",
33
+ "clean-install": "bun run clean && bun i",
34
+ "dev": "bun run dev:prepare && nuxt dev playground",
35
+ "dev:clean": "bun run clean-install && bun run dev",
36
+ "dev:build": "nuxt build playground",
37
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
38
+ "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
39
+ "lint": "eslint .",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest watch",
42
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
43
+ },
44
+ "dependencies": {
45
+ "@nuxt/kit": "^4.3.1",
46
+ "vue": "^3.5.29"
47
+ },
48
+ "devDependencies": {
49
+ "@nuxt/devtools": "^3.2.1",
50
+ "@nuxt/eslint-config": "^1.15.1",
51
+ "@nuxt/module-builder": "^1.0.2",
52
+ "@nuxt/schema": "^4.3.1",
53
+ "@nuxt/test-utils": "^4.0.0",
54
+ "@types/node": "latest",
55
+ "changelogen": "^0.6.2",
56
+ "husky": "^9.0.0",
57
+ "@commitlint/cli": "^19.0.0",
58
+ "@commitlint/config-conventional": "^19.0.0",
59
+ "eslint": "^10.0.1",
60
+ "fantasticon": "^4.1.0",
61
+ "nuxt": "^4.3.1",
62
+ "sass": "^1.97.3",
63
+ "typescript": "~5.9.3",
64
+ "vitest": "^4.0.18",
65
+ "vue-tsc": "^3.2.5"
66
+ }
67
+ }