@owdproject/nuxt-theme-ui 0.0.0-stage → 4.0.0-alpha.3

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 (85) hide show
  1. package/dist/i18n/locales/en.d.ts +2 -0
  2. package/dist/i18n/locales/en.js +1 -0
  3. package/dist/module.d.mts +7 -0
  4. package/dist/module.json +9 -0
  5. package/dist/module.mjs +50 -0
  6. package/dist/runtime/apps/calculator/app.config.d.ts +34 -0
  7. package/dist/runtime/apps/calculator/app.config.js +35 -0
  8. package/dist/runtime/apps/calculator/components/Window/WindowCalculator.d.vue.ts +6 -0
  9. package/dist/runtime/apps/calculator/components/Window/WindowCalculator.vue +85 -0
  10. package/dist/runtime/apps/calculator/components/Window/WindowCalculator.vue.d.ts +6 -0
  11. package/dist/runtime/apps/calculator/plugin.d.ts +2 -0
  12. package/dist/runtime/apps/calculator/plugin.js +11 -0
  13. package/dist/runtime/apps/explorer/app.config.d.ts +36 -0
  14. package/dist/runtime/apps/explorer/app.config.js +39 -0
  15. package/dist/runtime/apps/explorer/components/Window/WindowExplorer.d.vue.ts +6 -0
  16. package/dist/runtime/apps/explorer/components/Window/WindowExplorer.vue +30 -0
  17. package/dist/runtime/apps/explorer/components/Window/WindowExplorer.vue.d.ts +6 -0
  18. package/dist/runtime/apps/explorer/plugin.d.ts +2 -0
  19. package/dist/runtime/apps/explorer/plugin.js +11 -0
  20. package/dist/runtime/apps/installBuiltInApps.d.ts +3 -0
  21. package/dist/runtime/apps/installBuiltInApps.js +28 -0
  22. package/dist/runtime/apps/notepad/app.config.d.ts +34 -0
  23. package/dist/runtime/apps/notepad/app.config.js +35 -0
  24. package/dist/runtime/apps/notepad/components/Window/WindowNotepad.d.vue.ts +6 -0
  25. package/dist/runtime/apps/notepad/components/Window/WindowNotepad.vue +43 -0
  26. package/dist/runtime/apps/notepad/components/Window/WindowNotepad.vue.d.ts +6 -0
  27. package/dist/runtime/apps/notepad/plugin.d.ts +2 -0
  28. package/dist/runtime/apps/notepad/plugin.js +11 -0
  29. package/dist/runtime/apps/registry.d.ts +8 -0
  30. package/dist/runtime/apps/registry.js +10 -0
  31. package/dist/runtime/components/Background/DesktopBackground.d.vue.ts +3 -0
  32. package/dist/runtime/components/Background/DesktopBackground.vue +3 -0
  33. package/dist/runtime/components/Background/DesktopBackground.vue.d.ts +3 -0
  34. package/dist/runtime/components/Desktop/DesktopContent.d.vue.ts +13 -0
  35. package/dist/runtime/components/Desktop/DesktopContent.vue +23 -0
  36. package/dist/runtime/components/Desktop/DesktopContent.vue.d.ts +13 -0
  37. package/dist/runtime/components/Desktop.client.d.vue.ts +23 -0
  38. package/dist/runtime/components/Desktop.client.vue +47 -0
  39. package/dist/runtime/components/Desktop.client.vue.d.ts +23 -0
  40. package/dist/runtime/components/NuxtLauncherOverlay.d.vue.ts +3 -0
  41. package/dist/runtime/components/NuxtLauncherOverlay.vue +69 -0
  42. package/dist/runtime/components/NuxtLauncherOverlay.vue.d.ts +3 -0
  43. package/dist/runtime/components/NuxtTopBar.d.vue.ts +3 -0
  44. package/dist/runtime/components/NuxtTopBar.vue +63 -0
  45. package/dist/runtime/components/NuxtTopBar.vue.d.ts +3 -0
  46. package/dist/runtime/components/Window/DesktopWindow.d.vue.ts +43 -0
  47. package/dist/runtime/components/Window/DesktopWindow.vue +40 -0
  48. package/dist/runtime/components/Window/DesktopWindow.vue.d.ts +43 -0
  49. package/dist/runtime/components/Window/DesktopWindowContent.d.vue.ts +13 -0
  50. package/dist/runtime/components/Window/DesktopWindowContent.vue +9 -0
  51. package/dist/runtime/components/Window/DesktopWindowContent.vue.d.ts +13 -0
  52. package/dist/runtime/components/Window/DesktopWindowIframe.d.vue.ts +29 -0
  53. package/dist/runtime/components/Window/DesktopWindowIframe.vue +13 -0
  54. package/dist/runtime/components/Window/DesktopWindowIframe.vue.d.ts +29 -0
  55. package/dist/runtime/components/Window/DesktopWindowNav.d.vue.ts +3 -0
  56. package/dist/runtime/components/Window/DesktopWindowNav.vue +105 -0
  57. package/dist/runtime/components/Window/DesktopWindowNav.vue.d.ts +3 -0
  58. package/dist/runtime/composables/useNuxtStartMenu.d.ts +9 -0
  59. package/dist/runtime/composables/useNuxtStartMenu.js +57 -0
  60. package/dist/types.d.mts +7 -0
  61. package/package.json +70 -4
  62. package/src/i18n/locales/en.ts +1 -0
  63. package/src/module.ts +69 -0
  64. package/src/runtime/apps/calculator/app.config.ts +35 -0
  65. package/src/runtime/apps/calculator/components/Window/WindowCalculator.vue +95 -0
  66. package/src/runtime/apps/calculator/plugin.ts +12 -0
  67. package/src/runtime/apps/explorer/app.config.ts +39 -0
  68. package/src/runtime/apps/explorer/components/Window/WindowExplorer.vue +34 -0
  69. package/src/runtime/apps/explorer/plugin.ts +12 -0
  70. package/src/runtime/apps/installBuiltInApps.ts +36 -0
  71. package/src/runtime/apps/notepad/app.config.ts +35 -0
  72. package/src/runtime/apps/notepad/components/Window/WindowNotepad.vue +46 -0
  73. package/src/runtime/apps/notepad/plugin.ts +12 -0
  74. package/src/runtime/apps/registry.ts +21 -0
  75. package/src/runtime/components/Background/DesktopBackground.vue +3 -0
  76. package/src/runtime/components/Desktop/DesktopContent.vue +37 -0
  77. package/src/runtime/components/Desktop.client.vue +55 -0
  78. package/src/runtime/components/NuxtLauncherOverlay.vue +71 -0
  79. package/src/runtime/components/NuxtTopBar.vue +68 -0
  80. package/src/runtime/components/Window/DesktopWindow.vue +44 -0
  81. package/src/runtime/components/Window/DesktopWindowContent.vue +17 -0
  82. package/src/runtime/components/Window/DesktopWindowIframe.vue +13 -0
  83. package/src/runtime/components/Window/DesktopWindowNav.vue +110 -0
  84. package/src/runtime/composables/useNuxtStartMenu.ts +72 -0
  85. package/README.md +0 -3
