diff --git a/assets/css/tailwind.config.js b/assets/css/tailwind.config.js index 575381c..07d3a7b 100644 --- a/assets/css/tailwind.config.js +++ b/assets/css/tailwind.config.js @@ -1,14 +1,36 @@ const {join} = require("node:path"); /** @type {import('tailwindcss').Config} */ const root = join(__dirname, "../../"); -const content = join(root, "**/*.go"); +const contentGo = join(root, "**/*.go"); +const contentJs = join(root, "**/pages/**/*.js"); -console.log(content) module.exports = { - content: [content], + content: [contentGo, contentJs], theme: { - extend: {}, + extend: { + colors: { + background: 'hsl(224, 71.4%, 4.1%)', + foreground: 'hsl(0, 0%, 89%)', + card: 'hsl(224, 71.4%, 4.1%)', + cardForeground: 'hsl(0, 0%, 89%)', + popover: 'hsl(224, 71.4%, 4.1%)', + popoverForeground: 'hsl(0, 0%, 89%)', + primary: 'hsl(0, 0%, 89%)', + primaryForeground: 'hsl(220.9, 39.3%, 11%)', + secondary: 'hsl(215, 27.9%, 16.9%)', + secondaryForeground: 'hsl(0, 0%, 89%)', + muted: 'hsl(215, 27.9%, 16.9%)', + mutedForeground: 'hsl(217.9, 10.6%, 64.9%)', + accent: 'hsl(215, 27.9%, 16.9%)', + accentForeground: 'hsl(0, 0%, 89%)', + destructive: 'hsl(0, 62.8%, 30.6%)', + destructiveForeground: 'hsl(0, 0%, 89%)', + border: 'hsl(215, 27.9%, 16.9%)', + input: 'hsl(215, 27.9%, 16.9%)', + ring: 'hsl(216, 12.2%, 83.9%)', + }, + }, }, plugins: [], }; diff --git a/assets/js/htmx.ts b/assets/js/htmx.ts new file mode 100644 index 0000000..e69de29 diff --git a/assets/js/extensions/debug.ts b/assets/js/htmxextensions/debug.ts similarity index 100% rename from assets/js/extensions/debug.ts rename to assets/js/htmxextensions/debug.ts diff --git a/assets/js/extensions/mutation-error.ts b/assets/js/htmxextensions/mutation-error.ts similarity index 100% rename from assets/js/extensions/mutation-error.ts rename to assets/js/htmxextensions/mutation-error.ts diff --git a/assets/js/extensions/pathdeps.ts b/assets/js/htmxextensions/pathdeps.ts similarity index 100% rename from assets/js/extensions/pathdeps.ts rename to assets/js/htmxextensions/pathdeps.ts diff --git a/assets/js/extensions/response-targets.ts b/assets/js/htmxextensions/response-targets.ts similarity index 100% rename from assets/js/extensions/response-targets.ts rename to assets/js/htmxextensions/response-targets.ts diff --git a/assets/js/extensions/trigger-children.ts b/assets/js/htmxextensions/trigger-children.ts similarity index 100% rename from assets/js/extensions/trigger-children.ts rename to assets/js/htmxextensions/trigger-children.ts diff --git a/assets/js/mhtml.ts b/assets/js/mhtml.ts index 51bea3a..2debef2 100644 --- a/assets/js/mhtml.ts +++ b/assets/js/mhtml.ts @@ -1,9 +1,9 @@ import htmx from "htmx.org"; -import "./extensions/pathdeps"; -import "./extensions/trigger-children"; -import "./extensions/debug"; -import "./extensions/response-targets"; -import "./extensions/mutation-error"; +import "./htmxextensions/pathdeps"; +import "./htmxextensions/trigger-children"; +import "./htmxextensions/debug"; +import "./htmxextensions/response-targets"; +import "./htmxextensions/mutation-error"; function watchUrl(callback: (oldUrl: string, newUrl: string) => void) { let lastUrl = window.location.href; diff --git a/assets/js/package-lock.json b/assets/js/package-lock.json index ffeb3b8..80d97ab 100644 --- a/assets/js/package-lock.json +++ b/assets/js/package-lock.json @@ -15,6 +15,7 @@ "@swc/core": "^1.7.26", "@types/node": "^22.5.4", "prettier": "^3.3.3", + "shiki": "^1.17.6", "tailwindcss": "^3.4.11", "tsup": "^8.2.4", "typescript": "^5.6.2" @@ -734,6 +735,56 @@ "win32" ] }, + "node_modules/@shikijs/core": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.17.6.tgz", + "integrity": "sha512-9ztslig6/YmCg/XwESAXbKjAjOhaq6HVced9NY6qcbDz1X5g/S90Wco2vMjBNX/6V71ASkzri76JewSGPa7kiQ==", + "dev": true, + "dependencies": { + "@shikijs/engine-javascript": "1.17.6", + "@shikijs/engine-oniguruma": "1.17.6", + "@shikijs/types": "1.17.6", + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.2" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.17.6.tgz", + "integrity": "sha512-5EEZj8tVcierNxm4V0UMS2PVoflb0UJPalWWV8l9rRg+oOfnr5VivqBJbkyq5grltVPvByIXvVbY8GSM/356jQ==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.17.6", + "oniguruma-to-js": "0.4.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.17.6.tgz", + "integrity": "sha512-NLfWDMXFYe0nDHFbEoyZdz89aIIey3bTfF3zLYSUNTXks5s4uinZVmuPOFf1HfTeGqIn8uErJSBc3VnpJO7Alw==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.17.6", + "@shikijs/vscode-textmate": "^9.2.2" + } + }, + "node_modules/@shikijs/types": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.17.6.tgz", + "integrity": "sha512-ndTFa2TJi2w51ddKQDn3Jy8f6K4E5Q2x3dA3Hmsd3+YmxDQ10UWHjcw7VbVbKzv3VcUvYPLy+z9neqytSzUMUg==", + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.2.2.tgz", + "integrity": "sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==", + "dev": true + }, "node_modules/@swc/core": { "version": "1.7.26", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.26.tgz", @@ -953,6 +1004,24 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/node": { "version": "22.5.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", @@ -962,6 +1031,18 @@ "undici-types": "~6.19.2" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -1092,6 +1173,36 @@ "node": ">= 6" } }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -1134,6 +1245,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -1195,6 +1316,28 @@ } } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -1457,6 +1600,52 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.2.tgz", + "integrity": "sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/htmx.org": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.2.tgz", @@ -1636,6 +1825,27 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1651,6 +1861,95 @@ "node": ">= 8" } }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -1786,6 +2085,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oniguruma-to-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", + "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "dev": true, + "dependencies": { + "regex": "^4.3.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", @@ -2033,6 +2344,16 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -2083,6 +2404,12 @@ "node": ">=8.10.0" } }, + "node_modules/regex": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz", + "integrity": "sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -2198,6 +2525,20 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.17.6.tgz", + "integrity": "sha512-RejGugKpDM75vh6YtF9R771acxHRDikC/01kxsUGW+Pnaz3pTY+c8aZB5CnD7p0vuFPs1HaoAIU/4E+NCfS+mQ==", + "dev": true, + "dependencies": { + "@shikijs/core": "1.17.6", + "@shikijs/engine-javascript": "1.17.6", + "@shikijs/engine-oniguruma": "1.17.6", + "@shikijs/types": "1.17.6", + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -2234,6 +2575,16 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -2293,6 +2644,20 @@ "node": ">=8" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -2529,6 +2894,16 @@ "tree-kill": "cli.js" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -2605,12 +2980,108 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -2745,6 +3216,16 @@ "engines": { "node": ">= 14" } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/assets/js/package.json b/assets/js/package.json index a417950..0f245b6 100644 --- a/assets/js/package.json +++ b/assets/js/package.json @@ -3,8 +3,8 @@ "version": "1.0.0", "main": "mhtml.js", "scripts": { - "watch": "tsup ./mhtml.ts --watch --config ./tsup.config.ts --sourcemap inline", - "build": "tsup ./mhtml.ts --minify --config ./tsup.config.ts", + "watch": "tsup --watch --config ./tsup.config.ts --sourcemap inline", + "build": "tsup --minify --config ./tsup.config.ts", "tailwind:watch": "npx tailwindcss -i ./input.css -o ./output.css --watch", "pretty": "prettier --write ." }, @@ -18,6 +18,7 @@ "@swc/core": "^1.7.26", "@types/node": "^22.5.4", "prettier": "^3.3.3", + "shiki": "^1.17.6", "tailwindcss": "^3.4.11", "tsup": "^8.2.4", "typescript": "^5.6.2" diff --git a/assets/js/scripts/shiki.ts b/assets/js/scripts/shiki.ts new file mode 100644 index 0000000..972ae72 --- /dev/null +++ b/assets/js/scripts/shiki.ts @@ -0,0 +1,5 @@ +import htmx from "htmx.org"; + +htmx.findAll("body"); + +alert("here"); diff --git a/assets/js/tsup.config.ts b/assets/js/tsup.config.ts index 610f00e..b2f3ec2 100644 --- a/assets/js/tsup.config.ts +++ b/assets/js/tsup.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from "tsup"; export default defineConfig({ format: ["esm"], - entry: ["./src/mhtml.ts"], + entry: ["mhtml.ts", "./scripts/*.ts"], outDir: "./../dist", dts: false, shims: true, @@ -20,5 +20,4 @@ export default defineConfig({ bundle: true, // https://github.com/egoist/tsup/issues/619 noExternal: [/(.*)/], - splitting: false, }); diff --git a/h/livereload.go b/h/livereload.go index 0dc910d..f30375b 100644 --- a/h/livereload.go +++ b/h/livereload.go @@ -25,7 +25,7 @@ func LiveReloadHandler(c *fiber.Ctx) error { } func LiveReload() Renderable { - return Div(Get("/livereload"), Trigger("every 2s")) + return Div(Get("/livereload"), Trigger("every 200ms")) } func AddLiveReloadHandler(path string, app *fiber.App) { diff --git a/h/tag.go b/h/tag.go index 3b36a58..9c0696b 100644 --- a/h/tag.go +++ b/h/tag.go @@ -160,7 +160,7 @@ func Text(text string) Renderable { } func Pf(format string, args ...interface{}) Renderable { - return P(fmt.Sprintf(format, args...)) + return P(Text(fmt.Sprintf(format, args...))) } func Target(target string) Renderable { @@ -230,7 +230,8 @@ func Script(url string) Renderable { return &Node{ tag: "script", attributes: map[string]string{ - "src": url, + "src": url, + "type": "module", }, children: make([]Renderable, 0), } @@ -244,10 +245,26 @@ func Raw(text string) Renderable { } } +func MultiLineQuotes(text string) string { + return "`" + text + "`" +} + +func RawF(text string, args any) Renderable { + return &Node{ + tag: "raw", + children: make([]Renderable, 0), + value: fmt.Sprintf(text, args), + } +} + func RawScript(text string) Renderable { return Raw("") } +func Pre(children ...Renderable) Renderable { + return Tag("pre", children...) +} + func Div(children ...Renderable) Renderable { return Tag("div", children...) } @@ -347,24 +364,48 @@ func Indicator(tag string) Renderable { return Attribute("hx-indicator", tag) } -func P(text string, children ...Renderable) Renderable { - return &Node{ - tag: "p", - children: children, - text: text, - } +func P(children ...Renderable) Renderable { + return Tag("p", children...) +} + +func H1(children ...Renderable) Renderable { + return Tag("h1", children...) +} + +func H2(children ...Renderable) Renderable { + return Tag("h2", children...) +} + +func H3(children ...Renderable) Renderable { + return Tag("h3", children...) +} + +func H4(children ...Renderable) Renderable { + return Tag("h4", children...) +} + +func H5(children ...Renderable) Renderable { + return Tag("h5", children...) +} + +func H6(children ...Renderable) Renderable { + return Tag("h6", children...) +} + +func Img(children ...Renderable) Renderable { + return Tag("img", children...) +} + +func Src(src string) Renderable { + return Attribute("src", src) } func Form(children ...Renderable) Renderable { return Tag("form", children...) } -func A(text string, children ...Renderable) Renderable { - return &Node{ - tag: "a", - children: children, - text: text, - } +func A(children ...Renderable) Renderable { + return Tag("a", children...) } func Nav(children ...Renderable) Renderable { diff --git a/justfile b/justfile index f6ebf96..7bfeddf 100644 --- a/justfile +++ b/justfile @@ -1,5 +1,5 @@ -run-app: - just run-gen && air & just watch-js & just watch-gen +dev: + just run-gen && just build-css && air & just watch-js & just watch-gen & just watch-css bundle: rm -rf dist diff --git a/news/views.go b/news/views.go index 34713fe..1cfbf70 100644 --- a/news/views.go +++ b/news/views.go @@ -17,7 +17,7 @@ func StoryList() h.Renderable { time.Sleep(200 * time.Millisecond) if len(*posts) == 0 { - return h.P("No results found") + return h.Pf("No results found") } return h.Fragment( @@ -31,14 +31,14 @@ func StoryCard(post Post) h.Renderable { url := fmt.Sprintf("/news/%d", post.Id) return h.Div( h.Class("items-center bg-indigo-200 p-4 rounded"), - h.A(post.Title, h.Href(url)), + h.A(h.Text(post.Title), h.Href(url)), ) } func StoryFull(id string) h.Renderable { post, err := Get(id) if err != nil { - return h.P(err.Error()) + return h.Pf(err.Error()) } return StoryCard(post) } diff --git a/pages/index.go b/pages/index.go index fb2014e..cbb2ebb 100644 --- a/pages/index.go +++ b/pages/index.go @@ -1,17 +1,89 @@ package pages import ( + "fmt" "github.com/gofiber/fiber/v2" "mhtml/h" + "os" + "time" ) func IndexPage(c *fiber.Ctx) *h.Page { return h.NewPage(h.Html( - h.HxExtension("path-deps, response-targets, mutation-error"), + h.Class("bg-background flex flex-col items-center"), h.Head( - h.Script("https://cdn.tailwindcss.com"), - h.Script("/js/dist/mhtml.js"), + h.Link("/public/main.css", "stylesheet"), + h.Script("/public/mhtml.js"), + h.Script("/public/scripts/shiki.js"), + ), + h.Body( + h.Class("flex flex-col gap-3"), + // Navbar + h.Div( + h.Class("flex justify-between items-center w-full p-6"), + h.Div( + h.Class("text-white text-xl font-bold"), + h.Text("MHTML"), + ), + h.Div( + h.Class("flex gap-4"), + h.A(h.Href("/pricing"), h.Class("text-white"), h.Text("Pricing")), + h.A(h.Href("/docs"), h.Class("text-white"), h.Text("Docs")), + h.A(h.Href("/app"), h.Class("text-white"), h.Text("App")), + ), + ), + + // Hero Section + h.Div( + h.Class("flex flex-col items-center justify-center gap-6 p-12 bg-background text-center"), + h.H1( + h.Class("text-white text-4xl sm:text-5xl font-bold max-w-3xl"), + h.Text("Go and HTMX: The Simple Stack"), + ), + h.P( + h.Class("text-white text-lg sm:text-xl max-w-2xl"), + h.Text("Combine the simplicity of Go with the power of HTMX for dynamic, JavaScript-light web development."), + ), + h.A(h.Href("/get-started"), + h.Class("bg-white text-background px-6 py-3 rounded-md font-semibold mt-4"), + h.Text("Join the waitlist"), + ), + ), + + // Explore Section + h.Div( + h.Class("w-full max-w-4xl"), + CodeExample(), + ), + + // Footer Section + h.Div( + h.Class("flex justify-center items-center py-6"), + h.Text(fmt.Sprintf("© %d MHTML", time.Now().Year())), + ), ), - h.Body(), )) } + +func CodeExample() h.Renderable { + code, err := os.ReadFile("pages/assets/_example.go") + scriptSrc, err := os.ReadFile("pages/assets/shiki.js") + + if err != nil { + return h.Pf("Error loading code example") + } + + fmt.Printf("%s\n", code) + + script := fmt.Sprintf(string(scriptSrc), string(code)) + + return h.Div( + h.Class("text-white rounded-lg"), + h.Pre(h.Id("foo")), + h.RawF(` + + `, script), + ) +} diff --git a/pages/patients.index.go b/pages/patients.index.go index 94ea9d1..fb3bb2a 100644 --- a/pages/patients.index.go +++ b/pages/patients.index.go @@ -14,7 +14,7 @@ func PatientsIndex(ctx *fiber.Ctx) *h.Page { h.Div( h.Div( h.Class("flex justify-between items-center"), - h.P("Manage Patients", h.Class("text-lg font-bold")), + h.P(h.Text("Manage Patients"), h.Class("text-lg font-bold")), patient.AddPatientButton(), ), h.View(patient.List, h.ReloadParams{ diff --git a/partials/nav.go b/partials/nav.go index 15f3b4e..2c0fd79 100644 --- a/partials/nav.go +++ b/partials/nav.go @@ -19,7 +19,7 @@ func NavBar() h.Renderable { h.Boost(), h.Children( h.Map(links, func(link Link) h.Renderable { - return h.A(link.Name, h.Href(link.Path), h.Class("cursor-pointer hover:text-blue-400")) + return h.A(h.Text(link.Name), h.Href(link.Path), h.Class("cursor-pointer hover:text-blue-400")) })..., )) } diff --git a/partials/news.go b/partials/news.go index 27238e8..2dc5a3b 100644 --- a/partials/news.go +++ b/partials/news.go @@ -56,10 +56,10 @@ func SheetOpen() h.Renderable { h.Class(`fixed top-0 right-0 h-full w-96 bg-gray-100 shadow-lg z-50`), h.Div( h.Class("p-4 overflow-y-auto h-full w-full flex flex-col gap-4"), - h.P("My NewsSheet", + h.P(h.Text("News Sheet"), h.Class("text-lg font-bold"), ), - h.P("This is a sheet", + h.P(h.Text("Here are the latest news stories."), h.Class("text-sm mt-2"), ), ui.Button(ui.ButtonProps{ diff --git a/partials/patient/patient.go b/partials/patient/patient.go index 5570f82..547fef9 100644 --- a/partials/patient/patient.go +++ b/partials/patient/patient.go @@ -15,14 +15,14 @@ func List(ctx *fiber.Ctx) *h.Partial { if err != nil { return h.NewPartial(h.Div( h.Class("patient-list"), - h.P("Error loading patients"), + h.Pf("Error loading patients"), )) } if len(patients) == 0 { return h.NewPartial(h.Div( h.Class("patient-list"), - h.P("No patients found"), + h.Pf("No patients found"), )) } @@ -50,7 +50,7 @@ func AddPatientSheet(onClosePath string) h.Renderable { ClassName: "w-[400px] bg-gray-100 p-4", Root: h.Div( h.Class("flex flex-col gap-4"), - h.P("Add Patient", h.Class("text-lg font-bold")), + h.P(h.Text("Add Patient"), h.Class("text-lg font-bold")), addPatientForm(), ), }) @@ -62,19 +62,19 @@ func ValidateForm(ctx *fiber.Ctx) *h.Partial { if trigger == "name" { if strings.ToLower(value) == "sydne" { - return h.NewPartial(h.P("that name is reserved")) + return h.NewPartial(h.Pf("that name is reserved")) } } if trigger == "reason-for-visit" { if strings.ToLower(value) == "arm hurts" { - return h.NewPartial(h.P("lol that reason is fake")) + return h.NewPartial(h.Pf("lol that reason is fake")) } } if trigger == "location-name" { if strings.ToLower(value) == "hospital" { - return h.NewPartial(h.P("that location is reserved")) + return h.NewPartial(h.Pf("that location is reserved")) } }