diff --git a/package-lock.json b/package-lock.json index 591f8bacc0f..caba02a3fc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1531,6 +1531,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", + "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", @@ -3473,10 +3489,33 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/runtime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", - "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -5879,6 +5918,23 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, "node_modules/@next/env": { "version": "16.0.10", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.10.tgz", @@ -6355,6 +6411,16 @@ "node": "^16.13.0 || >=18.0.0" } }, + "node_modules/@oxc-project/types": { + "version": "0.103.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.103.0.tgz", + "integrity": "sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "dev": true, @@ -6443,7 +6509,9 @@ "link": true }, "node_modules/@primer/octicons": { - "version": "19.15.5", + "version": "19.21.1", + "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.21.1.tgz", + "integrity": "sha512-7tgtBkCNcg75YJnckinzvES+uxysYQCe+CHSEnzr3VYgxttzKRvfmrnVogl3aEuHCQP4xhiE9k2lFDhYwGtTzQ==", "license": "MIT", "dependencies": { "object-assign": "^4.1.1" @@ -6461,6 +6529,10 @@ "react": ">=16.3" } }, + "node_modules/@primer/octicons-react-symbols": { + "resolved": "packages/octicons-react-symbols", + "link": true + }, "node_modules/@primer/primitives": { "version": "11.3.1", "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-11.3.1.tgz", @@ -7353,6 +7425,234 @@ "dev": true, "license": "MIT" }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.57.tgz", + "integrity": "sha512-GoOVDy8bjw9z1K30Oo803nSzXJS/vWhFijFsW3kzvZCO8IZwFnNa6pGctmbbJstKl3Fv6UBwyjJQN6msejW0IQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.57.tgz", + "integrity": "sha512-9c4FOhRGpl+PX7zBK5p17c5efpF9aSpTPgyigv57hXf5NjQUaJOOiejPLAtFiKNBIfm5Uu6yFkvLKzOafNvlTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.57.tgz", + "integrity": "sha512-6RsB8Qy4LnGqNGJJC/8uWeLWGOvbRL/KG5aJ8XXpSEupg/KQtlBEiFaYU/Ma5Usj1s+bt3ItkqZYAI50kSplBA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.57.tgz", + "integrity": "sha512-uA9kG7+MYkHTbqwv67Tx+5GV5YcKd33HCJIi0311iYBd25yuwyIqvJfBdt1VVB8tdOlyTb9cPAgfCki8nhwTQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.57.tgz", + "integrity": "sha512-3KkS0cHsllT2T+Te+VZMKHNw6FPQihYsQh+8J4jkzwgvAQpbsbXmrqhkw3YU/QGRrD8qgcOvBr6z5y6Jid+rmw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.57.tgz", + "integrity": "sha512-A3/wu1RgsHhqP3rVH2+sM81bpk+Qd2XaHTl8LtX5/1LNR7QVBFBCpAoiXwjTdGnI5cMdBVi7Z1pi52euW760Fw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.57.tgz", + "integrity": "sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.57.tgz", + "integrity": "sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.57.tgz", + "integrity": "sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.57.tgz", + "integrity": "sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.57.tgz", + "integrity": "sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.57.tgz", + "integrity": "sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.57.tgz", + "integrity": "sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.57.tgz", + "integrity": "sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/plugin-babel": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.1.0.tgz", @@ -8561,6 +8861,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/acorn": { "version": "4.0.6", "dev": true, @@ -8576,6 +8887,8 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", "dependencies": { @@ -8587,7 +8900,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.3", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -21016,14 +21331,14 @@ "license": "MIT" }, "node_modules/publint": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.15.tgz", - "integrity": "sha512-xPbRAPW+vqdiaKy5sVVY0uFAu3LaviaPO3pZ9FaRx59l9+U/RKR1OEbLhkug87cwiVKxPXyB4txsv5cad67u+A==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.16.tgz", + "integrity": "sha512-MFqyfRLAExPVZdTQFwkAQELzA8idyXzROVOytg6nEJ/GEypXBUmMGrVaID8cTuzRS1U5L8yTOdOJtMXgFUJAeA==", "dev": true, "license": "MIT", "dependencies": { "@publint/pack": "^0.1.2", - "package-manager-detector": "^1.3.0", + "package-manager-detector": "^1.6.0", "picocolors": "^1.1.1", "sade": "^1.8.1" }, @@ -21038,9 +21353,9 @@ } }, "node_modules/publint/node_modules/package-manager-detector": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", - "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", "dev": true, "license": "MIT" }, @@ -21758,6 +22073,38 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rolldown": { + "version": "1.0.0-beta.57", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.57.tgz", + "integrity": "sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.103.0", + "@rolldown/pluginutils": "1.0.0-beta.57" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.57", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.57", + "@rolldown/binding-darwin-x64": "1.0.0-beta.57", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.57", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.57", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.57", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.57", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.57", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.57", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.57", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.57", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.57", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.57" + } + }, "node_modules/rollup": { "version": "4.54.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", @@ -21824,6 +22171,8 @@ }, "node_modules/rollup-plugin-typescript2": { "version": "0.36.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", + "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", "dev": true, "license": "MIT", "dependencies": { @@ -24580,9 +24929,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -26423,6 +26772,34 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "packages/octicons-react-symbols": { + "name": "@primer/octicons-react-symbols", + "version": "0.0.0", + "dependencies": { + "@babel/runtime": "^7.28.4", + "react-compiler-runtime": "^1.0.0" + }, + "devDependencies": { + "@babel/core": "^7.28.5", + "@babel/generator": "^7.28.5", + "@babel/plugin-transform-react-constant-elements": "^7.27.1", + "@babel/plugin-transform-runtime": "^7.28.5", + "@babel/preset-react": "^7.28.5", + "@babel/preset-typescript": "^7.28.5", + "@primer/octicons": "^19.21.1", + "@rollup/plugin-babel": "^6.1.0", + "@types/babel__core": "^7.20.5", + "@types/babel__generator": "^7.27.0", + "babel-plugin-react-compiler": "^1.0.0", + "change-case": "^5.4.4", + "publint": "^0.3.16", + "react": "^18.3.1", + "rimraf": "^5.0.5", + "rolldown": "^1.0.0-beta.57", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.9.3" + } + }, "packages/postcss-preset-primer": { "version": "0.0.0", "dependencies": { @@ -26482,6 +26859,7 @@ "@figma/code-connect": "1.3.2", "@primer/css": "^21.5.1", "@primer/doc-gen": "^0.0.1", + "@primer/octicons-react-symbols": "^0.0.0", "@rollup/plugin-babel": "6.1.0", "@rollup/plugin-commonjs": "29.0.0", "@rollup/plugin-json": "6.1.0", diff --git a/packages/octicons-react-symbols/.gitignore b/packages/octicons-react-symbols/.gitignore new file mode 100644 index 00000000000..4150114be5f --- /dev/null +++ b/packages/octicons-react-symbols/.gitignore @@ -0,0 +1 @@ +src/generated/** diff --git a/packages/octicons-react-symbols/package.json b/packages/octicons-react-symbols/package.json new file mode 100644 index 00000000000..b3ae568abc2 --- /dev/null +++ b/packages/octicons-react-symbols/package.json @@ -0,0 +1,40 @@ +{ + "name": "@primer/octicons-react-symbols", + "version": "0.0.0", + "type": "module", + "private": true, + "exports": { + "types": "./dist/generated/index.d.ts", + "default": "./dist/generated/index.js" + }, + "scripts": { + "build": "node script/build.ts && rolldown -c", + "clean": "rimraf dist", + "lint:npm": "publint --types", + "type-check": "tsc --noEmit", + "watch": "rolldown -c -w" + }, + "devDependencies": { + "@babel/core": "^7.28.5", + "@babel/generator": "^7.28.5", + "@babel/plugin-transform-runtime": "^7.28.5", + "@babel/preset-react": "^7.28.5", + "@babel/preset-typescript": "^7.28.5", + "@primer/octicons": "^19.21.1", + "@rollup/plugin-babel": "^6.1.0", + "@types/babel__core": "^7.20.5", + "@types/babel__generator": "^7.27.0", + "babel-plugin-react-compiler": "^1.0.0", + "change-case": "^5.4.4", + "publint": "^0.3.16", + "react": "^18.3.1", + "rimraf": "^5.0.5", + "rolldown": "^1.0.0-beta.57", + "rollup-plugin-typescript2": "^0.36.0", + "typescript": "^5.9.3" + }, + "dependencies": { + "@babel/runtime": "^7.28.4", + "react-compiler-runtime": "^1.0.0" + } +} diff --git a/packages/octicons-react-symbols/rolldown.config.js b/packages/octicons-react-symbols/rolldown.config.js new file mode 100644 index 00000000000..ee067401bd6 --- /dev/null +++ b/packages/octicons-react-symbols/rolldown.config.js @@ -0,0 +1,47 @@ +import {defineConfig} from 'rolldown/config' +import babel from '@rollup/plugin-babel' +import typescript from 'rollup-plugin-typescript2' +import packageJson from './package.json' with {type: 'json'} + +const external = [ + ...Object.keys(packageJson.peerDependencies ?? {}), + ...Object.keys(packageJson.dependencies ?? {}), + ...Object.keys(packageJson.devDependencies ?? {}), +].map(name => new RegExp(`^${name}(/.*)?`)) + +export default defineConfig({ + input: ['./src/generated/index.ts'], + external, + plugins: [ + typescript({ + tsconfig: 'tsconfig.build.json', + }), + babel({ + presets: [ + '@babel/preset-typescript', + [ + '@babel/preset-react', + { + runtime: 'automatic', + }, + ], + ], + plugins: [ + [ + 'babel-plugin-react-compiler', + { + target: '18', + }, + ], + '@babel/plugin-transform-runtime', + ], + extensions: ['.js', '.jsx', '.ts', '.tsx'], + babelHelpers: 'runtime', + }), + ], + output: { + dir: './dist', + preserveModules: true, + preserveModulesRoot: 'src', + }, +}) diff --git a/packages/octicons-react-symbols/script/build.ts b/packages/octicons-react-symbols/script/build.ts new file mode 100644 index 00000000000..4f9f2e6da12 --- /dev/null +++ b/packages/octicons-react-symbols/script/build.ts @@ -0,0 +1,242 @@ +import fs from 'node:fs/promises' +import path from 'node:path' +import babel from '@babel/core' +import {generate} from '@babel/generator' +import {pascalCase} from 'change-case' +import data from '@primer/octicons/build/data.json' with {type: 'json'} + +const {types: t} = babel +const SOURCE_DIRECTORY = path.resolve(import.meta.dirname, '../src') +const GENERATED_DIRECTORY = path.join(SOURCE_DIRECTORY, 'generated') + +await fs.mkdir(GENERATED_DIRECTORY, {recursive: true}) + +// Each icon is around 2-3kB in size, create modules around 100kB in size +const BUCKET_SIZE = 40 +const modules = partition(Object.values(data), BUCKET_SIZE).map((icons, index) => { + const filepath = path.join(GENERATED_DIRECTORY, `icons-${(index + 1).toString().padStart(2, '0')}.tsx`) + + const propsImportSpecifier = t.importSpecifier( + t.identifier('OcticonReferenceProps'), + t.identifier('OcticonReferenceProps'), + ) + propsImportSpecifier.importKind = 'type' + + const imports = [ + // import {forwardRef} from 'react' + t.importDeclaration( + [t.importSpecifier(t.identifier('forwardRef'), t.identifier('forwardRef'))], + t.stringLiteral('react'), + ), + + // import {Icon} from '../Icon' + t.importDeclaration([t.importSpecifier(t.identifier('Icon'), t.identifier('Icon'))], t.stringLiteral('../Icon')), + + // import type {OcticonReferenceProps} from '../types' + t.importDeclaration([propsImportSpecifier], t.stringLiteral('../types')), + ] + + const components = icons.flatMap(icon => { + const symbolName = `${pascalCase(icon.name)}Symbol` + const symbols = Object.entries(icon.heights).map(([height, size]) => { + const id = `symbol-octicon-${icon.name}-${height}` + + const jsx = t.jsxElement( + t.jsxOpeningElement(t.jsxIdentifier('symbol'), [ + t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(id)), + t.jsxAttribute(t.jsxIdentifier('viewBox'), t.stringLiteral(`0 0 ${size.width} ${height}`)), + ]), + t.jsxClosingElement(t.jsxIdentifier('symbol')), + svgToJSX(size.ast), + ) + + return { + id, + height, + width: size.width, + jsx, + } + }) + const symbolComponent = t.functionDeclaration( + t.identifier(symbolName), + [], + t.blockStatement([ + t.returnStatement( + symbols.length === 1 + ? symbols[0].jsx + : t.jsxFragment( + t.jsxOpeningFragment(), + t.jsxClosingFragment(), + symbols.map(symbol => symbol.jsx), + ), + ), + ]), + ) + + const referenceName = `${pascalCase(icon.name)}Icon` + const forwardRef = t.callExpression(t.identifier('forwardRef'), [ + t.functionExpression( + t.identifier(referenceName), + [t.identifier('props'), t.identifier('ref')], + t.blockStatement([ + t.returnStatement( + t.jsxElement( + t.jsxOpeningElement( + t.jsxIdentifier('Icon'), + [ + t.jsxSpreadAttribute(t.identifier('props')), + t.jsxAttribute(t.jsxIdentifier('ref'), t.jsxExpressionContainer(t.identifier('ref'))), + t.jsxAttribute( + t.jsxIdentifier('sizes'), + t.jsxExpressionContainer( + t.objectExpression( + symbols.map(symbol => + t.objectProperty( + t.stringLiteral(symbol.height), + t.objectExpression([ + t.objectProperty(t.stringLiteral('width'), t.numericLiteral(symbol.width)), + t.objectProperty(t.stringLiteral('id'), t.stringLiteral(symbol.id)), + ]), + ), + ), + ), + ), + ), + ], + true, + ), + t.jsxClosingElement(t.jsxIdentifier('Icon')), + [], + ), + ), + ]), + ), + ]) + + forwardRef.typeParameters = t.tsTypeParameterInstantiation([ + t.tsTypeReference(t.identifier('SVGSVGElement')), + t.tsTypeReference(t.identifier('OcticonReferenceProps')), + ]) + + const reference = t.variableDeclaration('const', [t.variableDeclarator(t.identifier(referenceName), forwardRef)]) + + return [t.exportNamedDeclaration(symbolComponent), t.exportNamedDeclaration(reference)] + }) + + const body = [...imports, ...components] + const program = t.addComment( + t.program(body), + 'leading', + `This file is auto-generated by 'script/build.ts'. Do not edit directly.`, + ) + + return { + filepath, + contents: generate(program).code, + exports: icons.flatMap(icon => [`${pascalCase(icon.name)}Icon`, `${pascalCase(icon.name)}Symbol`]), + } +}) + +for (const mod of modules) { + await fs.writeFile(mod.filepath, mod.contents) +} + +const indexFilePath = path.join(SOURCE_DIRECTORY, 'generated', 'index.ts') + +const octiconsSymbolsPropsExportSpecifier = t.exportSpecifier( + t.identifier('OcticonSymbolsProps'), + t.identifier('OcticonSymbolsProps'), +) +octiconsSymbolsPropsExportSpecifier.exportKind = 'type' + +const octiconsReferencePropsExportSpecifier = t.exportSpecifier( + t.identifier('OcticonReferenceProps'), + t.identifier('OcticonReferenceProps'), +) +octiconsReferencePropsExportSpecifier.exportKind = 'type' + +const index = t.addComment( + t.program([ + t.exportNamedDeclaration( + null, + [ + t.exportSpecifier(t.identifier('OcticonSymbols'), t.identifier('OcticonSymbols')), + octiconsSymbolsPropsExportSpecifier, + ], + t.stringLiteral('../OcticonSymbols'), + ), + t.exportNamedDeclaration(null, [octiconsReferencePropsExportSpecifier], t.stringLiteral('../types')), + ...modules.map(mod => { + return t.exportNamedDeclaration( + null, + mod.exports.map(exportName => t.exportSpecifier(t.identifier(exportName), t.identifier(exportName))), + t.stringLiteral(`./${path.basename(mod.filepath, path.extname(mod.filepath))}`), + ) + }), + ]), + 'leading', + `This file is auto-generated by 'script/build.ts'. Do not edit directly.`, +) + +await fs.writeFile(indexFilePath, generate(index).code) + +function partition(items: Array, size: number): Array> { + const result: Array> = [] + let bucket: Array = [] + let count = 0 + + for (const item of items) { + if (count >= size) { + result.push(bucket) + bucket = [] + count = 0 + } + + bucket.push(item) + count++ + } + + if (bucket.length > 0) { + result.push(bucket) + } + + return result +} + +type SVGASTNode = { + type: string + name: string + attributes: Record + children: Array +} + +function svgToJSX(node: SVGASTNode): Array { + if (node.type === 'element') { + const children = node.children.map(svgToJSX) + + if (node.name === 'svg') { + if (children.length === 0) { + throw new Error(`No children available for icon`) + } + + return children.flat() + } + + const attrs = Object.entries(node.attributes).map(([key, value]) => { + if (typeof value !== 'string') { + throw new Error(`Unknown value type: ${value}`) + } + return t.jsxAttribute(t.jsxIdentifier(key), t.stringLiteral(value)) + }) + const openingElement = t.jsxOpeningElement(t.jsxIdentifier(node.name), attrs, children.length === 0) + const closingElement = t.jsxClosingElement(t.jsxIdentifier(node.name)) + + if (children.length > 0) { + return [t.jsxElement(openingElement, closingElement, children.flat(), false)] + } + + return [t.jsxElement(openingElement, closingElement, [], true)] + } + + throw new Error(`Unknown type: ${node.type}`) +} diff --git a/packages/octicons-react-symbols/src/Icon.tsx b/packages/octicons-react-symbols/src/Icon.tsx new file mode 100644 index 00000000000..b6cf554c9b1 --- /dev/null +++ b/packages/octicons-react-symbols/src/Icon.tsx @@ -0,0 +1,67 @@ +import {forwardRef, type HTMLAttributes} from 'react' +import type {OcticonReferenceProps} from './types' + +const sizeMap = { + small: 16, + medium: 32, + large: 64, +} + +type Size = 'small' | 'medium' | 'large' + +type IconProps = HTMLAttributes & + OcticonReferenceProps & { + size?: Size | number + sizes: Record< + string, + { + id: string + width: number + } + > + } + +const Icon = forwardRef(function Icon( + {'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, className, size = 16, sizes, tabIndex, title, ...rest}, + ref, +) { + const height = typeof size === 'number' ? size : sizeMap[size] + const heights = Object.keys(sizes) + const naturalHeight = closestNaturalHeight(heights, height) + const naturalWidth = sizes[naturalHeight].width + const width = height * (naturalWidth / naturalHeight) + const id = sizes[naturalHeight].id + const labelled = ariaLabel || ariaLabelledBy + const role = labelled ? 'img' : undefined + + return ( + = 0 ? 'true' : 'false'} + aria-label={ariaLabel} + aria-labelledby={ariaLabelledBy} + className={className} + role={role} + viewBox={`0 0 ${naturalWidth} ${naturalHeight}`} + width={width} + height={height} + > + {title ? {title} : null} + + + ) +}) + +function closestNaturalHeight(naturalHeights: Array, height: number): number { + const parsed = naturalHeights.map(naturalHeight => parseInt(naturalHeight, 10)) + + return parsed.reduce((acc, naturalHeight) => { + return naturalHeight <= height ? naturalHeight : acc + }, parsed[0]) +} + +export {Icon} +export type {IconProps} diff --git a/packages/octicons-react-symbols/src/OcticonSymbols.tsx b/packages/octicons-react-symbols/src/OcticonSymbols.tsx new file mode 100644 index 00000000000..17d9846f5e5 --- /dev/null +++ b/packages/octicons-react-symbols/src/OcticonSymbols.tsx @@ -0,0 +1,14 @@ +import type {PropsWithChildren} from 'react' + +type OcticonSymbolsProps = PropsWithChildren<{}> + +function OcticonSymbols({children}: OcticonSymbolsProps) { + return ( + + ) +} + +export {OcticonSymbols} +export type {OcticonSymbolsProps} diff --git a/packages/octicons-react-symbols/src/types.ts b/packages/octicons-react-symbols/src/types.ts new file mode 100644 index 00000000000..e1e55247180 --- /dev/null +++ b/packages/octicons-react-symbols/src/types.ts @@ -0,0 +1,13 @@ +import type {HTMLAttributes, PropsWithChildren, ReactElement} from 'react' + +export type OcticonReferenceProps = HTMLAttributes & + PropsWithChildren<{ + 'aria-label'?: string + 'aria-labelledby'?: string + className?: string + fill?: string + id?: string + size?: number | 'small' | 'medium' | 'large' + tabIndex?: number + title?: string | ReactElement + }> diff --git a/packages/octicons-react-symbols/tsconfig.build.json b/packages/octicons-react-symbols/tsconfig.build.json new file mode 100644 index 00000000000..4a8f796ebc8 --- /dev/null +++ b/packages/octicons-react-symbols/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "emitDeclarationOnly": true, + "rootDir": "src" + }, + "exclude": [] +} + diff --git a/packages/octicons-react-symbols/tsconfig.json b/packages/octicons-react-symbols/tsconfig.json new file mode 100644 index 00000000000..c3dc902166e --- /dev/null +++ b/packages/octicons-react-symbols/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"] +} + diff --git a/packages/react/package.json b/packages/react/package.json index 674a73e6c47..2895bb2079d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -107,6 +107,7 @@ "@figma/code-connect": "1.3.2", "@primer/css": "^21.5.1", "@primer/doc-gen": "^0.0.1", + "@primer/octicons-react-symbols": "^0.0.0", "@tanstack/react-virtual": "^3.13.12", "@rollup/plugin-babel": "6.1.0", "@rollup/plugin-commonjs": "29.0.0", diff --git a/packages/react/src/OcticonSymbols/OcticonSymbols.stories.tsx b/packages/react/src/OcticonSymbols/OcticonSymbols.stories.tsx new file mode 100644 index 00000000000..02398d8ca9c --- /dev/null +++ b/packages/react/src/OcticonSymbols/OcticonSymbols.stories.tsx @@ -0,0 +1,15 @@ +import {OcticonSymbols, AccessibilitySymbol, AccessibilityIcon} from '@primer/octicons-react-symbols' + +export default { + title: 'Experimental/Components/OcticonSymbols', +} + +export const Default = () => ( + <> + + + + + + +) diff --git a/packages/react/src/OcticonSymbols/OcticonSymbols.tsx b/packages/react/src/OcticonSymbols/OcticonSymbols.tsx new file mode 100644 index 00000000000..4a1dce14e35 --- /dev/null +++ b/packages/react/src/OcticonSymbols/OcticonSymbols.tsx @@ -0,0 +1,10 @@ +import type {PropsWithChildren} from 'react' + +type OcticonSymbolsProps = PropsWithChildren<{}> + +function OcticonsSymbols({children}: OcticonSymbolsProps) { + return <>{children} +} + +export {OcticonsSymbols} +export type {OcticonSymbolsProps} diff --git a/packages/react/src/OcticonSymbols/index.ts b/packages/react/src/OcticonSymbols/index.ts new file mode 100644 index 00000000000..e69de29bb2d