@@ -0,0 +1,57 @@
1
+ import { ref, computed } from "vue";
2
+ import { useScrollLock } from "@vueuse/core";
3
+ import { useApplicationManager } from "@owdproject/nuxt/runtime/composables/useApplicationManager";
4
+ import { useApplicationEntries } from "@owdproject/nuxt/runtime/composables/useApplicationEntries";
5
+ const open = ref(false);
6
+ const searchQuery = ref("");
7
+ function isValidEntry(entry) {
8
+ return Boolean(entry?.application?.id && entry.command);
9
+ }
10
+ export function useNuxtStartMenu() {
11
+ const applicationManager = useApplicationManager();
12
+ const applicationEntries = useApplicationEntries();
13
+ const bodyScrollLock = useScrollLock(
14
+ typeof document !== "undefined" ? document.body : null
15
+ );
16
+ const allEntries = computed(() => {
17
+ return applicationEntries.sortedAppEntries("title", "primary").value.filter(isValidEntry);
18
+ });
19
+ const filteredEntries = computed(() => {
20
+ const q = searchQuery.value.trim().toLowerCase();
21
+ const entries = allEntries.value;
22
+ if (!q) return entries;
23
+ return entries.filter(
24
+ (entry) => (entry.title ?? "").toLowerCase().includes(q)
25
+ );
26
+ });
27
+ function syncScrollLock() {
28
+ bodyScrollLock.value = open.value;
29
+ }
30
+ function toggle() {
31
+ open.value = !open.value;
32
+ searchQuery.value = "";
33
+ syncScrollLock();
34
+ }
35
+ function close() {
36
+ open.value = false;
37
+ searchQuery.value = "";
38
+ bodyScrollLock.value = false;
39
+ }
40
+ async function launchEntry(entry) {
41
+ if (!isValidEntry(entry)) return;
42
+ await applicationManager.execAppCommand(
43
+ entry.application.id,
44
+ entry.command
45
+ );
46
+ close();
47
+ }
48
+ return {
49
+ open,
50
+ searchQuery,
51
+ allEntries,
52
+ filteredEntries,
53
+ toggle,
54
+ close,
55
+ launchEntry
56
+ };
57
+ }
@@ -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 CHANGED
@@ -1,6 +1,72 @@
1
1
  {
2
2
  "name": "@owdproject/nuxt-theme-ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "4.0.0-alpha.3",
4
+ "description": "Nuxt UI theme for Open Web Desktop",
5
+ "keywords": [
6
+ "owd-client",
7
+ "owd-themes",
8
+ "owd-modules"
9
+ ],
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/types.d.mts",
15
+ "development": "./src/module.ts",
16
+ "import": "./dist/module.mjs",
17
+ "default": "./dist/module.mjs"
18
+ }
19
+ },
20
+ "main": "./dist/module.mjs",
21
+ "typesVersions": {
22
+ "*": {
23
+ ".": [
24
+ "./dist/types.d.mts"
25
+ ]
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "src"
31
+ ],
32
+ "nx": {
33
+ "name": "theme-nuxt"
34
+ },
35
+ "scripts": {
36
+ "prepack": "nuxt-module-build build",
37
+ "dev": "pnpm run dev:prepare",
38
+ "dev:prepare": "nuxt-module-build build --stub"
39
+ },
40
+ "dependencies": {
41
+ "@nuxt/kit": "^4.4.4",
42
+ "@owdproject/nuxt-kit-nuxt-ui": "^4.0.0-alpha.3",
43
+ "defu": "^6.1.4",
44
+ "@owdproject/nuxt": "^4.0.0-alpha.3"
45
+ },
46
+ "devDependencies": {
47
+ "@nuxt/devtools": "^3.2.4",
48
+ "@nuxt/module-builder": "^1.0.2",
49
+ "@nuxt/schema": "^4.4.4",
50
+ "@owdproject/core": "^4.0.0-alpha.3",
51
+ "@owdproject/nuxt-module-fs": "^4.0.0-alpha.3",
52
+ "nuxt": "^4.4.4",
53
+ "typescript": "catalog:"
54
+ },
55
+ "peerDependencies": {
56
+ "@owdproject/core": "^4.0.0-alpha.3",
57
+ "@owdproject/nuxt-kit-nuxt-ui": "^4.0.0-alpha.3",
58
+ "@owdproject/nuxt-module-fs": "^4.0.0-alpha.3",
59
+ "nuxt": "^4.4.4",
60
+ "@owdproject/nuxt": "^4.0.0-alpha.3"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "@owdproject/nuxt-module-fs": {
64
+ "optional": true
65
+ }
66
+ },
67
+ "publishConfig": {
68
+ "access": "public",
69
+ "tag": "alpha",
70
+ "registry": "https://registry.npmjs.org/"
71
+ }
72
+ }
@@ -0,0 +1 @@
1
+ export default {}
package/src/module.ts ADDED
@@ -0,0 +1,69 @@
1
+ import { existsSync } from 'node:fs'
2
+ import {
3
+ createResolver,
4
+ addComponentsDir,
5
+ installModule,
6
+ addImportsDir,
7
+ addPlugin,
8
+ } from '@nuxt/kit'
9
+ import { defineDesktopTheme } from '@owdproject/nuxt'
10
+ import {
11
+ registerTailwindPath,
12
+ registerThemeTailwindPath,
13
+ } from '@owdproject/nuxt-kit-nuxt-ui/kit/registerTailwindPath'
14
+ import { installNuxtBuiltInApps } from './runtime/apps/installBuiltInApps'
15
+
16
+ export default defineDesktopTheme({
17
+ meta: {
18
+ name: 'desktop-theme-nuxt',
19
+ },
20
+ defaults: {
21
+ name: 'nuxt',
22
+ systemBar: {
23
+ enabled: true,
24
+ position: 'top',
25
+ startButton: true,
26
+ },
27
+ windows: {
28
+ position: 'fixed',
29
+ },
30
+ },
31
+ async setup(_options, nuxt) {
32
+ const { resolve } = createResolver(import.meta.url)
33
+
34
+ // Install the Nuxt UI kit module
35
+ await installModule('@owdproject/nuxt-kit-nuxt-ui')
36
+
37
+ // Register Tailwind content scan paths for theme-nuxt components and pages
38
+ registerThemeTailwindPath(nuxt, import.meta.url)
39
+ registerTailwindPath(nuxt, resolve('./runtime/pages/**/*.{vue,mjs,ts}'))
40
+
41
+ // Add theme components
42
+ addComponentsDir({
43
+ path: resolve('./runtime/components'),
44
+ pathPrefix: false,
45
+ })
46
+
47
+ // Register i18n module localization if present
48
+ nuxt.hook('i18n:registerModule', (register) => {
49
+ register({
50
+ langDir: resolve('./i18n'),
51
+ locales: [
52
+ {
53
+ code: 'en',
54
+ file: existsSync(resolve('./i18n/locales/en.js')) ? 'locales/en.js' : 'locales/en.ts',
55
+ },
56
+ ],
57
+ })
58
+ })
59
+
60
+ // Register theme dirs
61
+ addImportsDir(resolve('./runtime/composables'))
62
+ addImportsDir(resolve('./runtime/consts'))
63
+ addImportsDir(resolve('./runtime/stores'))
64
+ addImportsDir(resolve('./runtime/utils'))
65
+
66
+ // Install built-in apps (Explorer, Calculator, Notepad)
67
+ installNuxtBuiltInApps(nuxt, import.meta.url)
68
+ },
69
+ })
@@ -0,0 +1,35 @@
1
+ export default {
2
+ id: 'org.owdproject.calculator',
3
+ title: 'Calculator',
4
+ singleton: false,
5
+ icon: 'i-heroicons-calculator',
6
+ provides: {
7
+ name: 'calculator',
8
+ entry: 'calculator',
9
+ },
10
+ windows: {
11
+ main: {
12
+ component: () => import('./components/Window/WindowCalculator.vue'),
13
+ resizable: false,
14
+ size: {
15
+ width: 260,
16
+ height: 380,
17
+ },
18
+ position: {
19
+ x: 200,
20
+ y: 150,
21
+ z: 0,
22
+ },
23
+ },
24
+ },
25
+ entries: {
26
+ calculator: {
27
+ command: 'calculator',
28
+ },
29
+ },
30
+ commands: {
31
+ calculator: (app: any) => {
32
+ app.openWindow('main')
33
+ },
34
+ },
35
+ }
@@ -0,0 +1,95 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+
4
+ defineProps<{
5
+ window: any
6
+ }>()
7
+
8
+ const display = ref('0')
9
+ const equation = ref('')
10
+ const isFinished = ref(false)
11
+
12
+ const buttons = [
13
+ ['C', '(', ')', '/'],
14
+ ['7', '8', '9', '*'],
15
+ ['4', '5', '6', '-'],
16
+ ['1', '2', '3', '+'],
17
+ ['0', '.', '=', '']
18
+ ]
19
+
20
+ function handleClick(val: string) {
21
+ if (val === '=') {
22
+ calculate()
23
+ } else if (val === 'C') {
24
+ clear()
25
+ } else if (val === '') {
26
+ // Spacer button
27
+ } else {
28
+ append(val)
29
+ }
30
+ }
31
+
32
+ function append(val: string) {
33
+ if (isFinished.value) {
34
+ display.value = ''
35
+ isFinished.value = false
36
+ }
37
+ if (display.value === '0' && val !== '.') {
38
+ display.value = val
39
+ } else {
40
+ display.value += val
41
+ }
42
+ }
43
+
44
+ function clear() {
45
+ display.value = '0'
46
+ equation.value = ''
47
+ isFinished.value = false
48
+ }
49
+
50
+ function calculate() {
51
+ try {
52
+ const expr = display.value
53
+ // Safe evaluation for basic arithmetic only
54
+ if (/^[0-9+\-*/().\s]+$/.test(expr)) {
55
+ // eslint-disable-next-line no-eval
56
+ const res = eval(expr)
57
+ equation.value = expr + ' ='
58
+ display.value = String(res)
59
+ isFinished.value = true
60
+ } else {
61
+ display.value = 'Error'
62
+ }
63
+ } catch (e) {
64
+ display.value = 'Error'
65
+ }
66
+ }
67
+ </script>
68
+
69
+ <template>
70
+ <DesktopWindow :window="window" class="h-full bg-gray-50 dark:bg-gray-950 flex flex-col p-3">
71
+ <!-- Calculator screen -->
72
+ <div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-lg p-3 mb-3 text-right shadow-inner flex-shrink-0">
73
+ <div class="text-xs text-gray-400 dark:text-gray-500 h-4 mb-0.5 truncate">{{ equation }}</div>
74
+ <div class="text-2xl font-bold font-mono text-gray-800 dark:text-gray-100 truncate">{{ display }}</div>
75
+ </div>
76
+
77
+ <!-- Buttons Grid -->
78
+ <div class="grid grid-cols-4 gap-2 flex-1">
79
+ <template v-for="(row, rIdx) in buttons" :key="rIdx">
80
+ <template v-for="(btn, bIdx) in row" :key="bIdx">
81
+ <UButton
82
+ v-if="btn !== ''"
83
+ :label="btn"
84
+ size="md"
85
+ class="flex items-center justify-center font-bold text-sm h-11 w-full"
86
+ :color="btn === '=' ? 'primary' : btn === 'C' ? 'red' : ['/', '*', '-', '+'].includes(btn) ? 'orange' : 'gray'"
87
+ variant="solid"
88
+ @click="handleClick(btn)"
89
+ />
90
+ <div v-else class="h-11 w-full" />
91
+ </template>
92
+ </template>
93
+ </div>
94
+ </DesktopWindow>
95
+ </template>
@@ -0,0 +1,12 @@
1
+ import { defineNuxtPlugin } from 'nuxt/app'
2
+ import { defineDesktopApp } from '@owdproject/nuxt/kit/defineDesktopApp'
3
+ import configAppCalculator from './app.config'
4
+
5
+ export default defineNuxtPlugin({
6
+ name: 'desktop-theme-nuxt-calculator',
7
+ dependsOn: ['pinia', 'desktop-shell-init'],
8
+ async setup() {
9
+ if (import.meta.server) return
10
+ await defineDesktopApp(configAppCalculator)
11
+ },
12
+ })
@@ -0,0 +1,39 @@
1
+ export default {
2
+ id: 'org.owdproject.explorer',
3
+ title: 'Explorer',
4
+ singleton: false,
5
+ icon: 'i-heroicons-folder-open',
6
+ provides: {
7
+ name: 'explorer',
8
+ entry: 'explorer',
9
+ },
10
+ windows: {
11
+ main: {
12
+ component: () => import('./components/Window/WindowExplorer.vue'),
13
+ resizable: true,
14
+ size: {
15
+ width: 720,
16
+ height: 480,
17
+ minWidth: 560,
18
+ minHeight: 440,
19
+ },
20
+ position: {
21
+ x: 120,
22
+ y: 80,
23
+ z: 0,
24
+ },
25
+ },
26
+ },
27
+ entries: {
28
+ explorer: {
29
+ command: 'explorer /',
30
+ },
31
+ },
32
+ commands: {
33
+ explorer: (app: any, args: any) => {
34
+ const a = args as { _?: string[] } | undefined
35
+ const pathArg = a?._?.[1]
36
+ app.openWindow('main', undefined, { path: pathArg ?? '/' })
37
+ },
38
+ },
39
+ }
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import { useI18n } from 'vue-i18n'
3
+ import { inject } from 'vue'
4
+ import { DESKTOP_DIALOG_PROVIDER_KEY } from '@owdproject/nuxt/runtime/constants/desktopShellKeys'
5
+ import { createExplorerWindowMenuItems } from '@owdproject/nuxt-module-fs/runtime/composables/useExplorerWindowMenu'
6
+
7
+ const props = defineProps<{
8
+ window: any
9
+ }>()
10
+
11
+ const { t } = useI18n()
12
+ const dialogs = inject<any>(DESKTOP_DIALOG_PROVIDER_KEY)
13
+
14
+ const explorerMenu = createExplorerWindowMenuItems(
15
+ () => props.window,
16
+ t,
17
+ () => {
18
+ dialogs?.alert('Nuxt UI theme explorer powered by module-fs!', { title: 'About Explorer' })
19
+ }
20
+ )
21
+
22
+ props.window.setMenu(explorerMenu)
23
+ </script>
24
+
25
+ <template>
26
+ <DesktopExplorerWorkspace
27
+ :window="window"
28
+ frame-class="nuxt-explorer-frame"
29
+ >
30
+ <template #nav>
31
+ <DesktopWindowNav />
32
+ </template>
33
+ </DesktopExplorerWorkspace>
34
+ </template>
@@ -0,0 +1,12 @@
1
+ import { defineNuxtPlugin } from 'nuxt/app'
2
+ import { defineDesktopApp } from '@owdproject/nuxt/kit/defineDesktopApp'
3
+ import configAppExplorer from './app.config'
4
+
5
+ export default defineNuxtPlugin({
6
+ name: 'desktop-theme-nuxt-explorer',
7
+ dependsOn: ['pinia', 'desktop-shell-init'],
8
+ async setup() {
9
+ if (import.meta.server) return
10
+ await defineDesktopApp(configAppExplorer)
11
+ },
12
+ })
@@ -0,0 +1,36 @@
1
+ import {
2
+ addComponentsDir,
3
+ addPlugin,
4
+ createResolver,
5
+ } from '@nuxt/kit'
6
+ import type { Nuxt } from '@nuxt/schema'
7
+ import { registerTailwindPath } from '@owdproject/nuxt-kit-nuxt-ui/kit/registerTailwindPath'
8
+ import { NUXT_THEME_BUILTIN_APPS } from './registry'
9
+
10
+ /** Register autoload built-in apps from `runtime/apps/<name>/`. */
11
+ export function installNuxtBuiltInApps(nuxt: Nuxt, themeRoot: string) {
12
+ const { resolve } = createResolver(themeRoot)
13
+
14
+ for (const app of NUXT_THEME_BUILTIN_APPS) {
15
+ if (!app.autoload) continue
16
+ if (app.when && !app.when(nuxt)) continue
17
+
18
+ const appRoot = resolve(`./runtime/apps/${app.name}`)
19
+
20
+ addPlugin({
21
+ src: resolve(appRoot, 'plugin'),
22
+ mode: 'client',
23
+ name: `desktop-theme-nuxt-${app.name}`,
24
+ order: 1,
25
+ })
26
+
27
+ addComponentsDir({
28
+ path: resolve(appRoot, 'components'),
29
+ })
30
+
31
+ registerTailwindPath(
32
+ nuxt,
33
+ resolve(appRoot, 'components/**/*.{vue,mjs,ts}'),
34
+ )
35
+ }
36
+ }
@@ -0,0 +1,35 @@
1
+ export default {
2
+ id: 'org.owdproject.notepad',
3
+ title: 'Notepad',
4
+ singleton: false,
5
+ icon: 'i-heroicons-document-text',
6
+ provides: {
7
+ name: 'notepad',
8
+ entry: 'notepad',
9
+ },
10
+ windows: {
11
+ main: {
12
+ component: () => import('./components/Window/WindowNotepad.vue'),
13
+ resizable: true,
14
+ size: {
15
+ width: 600,
16
+ height: 400,
17
+ },
18
+ position: {
19
+ x: 180,
20
+ y: 120,
21
+ z: 0,
22
+ },
23
+ },
24
+ },
25
+ entries: {
26
+ notepad: {
27
+ command: 'notepad',
28
+ },
29
+ },
30
+ commands: {
31
+ notepad: (app: any) => {
32
+ app.openWindow('main')
33
+ },
34
+ },
35
+ }
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+
4
+ defineProps<{
5
+ window: any
6
+ }>()
7
+
8
+ const text = ref('')
9
+
10
+ function clear() {
11
+ text.value = ''
12
+ }
13
+ </script>
14
+
15
+ <template>
16
+ <DesktopWindow :window="window" class="h-full bg-white dark:bg-gray-950 flex flex-col">
17
+ <!-- Toolbar -->
18
+ <div class="flex items-center space-x-2 p-2 bg-gray-50 dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800 flex-shrink-0">
19
+ <UButton
20
+ icon="i-heroicons-document"
21
+ label="New"
22
+ color="gray"
23
+ variant="ghost"
24
+ size="xs"
25
+ @click="clear"
26
+ />
27
+ <UButton
28
+ icon="i-heroicons-trash"
29
+ label="Clear"
30
+ color="red"
31
+ variant="ghost"
32
+ size="xs"
33
+ @click="clear"
34
+ />
35
+ </div>
36
+
37
+ <!-- Text area -->
38
+ <div class="flex-1 min-h-0">
39
+ <textarea
40
+ v-model="text"
41
+ class="w-full h-full p-4 resize-none outline-none border-0 text-sm font-mono bg-transparent text-gray-800 dark:text-gray-200"
42
+ placeholder="Type here..."
43
+ />
44
+ </div>
45
+ </DesktopWindow>
46
+ </template>
@@ -0,0 +1,12 @@
1
+ import { defineNuxtPlugin } from 'nuxt/app'
2
+ import { defineDesktopApp } from '@owdproject/nuxt/kit/defineDesktopApp'
3
+ import configAppNotepad from './app.config'
4
+
5
+ export default defineNuxtPlugin({
6
+ name: 'desktop-theme-nuxt-notepad',
7
+ dependsOn: ['pinia', 'desktop-shell-init'],
8
+ async setup() {
9
+ if (import.meta.server) return
10
+ await defineDesktopApp(configAppNotepad)
11
+ },
12
+ })
@@ -0,0 +1,21 @@
1
+ import type { Nuxt } from '@nuxt/schema'
2
+
3
+ export type NuxtThemeBuiltInApp = {
4
+ name: string
5
+ autoload: boolean
6
+ when?: (nuxt: Nuxt) => boolean
7
+ }
8
+
9
+ export function hasModuleFs(nuxt: Nuxt): boolean {
10
+ const desktop = nuxt.options.runtimeConfig.public.desktop as {
11
+ modules?: string[]
12
+ }
13
+ const modules = desktop?.modules ?? []
14
+ return modules.some((m) => String(m).includes('nuxt-fs'))
15
+ }
16
+
17
+ export const NUXT_THEME_BUILTIN_APPS: NuxtThemeBuiltInApp[] = [
18
+ { name: 'explorer', autoload: true },
19
+ { name: 'calculator', autoload: true },
20
+ { name: 'notepad', autoload: true },
21
+ ]
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <DesktopCoreBackground />
3
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { useAppConfig } from "nuxt/app";
3
+ import { computed } from "vue";
4
+
5
+ const appConfig = useAppConfig() as any;
6
+ const classes = computed(() => {
7
+ const list = ["owd-desktop__content"];
8
+ const pos = appConfig.desktop?.systemBar?.position;
9
+ if (pos) {
10
+ list.push(`owd-desktop__content--system-bar-position-${pos}`);
11
+ }
12
+ return list;
13
+ });
14
+ </script>
15
+
16
+ <template>
17
+ <div :class="classes">
18
+ <slot />
19
+ </div>
20
+ </template>
21
+
22
+ <style scoped>
23
+ .owd-desktop__content {
24
+ position: relative;
25
+ width: 100%;
26
+ height: 100%;
27
+ overflow: hidden;
28
+ }
29
+ .owd-desktop__content--system-bar-position-top {
30
+ flex: 1 1 auto;
31
+ min-height: 0;
32
+ }
33
+ .owd-desktop__content--system-bar-position-bottom {
34
+ flex: 1 1 auto;
35
+ min-height: 0;
36
+ }
37
+ </style>