Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c0af889
CrowdIn Module Commit
sushilzore Aug 26, 2025
f12b4da
CrowdIn Module Fixes
sushilzore Sep 10, 2025
39eb435
Yarn Lock File CHanges
sushilzore Sep 10, 2025
4902ae9
Crowdin Plugin Change
sushilzore Sep 10, 2025
5f5c49a
Crowdin plugin changes
sushilzore Sep 11, 2025
5055556
bump version
clementroche Sep 10, 2025
2cc5326
TypeScript Error Fixes
sushilzore Sep 11, 2025
c1940a0
TypeScript Fixes
sushilzore Sep 11, 2025
19825c7
Corrected the Error Message
sushilzore Sep 11, 2025
9048459
CrowdIn Export Fixes
sushilzore Sep 12, 2025
d6ed3eb
TypeScript Fixes
sushilzore Sep 12, 2025
7de3db5
TypeScript Fixes
sushilzore Sep 12, 2025
e29a27e
TypeScript Fixes
sushilzore Sep 12, 2025
b24b916
TypeScript Fixes
sushilzore Sep 12, 2025
4bc7309
CrowdIn Language Related Fixes
sushilzore Sep 15, 2025
4ec5206
UI height
clementroche Sep 15, 2025
e069211
New UI provided As Per Mock Up
sushilzore Sep 25, 2025
8c6c17f
fix yarn
clementroche Oct 2, 2025
204b12c
assets
clementroche Oct 2, 2025
917c175
cleanup
clementroche Oct 3, 2025
9b8aa6b
readme
clementroche Oct 3, 2025
69fbcad
pass TS CI
clementroche Oct 3, 2025
15a144d
pass TS CI again
clementroche Oct 3, 2025
38c2c41
Update plugins/crowdin/src/App.tsx
clementroche Oct 6, 2025
d2378ff
Update plugins/crowdin/src/xliff.ts
clementroche Oct 6, 2025
403bfa8
UI QA
clementroche Oct 6, 2025
37cb6ff
invalid access token
clementroche Oct 6, 2025
f001255
conditional renderin plugin
clementroche Oct 6, 2025
7cc6068
pass ts CI
clementroche Oct 6, 2025
3ed2ba1
button theme
clementroche Oct 7, 2025
416d864
check permissions
clementroche Oct 7, 2025
1ff49a6
improve error managment
clementroche Oct 7, 2025
02073ff
QA
clementroche Oct 9, 2025
17afa71
Update framer-plugin
madebyisaacr Jan 28, 2026
e515c8e
Update CSS and logo
madebyisaacr Jan 28, 2026
8adf80d
Add link
madebyisaacr Jan 28, 2026
68f3377
Loading states and validation
madebyisaacr Jan 28, 2026
690513e
Update notifications
madebyisaacr Jan 28, 2026
3756bc0
Errors and validation
madebyisaacr Jan 28, 2026
7c1544c
Light theme logo, fix import error
madebyisaacr Jan 28, 2026
375f05e
Close warning
madebyisaacr Jan 28, 2026
67c8970
Add code
madebyisaacr Jan 28, 2026
83f3f49
Fix padding
madebyisaacr Jan 28, 2026
00094d2
Auto focus
madebyisaacr Jan 28, 2026
8004b08
Update image
madebyisaacr Jan 29, 2026
cce0466
Logo
madebyisaacr Jan 29, 2026
3dd72e8
Text
madebyisaacr Jan 29, 2026
782592c
Remove unused code
madebyisaacr Jan 29, 2026
e2fa461
Update index.html
madebyisaacr Jan 29, 2026
0fefa48
Update dependency
madebyisaacr Jan 29, 2026
1e941e6
New home page
madebyisaacr Jan 29, 2026
9038076
Config page
madebyisaacr Jan 29, 2026
1e85017
New app design
madebyisaacr Jan 29, 2026
6b02da5
Improve validation
madebyisaacr Jan 29, 2026
75df611
Locale selector
madebyisaacr Jan 29, 2026
e5e7994
Buttons
madebyisaacr Jan 29, 2026
0981c18
Error state
madebyisaacr Jan 29, 2026
6c62920
Move icons
madebyisaacr Jan 29, 2026
f81f82c
Make buttons work
madebyisaacr Jan 29, 2026
4b5dc13
Delete OldApp.tsx
madebyisaacr Jan 29, 2026
3b939fc
Update App.css
madebyisaacr Jan 29, 2026
d5fad93
Remove unused svg
madebyisaacr Jan 29, 2026
d6821c0
Projects menu
madebyisaacr Jan 29, 2026
ed809bd
Improve locale selection
madebyisaacr Jan 29, 2026
398cbff
Locales list
madebyisaacr Jan 29, 2026
ee21f43
Sync multiple locales
madebyisaacr Jan 29, 2026
0221854
Empty state
madebyisaacr Jan 29, 2026
02f5329
Fix token saving
madebyisaacr Jan 29, 2026
8a156b3
Confirmation modal
madebyisaacr Jan 29, 2026
a847f88
Close on import
madebyisaacr Jan 29, 2026
a03ab26
Revert close on import
madebyisaacr Jan 29, 2026
d8f1472
Fix formatting
madebyisaacr Jan 29, 2026
1a0ace2
Locales loading state
madebyisaacr Jan 30, 2026
3674dd3
Save selected project
madebyisaacr Jan 30, 2026
6511bbe
autoComplete off
madebyisaacr Jan 30, 2026
2193809
Add link, update empty states
madebyisaacr Jan 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"biome.enabled": true,
"editor.defaultFormatter": "biomejs.biome",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file added assets/crowdin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions plugins/crowdin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Crowdin Localization Plugin for Framer

