@hardimpactdev/craft-ui 0.0.6 → 0.0.8

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.
Files changed (36) hide show
  1. package/dist/craft-ui.css +1 -1
  2. package/dist/craft-ui.js +11928 -10977
  3. package/dist/index.d.ts +5 -1
  4. package/dist/src/components/InputError.vue.d.ts +5 -0
  5. package/dist/src/components/TextLink.vue.d.ts +27 -0
  6. package/dist/src/components/native-select/NativeSelectOptGroup.vue.d.ts +4 -4
  7. package/dist/src/components/native-select/NativeSelectOption.vue.d.ts +4 -4
  8. package/dist/src/layouts/auth/AuthCardLayout.vue.d.ts +28 -0
  9. package/dist/src/layouts/auth/AuthLayout.vue.d.ts +27 -0
  10. package/dist/src/layouts/auth/AuthSimpleLayout.vue.d.ts +2 -1
  11. package/dist/src/layouts/auth/AuthSplitLayout.vue.d.ts +29 -0
  12. package/dist/src/pages/auth/ConfirmPassword.vue.d.ts +38 -0
  13. package/dist/src/pages/auth/ForgotPassword.vue.d.ts +47 -0
  14. package/dist/src/pages/auth/Login.vue.d.ts +59 -0
  15. package/dist/src/pages/auth/Register.vue.d.ts +51 -0
  16. package/dist/src/pages/auth/ResetPassword.vue.d.ts +47 -0
  17. package/dist/src/pages/auth/TwoFactorChallenge.vue.d.ts +44 -0
  18. package/dist/src/pages/auth/VerifyEmail.vue.d.ts +37 -0
  19. package/dist/src/pages/auth/index.d.ts +8 -0
  20. package/dist/src/pages/auth/types.d.ts +54 -0
  21. package/dist/src/vite/aliases.d.ts +13 -0
  22. package/dist/src/vite/defineCraftConfig.d.ts +6 -21
  23. package/dist/src/vite/plugins.d.ts +17 -0
  24. package/dist/src/vite/server.d.ts +10 -0
  25. package/dist/src/vite/types.d.ts +64 -0
  26. package/dist/vite/aliases.js +62 -0
  27. package/dist/vite/defineCraftConfig.js +18 -161
  28. package/dist/vite/plugins.js +59 -0
  29. package/dist/vite/server.js +30 -0
  30. package/dist/vite/ts/aliases.ts +132 -0
  31. package/dist/vite/ts/defineCraftConfig.ts +23 -212
  32. package/dist/vite/ts/plugins.ts +86 -0
  33. package/dist/vite/ts/server.ts +42 -0
  34. package/dist/vite/ts/types.ts +73 -0
  35. package/dist/vite/types.js +0 -0
  36. package/package.json +1 -1
