mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
feat: add TypeScript support
This commit is contained in:
@@ -30,13 +30,18 @@ tmux select-window -t penpot:1
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch:app' enter
|
||||
|
||||
tmux new-window -t penpot:2 -n 'frontend storybook'
|
||||
tmux new-window -t penpot:2 -n 'frontend ts'
|
||||
tmux select-window -t penpot:2
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn watch:ts' enter
|
||||
|
||||
tmux new-window -t penpot:3 -n 'frontend storybook'
|
||||
tmux select-window -t penpot:3
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch:storybook' enter
|
||||
|
||||
tmux new-window -t penpot:3 -n 'exporter'
|
||||
tmux select-window -t penpot:3
|
||||
tmux new-window -t penpot:4 -n 'exporter'
|
||||
tmux select-window -t penpot:4
|
||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||
tmux send-keys -t penpot 'rm -f target/app.js*' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch' enter
|
||||
@@ -45,8 +50,8 @@ tmux split-window -v
|
||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
||||
|
||||
tmux new-window -t penpot:4 -n 'backend'
|
||||
tmux select-window -t penpot:4
|
||||
tmux new-window -t penpot:5 -n 'backend'
|
||||
tmux select-window -t penpot:5
|
||||
tmux send-keys -t penpot 'cd penpot/backend' enter C-l
|
||||
tmux send-keys -t penpot './scripts/start-dev' enter
|
||||
|
||||
|
||||
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@@ -11,4 +11,4 @@ node_modules/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/playwright/**/visual-specs/**/*.png
|
||||
|
||||
/ts/dist/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @type { import('@storybook/react-vite').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)", "../ts/src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
||||
staticDirs: ["../resources/public"],
|
||||
addons: [
|
||||
"@storybook/addon-themes",
|
||||
|
||||
23
frontend/eslint.config.js
Normal file
23
frontend/eslint.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import tseslint from 'typescript-eslint'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['ts/dist']),
|
||||
{
|
||||
files: ['ts/src/**/*.{ts,tsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
tseslint.configs.recommended,
|
||||
reactHooks.configs['recommended-latest'],
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
},
|
||||
},
|
||||
])
|
||||
@@ -17,7 +17,8 @@
|
||||
"@zip.js/zip.js@npm:^2.7.44": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch",
|
||||
"@vitejs/plugin-react": "^4.2.0",
|
||||
"playwright": "1.52.0",
|
||||
"playwright-core": "1.52.0"
|
||||
"playwright-core": "1.52.0",
|
||||
"globals": "^16.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build:app:assets": "node ./scripts/build-app-assets.js",
|
||||
@@ -32,8 +33,9 @@
|
||||
"e2e:server": "node ./scripts/e2e-server.js",
|
||||
"fmt:clj": "cljfmt fix --parallel=true src/ test/",
|
||||
"fmt:clj:check": "cljfmt check --parallel=false src/ test/",
|
||||
"fmt:js": "yarn run prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js -w",
|
||||
"fmt:js:check": "yarn run prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js",
|
||||
"fmt:js": "yarn run prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js -c ts/src/**/*.ts -w",
|
||||
"fmt:js:check": "yarn run prettier -c src/**/*.stories.jsx -c playwright/**/*.js -c scripts/**/*.js -c ts/src/**/*.ts -c --check",
|
||||
"lint:ts": "eslint ts/",
|
||||
"lint:clj": "clj-kondo --parallel --lint src/",
|
||||
"lint:scss": "yarn run prettier -c resources/styles -c src/**/*.scss",
|
||||
"lint:scss:fix": "yarn run prettier -c resources/styles -c src/**/*.scss -w",
|
||||
@@ -50,6 +52,7 @@
|
||||
"watch:app": "yarn run clear:shadow-cache && concurrently \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
|
||||
"watch": "yarn run watch:app:assets",
|
||||
"watch:storybook": "yarn run build:storybook:assets && concurrently \"storybook dev -p 6006 --no-open\" \"yarn run watch:storybook:assets\"",
|
||||
"watch:ts": "vite build --watch",
|
||||
"watch:storybook:assets": "node ./scripts/watch-storybook.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -59,11 +62,16 @@
|
||||
"@storybook/addon-vitest": "10.0.4",
|
||||
"@storybook/react-vite": "10.0.4",
|
||||
"@types/node": "^22.15.21",
|
||||
"@types/react": "^19.1.16",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"@vitest/browser": "3.2.4",
|
||||
"@vitest/coverage-v8": "3.2.4",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"concurrently": "^9.2.1",
|
||||
"esbuild": "^0.25.9",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.22",
|
||||
"express": "^5.1.0",
|
||||
"fancy-log": "^2.0.0",
|
||||
"getopts": "^2.3.0",
|
||||
@@ -95,6 +103,7 @@
|
||||
"storybook": "10.0.4",
|
||||
"svg-sprite": "^2.0.4",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.45.0",
|
||||
"vite": "^6.3.5",
|
||||
"vitest": "^3.2.0",
|
||||
"wasm-pack": "^0.13.1",
|
||||
@@ -108,7 +117,9 @@
|
||||
"@penpot/plugins-runtime": "1.3.2",
|
||||
"@penpot/svgo": "penpot/svgo#v3.1",
|
||||
"@penpot/text-editor": "portal:./text-editor",
|
||||
"@penpot/ts": "portal:./ts",
|
||||
"@tokens-studio/sd-transforms": "1.2.11",
|
||||
"@vitejs/plugin-react": "4.2.0",
|
||||
"@zip.js/zip.js": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch",
|
||||
"compression": "^1.8.1",
|
||||
"date-fns": "^4.1.0",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<meta name="twitter:creator" content="@penpotapp">
|
||||
<meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)">
|
||||
<link id="theme" href="css/main.css?version={{& version}}" rel="stylesheet" type="text/css" />
|
||||
<link href="css/ts-style.css?ts={{& ts}}" rel="stylesheet" type="text/css" />
|
||||
{{#isDebug}}
|
||||
<link href="css/debug.css?version={{& version}}" rel="stylesheet" type="text/css" />
|
||||
{{/isDebug}}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
(ns app.main
|
||||
(:require
|
||||
["@penpot/ts" :refer [setTranslation]]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.logging :as log]
|
||||
[app.common.types.objects-map]
|
||||
@@ -38,6 +39,8 @@
|
||||
(log/setup! {:app :info})
|
||||
(log/set-level! :debug)
|
||||
|
||||
(setTranslation i18n/tr)
|
||||
|
||||
(when (= :browser cf/target)
|
||||
(log/inf :version (:full cf/version)
|
||||
:asserts *assert*
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
(ns app.main.ui.dashboard.projects
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
["@penpot/ts" :refer [TestTsxComponent]]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.time :as ct]
|
||||
[app.main.data.common :as dcm]
|
||||
@@ -50,8 +51,11 @@
|
||||
::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [can-edit]}]
|
||||
;; (js/console.log "xxxx" TestTsxComponent)
|
||||
(let [on-click (mf/use-fn #(st/emit! (dd/create-project)))]
|
||||
[:header {:class (stl/css :dashboard-header) :data-testid "dashboard-header"}
|
||||
[:div
|
||||
[:> TestTsxComponent]]
|
||||
[:div#dashboard-projects-title {:class (stl/css :dashboard-title)}
|
||||
[:h1 (tr "dashboard.projects-title")]]
|
||||
(when can-edit
|
||||
|
||||
8
frontend/ts/package.json
Normal file
8
frontend/ts/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@penpot/ts",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@4.3.1"
|
||||
}
|
||||
3
frontend/ts/src/components/test-tsx.module.css
Normal file
3
frontend/ts/src/components/test-tsx.module.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.title {
|
||||
color: green;
|
||||
}
|
||||
16
frontend/ts/src/components/test-tsx.stories.tsx
Normal file
16
frontend/ts/src/components/test-tsx.stories.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
import {TestTsxComponent } from "./test-tsx";
|
||||
|
||||
export default {
|
||||
title: "TestTSX",
|
||||
component: TestTsxComponent,
|
||||
argTypes: {},
|
||||
parameters: {},
|
||||
};
|
||||
|
||||
export const Default = {};
|
||||
11
frontend/ts/src/components/test-tsx.tsx
Normal file
11
frontend/ts/src/components/test-tsx.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import styles from './test-tsx.module.css';
|
||||
|
||||
import { translate } from '../penpot-bridge';
|
||||
|
||||
export const TestTsxComponent = () => {
|
||||
return (
|
||||
<div>
|
||||
<h2 className={styles.title}>{translate("labels.delete")} xx</h2>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
4
frontend/ts/src/index.tsx
Normal file
4
frontend/ts/src/index.tsx
Normal file
@@ -0,0 +1,4 @@
|
||||
/* eslint-disable */
|
||||
|
||||
export { TestTsxComponent } from "./components/test-tsx";
|
||||
export { setTranslation } from "./penpot-bridge";
|
||||
7
frontend/ts/src/penpot-bridge.ts
Normal file
7
frontend/ts/src/penpot-bridge.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export let translate = (key: string) => {
|
||||
return key;
|
||||
};
|
||||
|
||||
export function setTranslation(translations: (key: string) => string) {
|
||||
translate = translations;
|
||||
}
|
||||
28
frontend/tsconfig.json
Normal file
28
frontend/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"types": ["vite/client"],
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["ts/src"]
|
||||
}
|
||||
@@ -1,8 +1,25 @@
|
||||
/// <reference types="vitest/config" />
|
||||
import { defineConfig } from "vite";
|
||||
import { configDefaults } from "vitest/config";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { copyFileSync } from "fs";
|
||||
|
||||
import { resolve } from "path";
|
||||
|
||||
const copyCssPlugin = () => ({
|
||||
name: "copy-css",
|
||||
closeBundle: () => {
|
||||
try {
|
||||
copyFileSync(
|
||||
"./ts/dist/frontend.css",
|
||||
"./resources/public/css/ts-style.css",
|
||||
);
|
||||
} catch (e) {
|
||||
console.log("Error copying css file", e);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -14,6 +31,7 @@ const dirname =
|
||||
|
||||
// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
|
||||
export default defineConfig({
|
||||
plugins: [react(), copyCssPlugin()],
|
||||
test: {
|
||||
exclude: [...configDefaults.exclude, "target/**", "resources/**"],
|
||||
environment: "jsdom",
|
||||
@@ -50,4 +68,22 @@ export default defineConfig({
|
||||
"@public": resolve(__dirname, "./resources/public/js/"),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: './ts/dist/',
|
||||
emptyOutDir: true,
|
||||
lib: {
|
||||
entry: './ts/src/index.tsx',
|
||||
fileName: () => `index.js`,
|
||||
formats: ['es'],
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react', 'react-dom'],
|
||||
output: {
|
||||
globals: {
|
||||
react: 'React',
|
||||
"react-dom": "ReactDOM",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user