A Framer plugin that synchronizes localization strings between **Framer** and **[Crowdin](https://crowdin.com/)**.
---

## ✨ Features
- **Export** source strings from Framer → Crowdin
- **Import** translations from Crowdin → Framer
- Simple UI with **two buttons**:
- `Export to Crowdin`
- `Import from Crowdin`


**By:** @sushilzore, @clementroche, and @madebyisaacr

![Crowdin Image](../../assets/hero.png)
6 changes: 6 additions & 0 deletions plugins/crowdin/framer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "cr0d1n",
"name": "Crowdin",
"modes": ["localization"],
"icon": "/icon.svg"
}
13 changes: 13 additions & 0 deletions plugins/crowdin/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Crowdin</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
27 changes: 27 additions & 0 deletions plugins/crowdin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "crowdin",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "run g:dev",
"build": "run g:build",
"check-biome": "run g:check-biome",
"check-eslint": "run g:check-eslint",
"preview": "run g:preview",
"pack": "npx framer-plugin-tools@latest pack",
"check-typescript": "run g:check-typescript"
},
"dependencies": {
"@crowdin/crowdin-api-client": "^1.46.0",
"classnames": "^2.5.1",
"framer-plugin": "^3.10.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"valibot": "^1.2.0"
},
"devDependencies": {
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.7"
}
}
12 changes: 12 additions & 0 deletions plugins/crowdin/public/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
244 changes: 244 additions & 0 deletions plugins/crowdin/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/* Your Plugin CSS */

:root {
--crowdin-brand-color: #263238;
--color-error: #ff3366;
}

[data-framer-theme="light"] {
--image-border-color: rgba(0, 0, 0, 0.05);
}

[data-framer-theme="dark"] {
--image-border-color: rgba(255, 255, 255, 0.05);
}

main {
display: flex;
flex-direction: column;
align-items: start;
padding: 0 15px 15px;
gap: 15px;

user-select: none;
-webkit-user-select: none;
}

main.home {
height: 270px;
}

select {
padding: 0 16px 0 10px;
}

select:not(:disabled) {
cursor: pointer;
}

h1 {
font-size: 12px;
font-weight: 600;
}

strong {
font-weight: 500;
color: var(--framer-color-text);
}

.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
gap: 10px;
width: 100%;
flex: 1;
}

.hero p {
text-wrap: balance;
color: var(--framer-color-text-tertiary);
max-width: 200px;
}

.hero .logo {
width: 30px;
height: 30px;
border-radius: 8px;
position: relative;
overflow: clip;
margin-bottom: 5px;
}

.hero .logo img {
width: 100%;
height: 100%;
}

.hero .logo:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid var(--image-border-color);
border-radius: 8px;
}

.button-row {
display: flex;
flex-direction: row;
gap: 10px;
width: 100%;
}

.button-row button {
flex: 1;
}

.controls-stack {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}

.property-control {
width: 100%;
display: flex;
flex-direction: row;
align-items: start;
gap: 10px;
padding-left: 10px;
}

.property-control.disabled > p,
.controls-stack.disabled {
opacity: 0.5;
pointer-events: none;
}

.property-control > p {
flex: 1;
height: 30px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}

.property-control .content {
display: flex;
flex-direction: column;
gap: 10px;
width: 150px;
}

.property-control .content > * {
width: 100%;
}

.access-token-input {
position: relative;
}

.access-token-input input {
width: 100%;
}

.access-token-input:has(.icon) input {
padding-right: 26px;
}

.access-token-input .icon-button {
position: absolute;
top: 0;
right: 0;
}

.link-icon:hover {
color: var(--framer-color-text);
}

.access-token-input .icon {
position: absolute;
padding: 0 8px;
height: 100%;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
}

.button-stack {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
}

.dropdown-button {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 10px;
width: 100%;
padding-right: 0;
font-weight: 500;
background-color: var(--framer-color-bg-tertiary) !important;
}

.icon-button {
display: flex;
align-items: center;
justify-content: center;
padding: 0 8px;
height: 100%;
color: var(--framer-color-text-tertiary);
transition: color 0.2s ease-in-out;
}

input.error {
box-shadow: inset 0 0 0 1px var(--color-error);
color: var(--color-error);
background-color: color-mix(in srgb, var(--color-error) 10%, transparent);
}

.locales-empty-state {
background-color: var(--framer-color-bg-tertiary);
border-radius: 8px;
opacity: 0.5;
height: 30px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 0 10px;
}

.checkbox-label {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
}

.checkbox-label input[type="checkbox"]:not(:checked) {
background-color: var(--framer-color-bg-tertiary);
}

.heading {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}

.step-indicator {
color: var(--framer-color-text-tertiary);
}
Loading
Loading