@@ -1,21 +1,6 @@
1
- interface viteConfigOptions {
2
- laravel?: {
3
- input?: string[];
4
- refresh?: boolean;
5
- };
6
- plugins?: any[];
7
- aliases?: any[];
8
- ui?: {
9
- localPath?: string;
10
- };
11
- }
12
- export declare function defineCraftConfig(options?: viteConfigOptions): import('vite').UserConfigFnObject;
13
- export declare function pluginConfig(options: viteConfigOptions): ({
14
- name: string;
15
- enforce: string;
16
- }[] | import('vite').PluginOption)[];
17
- export declare function aliasConfig(aliases?: any[], ui?: any): {
18
- dedupe: string[];
19
- alias: any[];
20
- };
21
- export {};
1
+ import { CraftConfigOptions } from './types.js';
2
+ export type { CraftConfigOptions } from './types.js';
3
+ export { getPlugins } from './plugins.js';
4
+ export { getServerConfig } from './server.js';
5
+ export { getResolveConfig } from './aliases.js';
6
+ export declare function defineCraftConfig(options?: CraftConfigOptions): import('vite').UserConfigFnObject;
@@ -0,0 +1,17 @@
1
+ import { CraftConfigOptions } from './types.js';
2
+ /**
3
+ * Configure all Vite plugins for the Craft stack
4
+ *
5
+ * Includes:
6
+ * - craft: Virtual module for Inertia app initialization
7
+ * - laravel: Laravel Vite integration
8
+ * - tailwindcss: Tailwind CSS v4
9
+ * - i18n: Laravel Vue i18n
10
+ * - vue: Vue 3 SFC support
11
+ * - vueDevTools: Vue DevTools integration
12
+ * - run: Auto-run artisan commands on file changes (dev only)
13
+ */
14
+ export declare function getPlugins(options: CraftConfigOptions): (false | {
15
+ name: string;
16
+ enforce: string;
17
+ }[] | import('vite').Plugin<any> | import('vite').PluginOption[] | Promise<import('vite').Plugin<any> | (false | null | undefined) | import('vite').PluginOption[]> | null | undefined)[];
@@ -0,0 +1,10 @@
1
+ import { ServerOptions } from 'vite';
2
+ /**
3
+ * Configure Vite dev server for Laravel apps behind a reverse proxy (Caddy/nginx)
4
+ *
5
+ * Handles:
6
+ * - HMR WebSocket connection through the proxy (wss://app.test:443)
7
+ * - Correct origin for CORS and asset URLs
8
+ * - Binding to all interfaces for proxy access
9
+ */
10
+ export declare function getServerConfig(mode: string): ServerOptions;
@@ -0,0 +1,64 @@
1
+ import { Alias } from 'vite';
2
+ /**
3
+ * Configuration options for defineCraftConfig
4
+ */
5
+ export interface CraftConfigOptions {
6
+ /**
7
+ * Laravel Vite plugin options
8
+ */
9
+ laravel?: {
10
+ /** Entry points for the application */
11
+ input?: string[];
12
+ /** Enable file refresh on changes */
13
+ refresh?: boolean;
14
+ };
15
+ /**
16
+ * Additional Vite plugins to include
17
+ */
18
+ plugins?: any[];
19
+ /**
20
+ * Additional Vite aliases
21
+ */
22
+ aliases?: Alias[];
23
+ /**
24
+ * Local UI library configuration for development with symlinked packages
25
+ */
26
+ ui?: LocalUiOptions;
27
+ }
28
+ /**
29
+ * Configuration for local UI library development
30
+ *
31
+ * When developing craft-ui alongside an app, this enables HMR by:
32
+ * 1. Redirecting package imports to source files instead of dist/
33
+ * 2. Resolving conflicting aliases (like @/) based on importer location
34
+ */
35
+ export interface LocalUiOptions {
36
+ /**
37
+ * Relative path from app root to the symlinked craft-ui directory
38
+ * @example '../craft-ui'
39
+ */
40
+ localPath?: string;
41
+ }
42
+ /**
43
+ * Internal alias configuration for local package resolution
44
+ */
45
+ export interface LocalAliasConfig {
46
+ /** Regex pattern to match imports */
47
+ pattern: RegExp;
48
+ /** The replacement path or alias */
49
+ replacement: string;
50
+ /**
51
+ * Absolute path to the library (for importer detection)
52
+ * If set along with basePaths, enables context-aware resolution
53
+ */
54
+ libraryPath?: string;
55
+ /**
56
+ * Base paths for context-aware resolution
57
+ */
58
+ basePaths?: {
59
+ /** Path to use when import is from the app */
60
+ app: string;
61
+ /** Path to use when import is from the library */
62
+ library: string;
63
+ };
64
+ }
@@ -0,0 +1,62 @@
1
+ import path from "path";
2
+ function getResolveConfig(options) {
3
+ const aliases = [...options.aliases || []];
4
+ if (isDevMode() && options.ui?.localPath) {
5
+ aliases.push(...createLocalDevAliases(options.ui.localPath));
6
+ }
7
+ return {
8
+ // Prevent duplicate instances of packages that must be singletons
9
+ dedupe: ["@inertiajs/vue3", "@tailwindcss/vite"],
10
+ alias: aliases
11
+ };
12
+ }
13
+ function createLocalDevAliases(localPath) {
14
+ const absoluteLibraryPath = path.resolve(process.cwd(), localPath);
15
+ const configs = [
16
+ // Handle @/ alias - resolve based on importer location
17
+ {
18
+ pattern: /^@\//,
19
+ replacement: "@/",
20
+ libraryPath: absoluteLibraryPath,
21
+ basePaths: {
22
+ app: "./resources/js",
23
+ library: path.join(localPath, "src")
24
+ }
25
+ },
26
+ // Redirect package imports to source
27
+ {
28
+ pattern: /^@hardimpactdev\/craft-ui/,
29
+ replacement: path.join(localPath, "index.ts")
30
+ }
31
+ ];
32
+ return configs.map(createAliasFromConfig);
33
+ }
34
+ function createAliasFromConfig(config) {
35
+ if (!config.libraryPath || !config.basePaths) {
36
+ return {
37
+ find: config.pattern,
38
+ replacement: path.resolve(process.cwd(), config.replacement)
39
+ };
40
+ }
41
+ return {
42
+ find: config.pattern,
43
+ replacement: config.replacement,
44
+ customResolver: createContextAwareResolver(config)
45
+ };
46
+ }
47
+ function createContextAwareResolver(config) {
48
+ return async function customResolver(source, importer) {
49
+ const isFromLibrary = importer?.includes(config.libraryPath);
50
+ const basePath = isFromLibrary ? config.basePaths.library : config.basePaths.app;
51
+ const importPath = source.replace(config.replacement, "");
52
+ const resolvedPath = path.resolve(process.cwd(), basePath, importPath);
53
+ const result = await this.resolve(resolvedPath);
54
+ return result?.id;
55
+ };
56
+ }
57
+ function isDevMode() {
58
+ return !process.argv.includes("build");
59
+ }
60
+ export {
61
+ getResolveConfig
62
+ };
@@ -1,166 +1,23 @@
1
- import { defineConfig, loadEnv } from "vite";
2
- import vue from "@vitejs/plugin-vue";
3
- import path from "path";
4
- import laravel from "laravel-vite-plugin";
5
- import { run } from "vite-plugin-run";
6
- import { craft } from "./craftPlugin.js";
7
- import tailwindcss from "@tailwindcss/vite";
8
- import i18n from "laravel-vue-i18n/vite";
9
- import vueDevTools from "vite-plugin-vue-devtools";
1
+ import { defineConfig } from "vite";
2
+ import { getPlugins } from "./plugins.js";
3
+ import { getServerConfig } from "./server.js";
4
+ import { getResolveConfig } from "./aliases.js";
5
+ import { getPlugins as getPlugins2 } from "./plugins.js";
6
+ import { getServerConfig as getServerConfig2 } from "./server.js";
7
+ import { getResolveConfig as getResolveConfig2 } from "./aliases.js";
10
8
  function defineCraftConfig(options = {}) {
11
- return defineConfig(({ mode }) => {
12
- const serverConfig = getServerConfig(mode);
13
- return {
14
- plugins: [
15
- ...pluginConfig(options),
16
- ...options.plugins || [],
17
- // Plugin to enforce allowedHosts after laravel-vite-plugin
18
- // This bypasses Vite's DNS rebinding protection which conflicts with reverse proxy setups
19
- {
20
- name: "craft-allowed-hosts",
21
- enforce: "post",
22
- config() {
23
- return {
24
- server: {
25
- allowedHosts: true
26
- }
27
- };
28
- }
29
- }
30
- ],
31
- resolve: {
32
- ...aliasConfig(options.aliases, options.ui)
33
- },
34
- server: serverConfig
35
- };
36
- });
37
- }
38
- function getServerConfig(mode) {
39
- const env = loadEnv(mode, process.cwd());
40
- const appUrl = env.VITE_APP_URL;
41
- if (!appUrl) {
42
- return { host: "0.0.0.0" };
43
- }
44
- try {
45
- const url = new URL(appUrl);
46
- const isHttps = url.protocol === "https:";
47
- return {
48
- host: "0.0.0.0",
49
- origin: appUrl,
50
- allowedHosts: true,
51
- hmr: {
52
- host: url.hostname,
53
- protocol: isHttps ? "wss" : "ws",
54
- clientPort: isHttps ? 443 : parseInt(url.port) || 80
55
- }
56
- };
57
- } catch {
58
- return { host: "0.0.0.0" };
59
- }
60
- }
61
- function pluginConfig(options) {
62
- return [
63
- craft(),
64
- laravel({
65
- input: options.laravel?.input || ["resources/js/app.ts"],
66
- refresh: options.laravel?.refresh || true
67
- }),
68
- tailwindcss(),
69
- i18n(),
70
- vue({
71
- template: {
72
- transformAssetUrls: {
73
- base: null,
74
- includeAbsolute: false
75
- },
76
- compilerOptions: {
77
- isCustomElement: (tag) => tag === "trix-editor"
78
- }
79
- }
80
- }),
81
- runConfiguration(),
82
- vueDevTools({
83
- appendTo: "virtual:craft",
84
- launchEditor: import.meta.env?.VITE_EDITOR || "cursor"
85
- })
86
- ].filter(Boolean);
87
- }
88
- function runConfiguration() {
89
- if (false) {
90
- return null;
91
- }
92
- return run([
93
- {
94
- name: "waymaker",
95
- run: ["php", "artisan", "waymaker:generate"],
96
- pattern: ["app/**/Http/**/*.php"]
97
- },
98
- {
99
- name: "wayfinder",
100
- run: ["php", "artisan", "wayfinder:generate"],
101
- pattern: ["routes/*.php", "app/**/Http/**/*.php"]
102
- },
103
- {
104
- name: "typescript",
105
- run: ["php", "artisan", "typescript:transform"],
106
- pattern: ["app/{Data,Enums}/**/*.php"]
107
- }
108
- ]);
109
- }
110
- function aliasConfig(aliases = [], ui = {}) {
111
- if (!process.argv.includes("build") && ui.localPath) {
112
- const absoluteLibraryPath = path.resolve(process.cwd(), ui.localPath);
113
- const localAliases = [
114
- // The following alias will make the @ alias work correctly depending on the importer path.
115
- {
116
- regex: /^@\//,
117
- replacement: "@/",
118
- libraryPath: absoluteLibraryPath,
119
- aliasLocalBasePath: "./resources/js",
120
- aliasExternalBasePath: path.join(ui.localPath, "src")
121
- },
122
- // The following alias config will change all package references like import { Dialog } from '@hardimpactdev/craft-ui';
123
- // to the library's index.ts file instead.
124
- {
125
- regex: /^@hardimpactdev\/craft-ui/,
126
- replacement: path.join(ui.localPath, "index.ts")
127
- }
128
- ];
129
- aliases.push(...aliasLocalPackage(localAliases));
130
- }
131
- return {
132
- dedupe: ["@inertiajs/vue3", "@tailwindcss/vite"],
133
- alias: aliases
134
- };
135
- }
136
- function aliasLocalPackage(aliases) {
137
- return aliases.map((alias) => {
138
- if (!alias.libraryPath && !alias.aliasLocalBasePath && !alias.aliasExternalBasePath) {
139
- return {
140
- find: alias.regex,
141
- replacement: path.resolve(process.cwd(), alias.replacement)
142
- };
143
- }
144
- return {
145
- find: alias.regex,
146
- replacement: alias.replacement,
147
- async customResolver(source, importer) {
148
- let resolvedPath = "";
149
- resolvedPath = path.resolve(
150
- // get the directory name of the importer
151
- process.cwd(),
152
- // if the importer string includes the folder name, use the external path, otherwise use the local path
153
- importer?.includes(alias.libraryPath) ? alias.aliasExternalBasePath : alias.aliasLocalBasePath,
154
- // remove the alias replacement from the source path
155
- source.replace(alias.replacement, "")
156
- );
157
- return (await this.resolve(resolvedPath))?.id;
158
- }
159
- };
160
- });
9
+ return defineConfig(({ mode }) => ({
10
+ plugins: [
11
+ ...getPlugins(options),
12
+ ...options.plugins || []
13
+ ],
14
+ resolve: getResolveConfig(options),
15
+ server: getServerConfig(mode)
16
+ }));
161
17
  }
