From 31f2dfac5c42c26b8dfd6048cb9e039cf113b95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Hribernik?= Date: Mon, 5 Jan 2026 18:42:28 +0100 Subject: [PATCH 1/9] text field and theme.css --- web/src/components/TextField.vue | 151 +++++++++++++++++++++++++++++++ web/src/theme.css | 45 +++++++++ 2 files changed, 196 insertions(+) create mode 100644 web/src/components/TextField.vue create mode 100644 web/src/theme.css diff --git a/web/src/components/TextField.vue b/web/src/components/TextField.vue new file mode 100644 index 0000000..cd8965d --- /dev/null +++ b/web/src/components/TextField.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/web/src/theme.css b/web/src/theme.css new file mode 100644 index 0000000..da519b6 --- /dev/null +++ b/web/src/theme.css @@ -0,0 +1,45 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + + --color-background: var(--vt-c-white); + --color-background-alt: rgba(244, 244, 244, 1); + + --color-primary: rgba(231, 55, 119, 1); + --color-primary-light: rgba(231, 55, 119, 0.2); + --color-primary-dark: rgba(186, 35, 90, 1); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-text: rgba(0, 0, 0, 1); + --color-text-subtle: rgba(76, 76, 76, 1); + + --color-error-light: rgba(255, 228, 228, 1); + --color-error: rgba(231, 55, 58, 1); + --color-error-dark: rgba(186, 35, 38, 1); + + --section-gap: 160px; +} \ No newline at end of file From d8fa956f3627c358a13cd9563193829ed73e9145 Mon Sep 17 00:00:00 2001 From: Matic Babnik Date: Mon, 5 Jan 2026 20:16:11 +0100 Subject: [PATCH 2/9] fix: correct extensions list --- .vscode/extensions.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index bbbbfd4..66913b2 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,16 +3,18 @@ // CSS Variable autocomplete "vunguyentuan.vscode-css-variables", - // Formatter/linter - "biomejs.biome", - // Typescript help "orta.vscode-twoslash-queries", - + // Vue "Vue.volar", - + // Docker (compose) files - "docker.docker" + "docker.docker", + + // Formatting and linting + "oxc.oxc-vscode", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint" ] } From d163ba948db9106fd51b66bd5a20e4660f9fcebd Mon Sep 17 00:00:00 2001 From: Matic Babnik Date: Mon, 5 Jan 2026 20:17:07 +0100 Subject: [PATCH 3/9] feat: Add icons & some button styles --- web/bun.lock | 11 +- web/index.html | 2 +- web/package.json | 24 ++-- web/src/App.vue | 7 +- .../components/button/sync-button.story.vue | 42 ++++++- web/src/components/button/sync-button.vue | 108 ++++++++++++++---- web/src/components/icon/icons.ts | 3 + web/src/components/icon/sync-icon.story.vue | 12 ++ web/src/components/icon/sync-icon.vue | 17 +++ web/src/icons/.gitkeep | 0 web/src/icons/arrow_forward.svg | 1 + web/src/icons/settings.svg | 1 + web/src/icons/share.svg | 1 + web/vite.config.ts | 24 ++-- 14 files changed, 194 insertions(+), 59 deletions(-) create mode 100644 web/src/components/icon/icons.ts create mode 100644 web/src/components/icon/sync-icon.story.vue create mode 100644 web/src/components/icon/sync-icon.vue delete mode 100644 web/src/icons/.gitkeep create mode 100644 web/src/icons/arrow_forward.svg create mode 100644 web/src/icons/settings.svg create mode 100644 web/src/icons/share.svg diff --git a/web/bun.lock b/web/bun.lock index 0dd014a..b0de624 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "sync3-web", @@ -9,6 +10,7 @@ }, "devDependencies": { "@histoire/plugin-vue": "^1.0.0-alpha.5", + "@spiriit/vite-plugin-svg-spritemap": "^6.0.0", "@types/node": "^24.10.1", "@vitejs/plugin-vue": "5.2.1", "@vue/eslint-config-prettier": "^10.2.0", @@ -22,7 +24,6 @@ "prettier": "^3.7.4", "typescript": "~5.9.3", "vite": "~7.0.0", - "vite-plugin-svg-sprite": "^0.7.0", "vite-plugin-vue-devtools": "^8.0.5", "vue-tsc": "^3.2.1", }, @@ -313,6 +314,8 @@ "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], + "@spiriit/vite-plugin-svg-spritemap": ["@spiriit/vite-plugin-svg-spritemap@6.0.0", "", { "dependencies": { "@xmldom/xmldom": "^0.9.8", "hash-sum": "^2.0.0", "mini-svg-data-uri": "^1.4.4", "picomatch": "^4.0.3", "tinyglobby": "^0.2.15" }, "peerDependencies": { "@oxvg/napi": "^0.0.4-1", "@oxvg/napi-darwin-arm64": "^0.0.4-1", "@oxvg/napi-darwin-x64": "^0.0.4-1", "@oxvg/napi-linux-x64-gnu": "^0.0.4-1", "@oxvg/napi-win32-x64-msvc": "^0.0.4-1", "svgo": "^4.0.0", "vite": "^6.0.0 || ^7.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@oxvg/napi", "@oxvg/napi-darwin-arm64", "@oxvg/napi-darwin-x64", "@oxvg/napi-linux-x64-gnu", "@oxvg/napi-win32-x64-msvc", "svgo", "vue"] }, "sha512-zCxwZQmW9ZRGRsmzOWcwkObkUkLbUBv8mG4VEnAGHtQPijYleq5rI5hCvVEHFsXaWFKnqB4hBHQURXDzrkdENg=="], + "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], @@ -649,6 +652,8 @@ "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + "hash-sum": ["hash-sum@2.0.0", "", {}, "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="], + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "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": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], @@ -771,6 +776,8 @@ "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "mini-svg-data-uri": ["mini-svg-data-uri@1.4.4", "", { "bin": { "mini-svg-data-uri": "cli.js" } }, "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg=="], + "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], @@ -991,8 +998,6 @@ "vite-plugin-inspect": ["vite-plugin-inspect@11.3.3", "", { "dependencies": { "ansis": "^4.1.0", "debug": "^4.4.1", "error-stack-parser-es": "^1.0.5", "ohash": "^2.0.11", "open": "^10.2.0", "perfect-debounce": "^2.0.0", "sirv": "^3.0.1", "unplugin-utils": "^0.3.0", "vite-dev-rpc": "^1.1.0" }, "peerDependencies": { "vite": "^6.0.0 || ^7.0.0-0" } }, "sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA=="], - "vite-plugin-svg-sprite": ["vite-plugin-svg-sprite@0.7.0", "", { "dependencies": { "@xmldom/xmldom": "^0.9.4", "micromatch": "^4.0.2", "svgo": "^3.0.2" }, "peerDependencies": { "react": "17 || 18 || 19", "vite": "2 || 3 || 4 || 5 || 6 || 7", "vue": "3" }, "optionalPeers": ["react", "vue"] }, "sha512-z3KNUVELZxFkDPLswR4ua7S29FMYkluGP1BdCX5PYBYMkFp/3jrlZpC9Fhu2LrkNH56AejFAOWHWR7+qxAP8Vw=="], - "vite-plugin-vue-devtools": ["vite-plugin-vue-devtools@8.0.5", "", { "dependencies": { "@vue/devtools-core": "^8.0.5", "@vue/devtools-kit": "^8.0.5", "@vue/devtools-shared": "^8.0.5", "sirv": "^3.0.2", "vite-plugin-inspect": "^11.3.3", "vite-plugin-vue-inspector": "^5.3.2" }, "peerDependencies": { "vite": "^6.0.0 || ^7.0.0-0" } }, "sha512-p619BlKFOqQXJ6uDWS1vUPQzuJOD6xJTfftj57JXBGoBD/yeQCowR7pnWcr/FEX4/HVkFbreI6w2uuGBmQOh6A=="], "vite-plugin-vue-inspector": ["vite-plugin-vue-inspector@5.3.2", "", { "dependencies": { "@babel/core": "^7.23.0", "@babel/plugin-proposal-decorators": "^7.23.0", "@babel/plugin-syntax-import-attributes": "^7.22.5", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-transform-typescript": "^7.22.15", "@vue/babel-plugin-jsx": "^1.1.5", "@vue/compiler-dom": "^3.3.4", "kolorist": "^1.8.0", "magic-string": "^0.30.4" }, "peerDependencies": { "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" } }, "sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q=="], diff --git a/web/index.html b/web/index.html index bd2ed7e..568c7af 100644 --- a/web/index.html +++ b/web/index.html @@ -4,7 +4,7 @@ - sync3-web + Sync
diff --git a/web/package.json b/web/package.json index 4b195f1..3f6325b 100644 --- a/web/package.json +++ b/web/package.json @@ -22,22 +22,22 @@ "vue": "3.5.15" }, "devDependencies": { - "vue-tsc": "^3.2.1", - "typescript": "~5.9.3", + "@histoire/plugin-vue": "^1.0.0-alpha.5", + "@spiriit/vite-plugin-svg-spritemap": "^6.0.0", "@types/node": "^24.10.1", - "@vue/tsconfig": "^0.8.1", - "vite": "~7.0.0", - "vite-plugin-svg-sprite": "^0.7.0", - "vite-plugin-vue-devtools": "^8.0.5", "@vitejs/plugin-vue": "5.2.1", - "@histoire/plugin-vue": "^1.0.0-alpha.5", + "@vue/eslint-config-prettier": "^10.2.0", + "@vue/eslint-config-typescript": "^14.6.0", + "@vue/tsconfig": "^0.8.1", + "eslint": "^9.39.2", + "eslint-plugin-oxlint": "~1.35.0", + "eslint-plugin-vue": "~10.6.2", "histoire": "^1.0.0-alpha.5", "oxlint": "^1.36.0", "prettier": "^3.7.4", - "eslint": "^9.39.2", - "eslint-plugin-vue": "~10.6.2", - "eslint-plugin-oxlint": "~1.35.0", - "@vue/eslint-config-prettier": "^10.2.0", - "@vue/eslint-config-typescript": "^14.6.0" + "typescript": "~5.9.3", + "vite": "~7.0.0", + "vite-plugin-vue-devtools": "^8.0.5", + "vue-tsc": "^3.2.1" } } diff --git a/web/src/App.vue b/web/src/App.vue index 1782734..914fb95 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -1,7 +1,12 @@ - + diff --git a/web/src/components/icon/icons.ts b/web/src/components/icon/icons.ts new file mode 100644 index 0000000..07020db --- /dev/null +++ b/web/src/components/icon/icons.ts @@ -0,0 +1,3 @@ +export const ICONS = ['arrow_forward', 'settings', 'share'] as const + +export type TIconName = (typeof ICONS)[number] diff --git a/web/src/components/icon/sync-icon.story.vue b/web/src/components/icon/sync-icon.story.vue new file mode 100644 index 0000000..f1a01b4 --- /dev/null +++ b/web/src/components/icon/sync-icon.story.vue @@ -0,0 +1,12 @@ + + + diff --git a/web/src/components/icon/sync-icon.vue b/web/src/components/icon/sync-icon.vue new file mode 100644 index 0000000..53b813a --- /dev/null +++ b/web/src/components/icon/sync-icon.vue @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/web/src/icons/.gitkeep b/web/src/icons/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/web/src/icons/arrow_forward.svg b/web/src/icons/arrow_forward.svg new file mode 100644 index 0000000..564959c --- /dev/null +++ b/web/src/icons/arrow_forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/icons/settings.svg b/web/src/icons/settings.svg new file mode 100644 index 0000000..f64cfd6 --- /dev/null +++ b/web/src/icons/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/src/icons/share.svg b/web/src/icons/share.svg new file mode 100644 index 0000000..6e64082 --- /dev/null +++ b/web/src/icons/share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/vite.config.ts b/web/vite.config.ts index ca92866..9ac088b 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -1,20 +1,14 @@ /// -import { defineConfig } from 'vite'; -import vue from '@vitejs/plugin-vue'; -import createSvgSpritePlugin from 'vite-plugin-svg-sprite'; +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueDevTools from 'vite-plugin-vue-devtools' +import VitePluginSvgSpritemap from '@spiriit/vite-plugin-svg-spritemap' // https://vite.dev/config/ export default defineConfig({ - plugins: [ - vue(), - createSvgSpritePlugin({ - exportType: 'vanilla', - include: 'src/icons/*.svg', - symbolId: 's-[name]', - }), - ], - histoire: { - setupFile: '/src/histoire.setup.ts', - }, -}); + plugins: [vue(), vueDevTools(), VitePluginSvgSpritemap('./src/icons/*.svg')], + histoire: { + setupFile: '/src/histoire.setup.ts', + }, +}) From d0785cca5097f1dd652115da415783524cdc724e Mon Sep 17 00:00:00 2001 From: Matic Babnik Date: Tue, 6 Jan 2026 00:33:01 +0100 Subject: [PATCH 4/9] feat: Text input --- .vscode/settings.json | 14 +- web/src/components/TextField.vue | 151 ----------------- web/src/components/button/sync-button.vue | 2 +- web/src/components/icon/icons.ts | 2 +- web/src/components/icon/sync-icon.story.vue | 4 +- web/src/components/input/sync-input.story.vue | 17 ++ web/src/components/input/sync-input.vue | 157 ++++++++++++++++++ web/src/icons/error.svg | 1 + web/src/syncds.css | 1 + 9 files changed, 183 insertions(+), 166 deletions(-) delete mode 100644 web/src/components/TextField.vue create mode 100644 web/src/components/input/sync-input.story.vue create mode 100644 web/src/components/input/sync-input.vue create mode 100644 web/src/icons/error.svg diff --git a/.vscode/settings.json b/.vscode/settings.json index 48d87c4..805125e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,13 +1,5 @@ { - "cssVariables.lookupFiles": [ - "sync3-web/src/syncds.css" - ], - "cssVariables.languages": [ - "vue", - "vue-html", - "css", - "source.css.styled" - ], + "cssVariables.lookupFiles": ["web/src/syncds.css"], "editor.tabSize": 4, "editor.indentSize": "tabSize", "editor.detectIndentation": false, @@ -18,5 +10,5 @@ "package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, bun.lock, .oxlintrc.json, .prettierrc.json, eslint.config.js", "Dockerfile": "nginx.conf", "vite.config.ts": "histoire.config.ts" - }, -} \ No newline at end of file + } +} diff --git a/web/src/components/TextField.vue b/web/src/components/TextField.vue deleted file mode 100644 index cd8965d..0000000 --- a/web/src/components/TextField.vue +++ /dev/null @@ -1,151 +0,0 @@ - - - - - diff --git a/web/src/components/button/sync-button.vue b/web/src/components/button/sync-button.vue index f8ec0ac..03acdeb 100644 --- a/web/src/components/button/sync-button.vue +++ b/web/src/components/button/sync-button.vue @@ -73,7 +73,7 @@ const emit = defineEmits<{ .s-btn-smat { font-size: 18px; - padding: 14px; + padding: 13px; border-radius: 4px; } diff --git a/web/src/components/icon/icons.ts b/web/src/components/icon/icons.ts index 07020db..9815570 100644 --- a/web/src/components/icon/icons.ts +++ b/web/src/components/icon/icons.ts @@ -1,3 +1,3 @@ -export const ICONS = ['arrow_forward', 'settings', 'share'] as const +export const ICONS = ['arrow_forward', 'settings', 'share', 'error'] as const export type TIconName = (typeof ICONS)[number] diff --git a/web/src/components/icon/sync-icon.story.vue b/web/src/components/icon/sync-icon.story.vue index f1a01b4..7643ab3 100644 --- a/web/src/components/icon/sync-icon.story.vue +++ b/web/src/components/icon/sync-icon.story.vue @@ -4,8 +4,8 @@ import SyncIcon from './sync-icon.vue';