162
18
  export {
163
- aliasConfig,
164
19
  defineCraftConfig,
165
- pluginConfig
20
+ getPlugins2 as getPlugins,
21
+ getResolveConfig2 as getResolveConfig,
22
+ getServerConfig2 as getServerConfig
166
23
  };
@@ -0,0 +1,59 @@
1
+ import vue from "@vitejs/plugin-vue";
2
+ import laravel from "laravel-vite-plugin";
3
+ import { run } from "vite-plugin-run";
4
+ import tailwindcss from "@tailwindcss/vite";
5
+ import i18n from "laravel-vue-i18n/vite";
6
+ import vueDevTools from "vite-plugin-vue-devtools";
7
+ import { craft } from "./craftPlugin.js";
8
+ function getPlugins(options) {
9
+ return [
10
+ craft(),
11
+ laravel({
12
+ input: options.laravel?.input || ["resources/js/app.ts"],
13
+ refresh: options.laravel?.refresh ?? true
14
+ }),
15
+ tailwindcss(),
16
+ i18n(),
17
+ vue({
18
+ template: {
19
+ transformAssetUrls: {
20
+ base: null,
21
+ includeAbsolute: false
22
+ },
23
+ compilerOptions: {
24
+ isCustomElement: (tag) => tag === "trix-editor"
25
+ }
26
+ }
27
+ }),
28
+ getArtisanRunners(),
29
+ vueDevTools({
30
+ appendTo: "virtual:craft",
31
+ launchEditor: import.meta.env?.VITE_EDITOR || "cursor"
32
+ })
33
+ ].filter(Boolean);
34
+ }
35
+ function getArtisanRunners() {
36
+ if (false) {
37
+ return null;
38
+ }
39
+ return run([
40
+ {
41
+ name: "waymaker",
42
+ run: ["php", "artisan", "waymaker:generate"],
43
+ pattern: ["app/**/Http/**/*.php"]
44
+ },
45
+ {
46
+ name: "wayfinder",
47
+ run: ["php", "artisan", "wayfinder:generate"],
48
+ pattern: ["routes/*.php", "app/**/Http/**/*.php"]
49
+ },
50
+ {
51
+ name: "typescript",
52
+ run: ["php", "artisan", "typescript:transform"],
53
+ pattern: ["app/{Data,Enums}/**/*.php"]
54
+ }
55
+ ]);
56
+ }
57
+ export {
58
+ getPlugins
59
+ };
@@ -0,0 +1,30 @@
1
+ import { loadEnv } from "vite";
2
+ function getServerConfig(mode) {
3
+ const env = loadEnv(mode, process.cwd());
4
+ const appUrl = env.VITE_APP_URL;
5
+ if (!appUrl) {
6
+ return { host: "0.0.0.0" };
7
+ }
8
+ try {
9
+ const url = new URL(appUrl);
10
+ const isHttps = url.protocol === "https:";
11
+ return {
12
+ // Accept connections from reverse proxy
13
+ host: "0.0.0.0",
14
+ // Tell Vite the public origin for asset URLs
15
+ origin: appUrl,
16
+ // Configure HMR to connect through the reverse proxy
17
+ // Without this, browser would try localhost:5173 directly
18
+ hmr: {
19
+ host: url.hostname,
20
+ protocol: isHttps ? "wss" : "ws",
21
+ clientPort: isHttps ? 443 : parseInt(url.port) || 80
22
+ }
23
+ };
24
+ } catch {
25
+ return { host: "0.0.0.0" };
26
+ }
27
+ }
28
+ export {
29
+ getServerConfig
30
+ };
@@ -0,0 +1,132 @@
1
+ import path from 'path';
2
+ import type { Alias } from 'vite';
3
+ import type { CraftConfigOptions, LocalAliasConfig } from './types.js';
4
+
5
+ /**
6
+ * Configure Vite resolve options for the Craft stack
7
+ *
8
+ * Handles two scenarios:
9
+ * 1. Normal: Just returns dedupe config and any custom aliases
10
+ * 2. Local development: Adds aliases for symlinked craft-ui to enable HMR
11
+ */
12
+ export function getResolveConfig(options: CraftConfigOptions) {
13
+ const aliases: Alias[] = [...(options.aliases || [])];
14
+
15
+ // Add local development aliases when craft-ui is symlinked
16
+ if (isDevMode() && options.ui?.localPath) {
17
+ aliases.push(...createLocalDevAliases(options.ui.localPath));
18
+ }
19
+
20
+ return {
21
+ // Prevent duplicate instances of packages that must be singletons
22
+ dedupe: ['@inertiajs/vue3', '@tailwindcss/vite'],
23
+ alias: aliases,
24
+ };
25
+ }
26
+
27
+ /**
28
+ * Create aliases for local craft-ui development
29
+ *
30
+ * When craft-ui is symlinked (e.g., for development), we need to:
31
+ *
32
+ * 1. Redirect package imports to source files
33
+ * `import { Button } from '@hardimpactdev/craft-ui'`
34
+ * → resolves to `../craft-ui/index.ts` instead of `dist/`
35
+ * This enables HMR (dist files can't hot-reload)
36
+ *
37
+ * 2. Handle the @/ alias conflict
38
+ * Both the app and craft-ui use @/ as an alias:
39
+ * - App: @/ → ./resources/js
40
+ * - craft-ui: @/ → ./src
41
+ *
42
+ * When a file in craft-ui imports `@/lib/utils`, we need to resolve
43
+ * it to craft-ui/src/lib/utils, not app/resources/js/lib/utils.
44
+ * The resolver checks WHERE the import comes from to decide.
45
+ */
46
+ function createLocalDevAliases(localPath: string): Alias[] {
47
+ const absoluteLibraryPath = path.resolve(process.cwd(), localPath);
48
+
49
+ const configs: LocalAliasConfig[] = [
50
+ // Handle @/ alias - resolve based on importer location
51
+ {
52
+ pattern: /^@\//,
53
+ replacement: '@/',
54
+ libraryPath: absoluteLibraryPath,
55
+ basePaths: {
56
+ app: './resources/js',
57
+ library: path.join(localPath, 'src'),
58
+ },
59
+ },
60
+
61
+ // Redirect package imports to source
62
+ {
63
+ pattern: /^@hardimpactdev\/craft-ui/,
64
+ replacement: path.join(localPath, 'index.ts'),
65
+ },
66
+ ];
67
+
68
+ return configs.map(createAliasFromConfig);
69
+ }
70
+
71
+ /**
72
+ * Create a Vite alias from our config format
73
+ */
74
+ function createAliasFromConfig(config: LocalAliasConfig): Alias {
75
+ // Simple redirect (no context-aware resolution needed)
76
+ if (!config.libraryPath || !config.basePaths) {
77
+ return {
78
+ find: config.pattern,
79
+ replacement: path.resolve(process.cwd(), config.replacement),
80
+ };
81
+ }
82
+
83
+ // Context-aware resolution: choose base path based on importer location
84
+ return {
85
+ find: config.pattern,
86
+ replacement: config.replacement,
87
+ customResolver: createContextAwareResolver(config),
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Create a resolver that picks the right base path based on where the import comes from
93
+ *
94
+ * @example
95
+ * // Import from app file → use app base path
96
+ * // resources/js/pages/Home.vue imports @/lib/utils
97
+ * // → resolves to resources/js/lib/utils
98
+ *
99
+ * // Import from library file → use library base path
100
+ * // ../craft-ui/src/components/Button.vue imports @/lib/utils
101
+ * // → resolves to ../craft-ui/src/lib/utils
102
+ */
103
+ function createContextAwareResolver(config: LocalAliasConfig) {
104
+ return async function customResolver(
105
+ this: { resolve: (id: string, importer?: string) => Promise<{ id: string } | null> },
106
+ source: string,
107
+ importer: string | undefined
108
+ ): Promise<string | undefined> {
109
+ // Determine if the import is coming from the library or the app
110
+ const isFromLibrary = importer?.includes(config.libraryPath!);
111
+ const basePath = isFromLibrary ? config.basePaths!.library : config.basePaths!.app;
112
+
113
+ // Build the full path by combining:
114
+ // 1. Current working directory
115
+ // 2. The appropriate base path (app or library)
116
+ // 3. The import path (minus the alias prefix)
117
+ const importPath = source.replace(config.replacement, '');
118
+ const resolvedPath = path.resolve(process.cwd(), basePath, importPath);
119
+
120
+ // Use Vite's resolver to get the final path (handles extensions, index files, etc.)
121
+ const result = await this.resolve(resolvedPath);
122
+ return result?.id;
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Check if we're in development mode
128
+ * Used to skip local dev aliases during production builds
129
+ */
130
+ function isDevMode(): boolean {
131
+ return !process.argv.includes('build');
132
+ }