Merge tag 'v0.10.27' into beta

This commit is contained in:
2026-01-27 23:03:46 +03:00
804 changed files with 69201 additions and 21982 deletions

View File

@@ -0,0 +1,19 @@
# Copying
The source code of Modrinth's UI library is licensed under the GNU General Public License, Version 3 only, which is provided in the file [LICENSE](./LICENSE). However, some files listed below are licensed under a different license.
## Modrinth logo
The use of Modrinth branding elements, including but not limited to the wrench-in-labyrinth logo, the landing image, and any variations thereof, is strictly prohibited without explicit written permission from Rinth, Inc. This includes trademarks, logos, or other branding elements.
> All rights reserved. © 2020-2025 Rinth, Inc.
This includes, but may not be limited to, the following files:
- branding/\*
## External logos
The following files are owned by their respective copyright holders and must be used within each of their Brand Guidelines:
- external/\*

View File

@@ -0,0 +1,213 @@
import fs from 'node:fs'
import path from 'node:path'
import readline from 'node:readline'
const packageRoot = path.resolve(__dirname, '..')
const iconsDir = path.join(packageRoot, 'icons')
const lucideIconsDir = path.join(packageRoot, 'node_modules/lucide-static/icons')
function listAvailableIcons(): string[] {
if (!fs.existsSync(lucideIconsDir)) {
return []
}
return fs
.readdirSync(lucideIconsDir)
.filter((file) => file.endsWith('.svg'))
.map((file) => path.basename(file, '.svg'))
.sort()
}
function paginateList(allIcons: string[], pageSize = 20): void {
let page = 0
let search = ''
let filteredIcons = allIcons
const getFilteredIcons = (): string[] => {
if (!search) return allIcons
return allIcons.filter((icon) => icon.includes(search))
}
const renderPage = (): void => {
console.clear()
filteredIcons = getFilteredIcons()
const totalPages = Math.max(1, Math.ceil(filteredIcons.length / pageSize))
if (page >= totalPages) page = Math.max(0, totalPages - 1)
const start = page * pageSize
const end = Math.min(start + pageSize, filteredIcons.length)
const pageIcons = filteredIcons.slice(start, end)
console.log(`\x1b[1mAvailable Lucide Icons\x1b[0m`)
console.log(`\x1b[2mSearch: \x1b[0m${search || '\x1b[2m(type to search)\x1b[0m'}\n`)
if (pageIcons.length === 0) {
console.log(` \x1b[2mNo icons found matching "${search}"\x1b[0m`)
} else {
pageIcons.forEach((icon) => {
if (search) {
const highlighted = icon.replace(search, `\x1b[33m${search}\x1b[0m`)
console.log(` ${highlighted}`)
} else {
console.log(` ${icon}`)
}
})
}
console.log(
`\n\x1b[2m${filteredIcons.length}/${allIcons.length} icons | Page ${page + 1}/${totalPages} | ← → navigate | :q quit\x1b[0m`,
)
}
renderPage()
readline.emitKeypressEvents(process.stdin)
if (process.stdin.isTTY) {
process.stdin.setRawMode(true)
}
process.stdin.on('keypress', (str, key) => {
if (key.ctrl && key.name === 'c') {
console.clear()
process.exit(0)
}
// :q to quit
if (search === ':' && key.name === 'q') {
console.clear()
process.exit(0)
}
// Navigation
if (key.name === 'right') {
const totalPages = Math.max(1, Math.ceil(filteredIcons.length / pageSize))
if (page < totalPages - 1) {
page++
renderPage()
}
return
}
if (key.name === 'left') {
if (page > 0) {
page--
renderPage()
}
return
}
// Backspace
if (key.name === 'backspace') {
search = search.slice(0, -1)
page = 0
renderPage()
return
}
// Escape to clear search
if (key.name === 'escape') {
search = ''
page = 0
renderPage()
return
}
// Type to search
if (str && str.length === 1 && !key.ctrl && !key.meta) {
search += str
page = 0
renderPage()
}
})
}
function addIcon(iconId: string, overwrite: boolean): boolean {
const sourcePath = path.join(lucideIconsDir, `${iconId}.svg`)
const targetPath = path.join(iconsDir, `${iconId}.svg`)
if (!fs.existsSync(sourcePath)) {
console.error(`❌ Icon "${iconId}" not found in lucide-static`)
console.error(` Run with --list to see available icons`)
return false
}
if (fs.existsSync(targetPath) && !overwrite) {
console.log(`⏭️ Skipping "${iconId}" (already exists, use --overwrite to replace)`)
return false
}
fs.copyFileSync(sourcePath, targetPath)
console.log(`✅ Added "${iconId}"`)
return true
}
function main(): void {
const args = process.argv.slice(2)
if (args.includes('--help') || args.includes('-h')) {
console.log(`
Usage: pnpm icons:add [options] <icon_id> [icon_id...]
Options:
--list, -l Browse all available Lucide icons (interactive)
--overwrite, -o Overwrite existing icons
--help, -h Show this help message
Examples:
pnpm icons:add heart star settings-2
pnpm icons:add --overwrite heart
pnpm icons:add --list # Interactive browser
pnpm icons:add --list | grep arrow # Pipe to grep
Interactive controls:
Type Search icons
← → Navigate pages
Escape Clear search
:q Quit
`)
process.exit(0)
}
if (args.includes('--list') || args.includes('-l')) {
const icons = listAvailableIcons()
if (icons.length === 0) {
console.error('❌ lucide-static not installed. Run pnpm install first.')
process.exit(1)
}
if (process.stdout.isTTY) {
paginateList(icons)
} else {
// Non-interactive mode (piped output)
icons.forEach((icon) => console.log(icon))
process.exit(0)
}
return
}
const overwrite = args.includes('--overwrite') || args.includes('-o')
const iconIds = args.filter((arg) => !arg.startsWith('-'))
if (iconIds.length === 0) {
console.error('Usage: pnpm icons:add <icon_id> [icon_id...]')
console.error('Example: pnpm icons:add heart star settings-2')
console.error('Run with --help for more options')
process.exit(1)
}
if (!fs.existsSync(lucideIconsDir)) {
console.error('❌ lucide-static not installed. Run pnpm install first.')
process.exit(1)
}
let added = 0
for (const iconId of iconIds) {
if (addIcon(iconId, overwrite)) {
added++
}
}
if (added > 0) {
console.log(`\n📦 Added ${added} icon(s). Run 'pnpm prepr:frontend:lib' to update exports.`)
}
}
main()

View File

@@ -1,3 +1,4 @@
import { compareImportSources } from '@modrinth/tooling-config/script-utils/import-sort'
import fs from 'fs'
import path from 'path'
@@ -22,15 +23,10 @@ function generateIconExports(): { imports: string; exports: string } {
throw new Error(`Icons directory not found: ${iconsDir}`)
}
const files = fs
.readdirSync(iconsDir)
.filter((file) => file.endsWith('.svg'))
.sort()
const files = fs.readdirSync(iconsDir).filter((file) => file.endsWith('.svg'))
let imports = ''
let exports = ''
files.forEach((file) => {
// Build icon data with import paths
const icons = files.map((file) => {
const baseName = path.basename(file, '.svg')
let pascalName = toPascalCase(baseName)
@@ -42,9 +38,21 @@ function generateIconExports(): { imports: string; exports: string } {
pascalName += 'Icon'
}
const privateName = `_${pascalName}`
return {
importPath: `./icons/${file}?component`,
pascalName,
privateName: `_${pascalName}`,
}
})
imports += `import ${privateName} from './icons/${file}?component'\n`
// Sort by import path using simple-import-sort's algorithm
icons.sort((a, b) => compareImportSources(a.importPath, b.importPath))
let imports = ''
let exports = ''
icons.forEach(({ importPath, pascalName, privateName }) => {
imports += `import ${privateName} from '${importPath}'\n`
exports += `export const ${pascalName} = ${privateName}\n`
})

7
packages/assets/external/flathub.svg vendored Normal file
View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0.04 -1.13 62.99 60.24">
<g fill="currentColor" stroke-width="1.123" transform="matrix(1.56993 0 0 1.56993 -247.445 -135.95)">
<circle cx="166.69" cy="95.647" r="9.048"/>
<rect width="15.875" height="15.875" x="158.75" y="108.33" rx="4.233" ry="4.233"/>
<path d="m195.534 93.49-1.622-.938-9.339-5.391a2.572 2.572 0 0 0-3.857 2.227v12.657a2.572 2.572 0 0 0 3.858 2.227l10.96-6.328a2.572 2.572 0 0 0 0-4.455zM194.99 116.31c0 .88-.708 1.587-1.587 1.587h-12.7c-.88 0-1.588-.708-1.588-1.587 0-.88.708-1.588 1.587-1.588h12.7c.88 0 1.588.709 1.588 1.588zm-7.938-7.938c.88 0 1.588.709 1.588 1.588v12.7c0 .88-.708 1.587-1.587 1.587-.88 0-1.588-.708-1.588-1.587v-12.7c0-.88.708-1.587 1.587-1.587z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 759 B

View File

@@ -8,6 +8,7 @@ import _ArrowBigRightDashIcon from './icons/arrow-big-right-dash.svg?component'
import _ArrowBigUpDashIcon from './icons/arrow-big-up-dash.svg?component'
import _ArrowDownIcon from './icons/arrow-down.svg?component'
import _ArrowDownLeftIcon from './icons/arrow-down-left.svg?component'
import _ArrowLeftIcon from './icons/arrow-left.svg?component'
import _ArrowLeftRightIcon from './icons/arrow-left-right.svg?component'
import _ArrowUpIcon from './icons/arrow-up.svg?component'
import _ArrowUpRightIcon from './icons/arrow-up-right.svg?component'
@@ -17,6 +18,7 @@ import _BadgeDollarSignIcon from './icons/badge-dollar-sign.svg?component'
import _BanIcon from './icons/ban.svg?component'
import _BellIcon from './icons/bell.svg?component'
import _BellRingIcon from './icons/bell-ring.svg?component'
import _BlendIcon from './icons/blend.svg?component'
import _BlocksIcon from './icons/blocks.svg?component'
import _BoldIcon from './icons/bold.svg?component'
import _BookIcon from './icons/book.svg?component'
@@ -26,6 +28,7 @@ import _BookmarkIcon from './icons/bookmark.svg?component'
import _BotIcon from './icons/bot.svg?component'
import _BoxIcon from './icons/box.svg?component'
import _BoxImportIcon from './icons/box-import.svg?component'
import _BoxesIcon from './icons/boxes.svg?component'
import _BracesIcon from './icons/braces.svg?component'
import _BrushCleaningIcon from './icons/brush-cleaning.svg?component'
import _BugIcon from './icons/bug.svg?component'
@@ -39,6 +42,7 @@ import _CheckCircleIcon from './icons/check-circle.svg?component'
import _ChevronDownIcon from './icons/chevron-down.svg?component'
import _ChevronLeftIcon from './icons/chevron-left.svg?component'
import _ChevronRightIcon from './icons/chevron-right.svg?component'
import _ChevronUpIcon from './icons/chevron-up.svg?component'
import _CircleUserIcon from './icons/circle-user.svg?component'
import _ClearIcon from './icons/clear.svg?component'
import _ClientIcon from './icons/client.svg?component'
@@ -61,6 +65,7 @@ import _CubeIcon from './icons/cube.svg?component'
import _CurrencyIcon from './icons/currency.svg?component'
import _DashboardIcon from './icons/dashboard.svg?component'
import _DatabaseIcon from './icons/database.svg?component'
import _DatabaseBackupIcon from './icons/database-backup.svg?component'
import _DownloadIcon from './icons/download.svg?component'
import _DropdownIcon from './icons/dropdown.svg?component'
import _EditIcon from './icons/edit.svg?component'
@@ -73,11 +78,13 @@ import _FileIcon from './icons/file.svg?component'
import _FileArchiveIcon from './icons/file-archive.svg?component'
import _FileCodeIcon from './icons/file-code.svg?component'
import _FileImageIcon from './icons/file-image.svg?component'
import _FilePlusIcon from './icons/file-plus.svg?component'
import _FileTextIcon from './icons/file-text.svg?component'
import _FilterIcon from './icons/filter.svg?component'
import _FilterXIcon from './icons/filter-x.svg?component'
import _FolderIcon from './icons/folder.svg?component'
import _FolderArchiveIcon from './icons/folder-archive.svg?component'
import _FolderCogIcon from './icons/folder-cog.svg?component'
import _FolderOpenIcon from './icons/folder-open.svg?component'
import _FolderSearchIcon from './icons/folder-search.svg?component'
import _FolderUpIcon from './icons/folder-up.svg?component'
@@ -112,6 +119,7 @@ import _KeyIcon from './icons/key.svg?component'
import _KeyboardIcon from './icons/keyboard.svg?component'
import _LandmarkIcon from './icons/landmark.svg?component'
import _LanguagesIcon from './icons/languages.svg?component'
import _LayoutTemplateIcon from './icons/layout-template.svg?component'
import _LeftArrowIcon from './icons/left-arrow.svg?component'
import _LibraryIcon from './icons/library.svg?component'
import _LightBulbIcon from './icons/light-bulb.svg?component'
@@ -149,6 +157,7 @@ import _PackageIcon from './icons/package.svg?component'
import _PackageClosedIcon from './icons/package-closed.svg?component'
import _PackageOpenIcon from './icons/package-open.svg?component'
import _PaintbrushIcon from './icons/paintbrush.svg?component'
import _PaletteIcon from './icons/palette.svg?component'
import _PickaxeIcon from './icons/pickaxe.svg?component'
import _PlayIcon from './icons/play.svg?component'
import _PlugIcon from './icons/plug.svg?component'
@@ -232,26 +241,29 @@ export const AlignLeftIcon = _AlignLeftIcon
export const ArchiveIcon = _ArchiveIcon
export const ArrowBigRightDashIcon = _ArrowBigRightDashIcon
export const ArrowBigUpDashIcon = _ArrowBigUpDashIcon
export const ArrowDownLeftIcon = _ArrowDownLeftIcon
export const ArrowDownIcon = _ArrowDownIcon
export const ArrowDownLeftIcon = _ArrowDownLeftIcon
export const ArrowLeftIcon = _ArrowLeftIcon
export const ArrowLeftRightIcon = _ArrowLeftRightIcon
export const ArrowUpRightIcon = _ArrowUpRightIcon
export const ArrowUpIcon = _ArrowUpIcon
export const ArrowUpRightIcon = _ArrowUpRightIcon
export const AsteriskIcon = _AsteriskIcon
export const BadgeCheckIcon = _BadgeCheckIcon
export const BadgeDollarSignIcon = _BadgeDollarSignIcon
export const BanIcon = _BanIcon
export const BellRingIcon = _BellRingIcon
export const BellIcon = _BellIcon
export const BellRingIcon = _BellRingIcon
export const BlendIcon = _BlendIcon
export const BlocksIcon = _BlocksIcon
export const BoldIcon = _BoldIcon
export const BookIcon = _BookIcon
export const BookOpenIcon = _BookOpenIcon
export const BookTextIcon = _BookTextIcon
export const BookIcon = _BookIcon
export const BookmarkIcon = _BookmarkIcon
export const BotIcon = _BotIcon
export const BoxImportIcon = _BoxImportIcon
export const BoxIcon = _BoxIcon
export const BoxImportIcon = _BoxImportIcon
export const BoxesIcon = _BoxesIcon
export const BracesIcon = _BracesIcon
export const BrushCleaningIcon = _BrushCleaningIcon
export const BugIcon = _BugIcon
@@ -259,12 +271,13 @@ export const CalendarIcon = _CalendarIcon
export const CardIcon = _CardIcon
export const ChangeSkinIcon = _ChangeSkinIcon
export const ChartIcon = _ChartIcon
export const CheckIcon = _CheckIcon
export const CheckCheckIcon = _CheckCheckIcon
export const CheckCircleIcon = _CheckCircleIcon
export const CheckIcon = _CheckIcon
export const ChevronDownIcon = _ChevronDownIcon
export const ChevronLeftIcon = _ChevronLeftIcon
export const ChevronRightIcon = _ChevronRightIcon
export const ChevronUpIcon = _ChevronUpIcon
export const CircleUserIcon = _CircleUserIcon
export const ClearIcon = _ClearIcon
export const ClientIcon = _ClientIcon
@@ -287,25 +300,28 @@ export const CubeIcon = _CubeIcon
export const CurrencyIcon = _CurrencyIcon
export const DashboardIcon = _DashboardIcon
export const DatabaseIcon = _DatabaseIcon
export const DatabaseBackupIcon = _DatabaseBackupIcon
export const DownloadIcon = _DownloadIcon
export const DropdownIcon = _DropdownIcon
export const EditIcon = _EditIcon
export const EllipsisVerticalIcon = _EllipsisVerticalIcon
export const ExpandIcon = _ExpandIcon
export const ExternalIcon = _ExternalIcon
export const EyeOffIcon = _EyeOffIcon
export const EyeIcon = _EyeIcon
export const EyeOffIcon = _EyeOffIcon
export const FileIcon = _FileIcon
export const FileArchiveIcon = _FileArchiveIcon
export const FileCodeIcon = _FileCodeIcon
export const FileImageIcon = _FileImageIcon
export const FilePlusIcon = _FilePlusIcon
export const FileTextIcon = _FileTextIcon
export const FileIcon = _FileIcon
export const FilterXIcon = _FilterXIcon
export const FilterIcon = _FilterIcon
export const FilterXIcon = _FilterXIcon
export const FolderIcon = _FolderIcon
export const FolderArchiveIcon = _FolderArchiveIcon
export const FolderCogIcon = _FolderCogIcon
export const FolderOpenIcon = _FolderOpenIcon
export const FolderSearchIcon = _FolderSearchIcon
export const FolderIcon = _FolderIcon
export const FolderUpIcon = _FolderUpIcon
export const GameIcon = _GameIcon
export const GapIcon = _GapIcon
@@ -323,9 +339,9 @@ export const HashIcon = _HashIcon
export const Heading1Icon = _Heading1Icon
export const Heading2Icon = _Heading2Icon
export const Heading3Icon = _Heading3Icon
export const HeartIcon = _HeartIcon
export const HeartHandshakeIcon = _HeartHandshakeIcon
export const HeartMinusIcon = _HeartMinusIcon
export const HeartIcon = _HeartIcon
export const HistoryIcon = _HistoryIcon
export const HomeIcon = _HomeIcon
export const ImageIcon = _ImageIcon
@@ -338,19 +354,20 @@ export const KeyIcon = _KeyIcon
export const KeyboardIcon = _KeyboardIcon
export const LandmarkIcon = _LandmarkIcon
export const LanguagesIcon = _LanguagesIcon
export const LayoutTemplateIcon = _LayoutTemplateIcon
export const LeftArrowIcon = _LeftArrowIcon
export const LibraryIcon = _LibraryIcon
export const LightBulbIcon = _LightBulbIcon
export const LinkIcon = _LinkIcon
export const ListIcon = _ListIcon
export const ListBulletedIcon = _ListBulletedIcon
export const ListEndIcon = _ListEndIcon
export const ListFilterIcon = _ListFilterIcon
export const ListOrderedIcon = _ListOrderedIcon
export const ListIcon = _ListIcon
export const LoaderCircleIcon = _LoaderCircleIcon
export const LoaderIcon = _LoaderIcon
export const LockOpenIcon = _LockOpenIcon
export const LoaderCircleIcon = _LoaderCircleIcon
export const LockIcon = _LockIcon
export const LockOpenIcon = _LockOpenIcon
export const LogInIcon = _LogInIcon
export const LogOutIcon = _LogOutIcon
export const MailIcon = _MailIcon
@@ -361,8 +378,8 @@ export const MessageIcon = _MessageIcon
export const MicrophoneIcon = _MicrophoneIcon
export const MinimizeIcon = _MinimizeIcon
export const MinusIcon = _MinusIcon
export const MonitorSmartphoneIcon = _MonitorSmartphoneIcon
export const MonitorIcon = _MonitorIcon
export const MonitorSmartphoneIcon = _MonitorSmartphoneIcon
export const MoonIcon = _MoonIcon
export const MoreHorizontalIcon = _MoreHorizontalIcon
export const MoreVerticalIcon = _MoreVerticalIcon
@@ -371,16 +388,17 @@ export const NoSignalIcon = _NoSignalIcon
export const NotepadTextIcon = _NotepadTextIcon
export const OmorphiaIcon = _OmorphiaIcon
export const OrganizationIcon = _OrganizationIcon
export const PackageIcon = _PackageIcon
export const PackageClosedIcon = _PackageClosedIcon
export const PackageOpenIcon = _PackageOpenIcon
export const PackageIcon = _PackageIcon
export const PaintbrushIcon = _PaintbrushIcon
export const PaletteIcon = _PaletteIcon
export const PickaxeIcon = _PickaxeIcon
export const PlayIcon = _PlayIcon
export const PlugIcon = _PlugIcon
export const PlusIcon = _PlusIcon
export const RadioButtonCheckedIcon = _RadioButtonCheckedIcon
export const RadioButtonIcon = _RadioButtonIcon
export const RadioButtonCheckedIcon = _RadioButtonCheckedIcon
export const ReceiptTextIcon = _ReceiptTextIcon
export const RedoIcon = _RedoIcon
export const RefreshCwIcon = _RefreshCwIcon
@@ -397,13 +415,13 @@ export const ScaleIcon = _ScaleIcon
export const ScanEyeIcon = _ScanEyeIcon
export const SearchIcon = _SearchIcon
export const SendIcon = _SendIcon
export const ServerPlusIcon = _ServerPlusIcon
export const ServerIcon = _ServerIcon
export const ServerPlusIcon = _ServerPlusIcon
export const SettingsIcon = _SettingsIcon
export const ShareIcon = _ShareIcon
export const ShieldIcon = _ShieldIcon
export const ShieldAlertIcon = _ShieldAlertIcon
export const ShieldCheckIcon = _ShieldCheckIcon
export const ShieldIcon = _ShieldIcon
export const SignalIcon = _SignalIcon
export const SkullIcon = _SkullIcon
export const SlashIcon = _SlashIcon
@@ -430,25 +448,25 @@ export const TrashIcon = _TrashIcon
export const TriangleAlertIcon = _TriangleAlertIcon
export const UnderlineIcon = _UnderlineIcon
export const UndoIcon = _UndoIcon
export const UnknownDonationIcon = _UnknownDonationIcon
export const UnknownIcon = _UnknownIcon
export const UnknownDonationIcon = _UnknownDonationIcon
export const UnlinkIcon = _UnlinkIcon
export const UnplugIcon = _UnplugIcon
export const UpdatedIcon = _UpdatedIcon
export const UploadIcon = _UploadIcon
export const UserIcon = _UserIcon
export const UserCogIcon = _UserCogIcon
export const UserPlusIcon = _UserPlusIcon
export const UserRoundIcon = _UserRoundIcon
export const UserSearchIcon = _UserSearchIcon
export const UserXIcon = _UserXIcon
export const UserIcon = _UserIcon
export const UsersIcon = _UsersIcon
export const VersionIcon = _VersionIcon
export const WikiIcon = _WikiIcon
export const WindowIcon = _WindowIcon
export const WorldIcon = _WorldIcon
export const WrenchIcon = _WrenchIcon
export const XCircleIcon = _XCircleIcon
export const XIcon = _XIcon
export const XCircleIcon = _XCircleIcon
export const ZoomInIcon = _ZoomInIcon
export const ZoomOutIcon = _ZoomOutIcon

View File

@@ -0,0 +1,16 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-arrow-left"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="m12 19-7-7 7-7" />
<path d="M19 12H5" />
</svg>

After

Width:  |  Height:  |  Size: 344 B

View File

@@ -0,0 +1,16 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-blend"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="9" cy="9" r="7" />
<circle cx="15" cy="15" r="7" />
</svg>

After

Width:  |  Height:  |  Size: 353 B

View File

@@ -0,0 +1,26 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-boxes"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" />
<path d="m7 16.5-4.74-2.85" />
<path d="m7 16.5 5-3" />
<path d="M7 16.5v5.17" />
<path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" />
<path d="m17 16.5-5-3" />
<path d="m17 16.5 4.74-2.85" />
<path d="M17 16.5v5.17" />
<path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" />
<path d="M12 8 7.26 5.15" />
<path d="m12 8 4.74-2.85" />
<path d="M12 13.5V8" />
</svg>

After

Width:  |  Height:  |  Size: 901 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-chevron-up-icon lucide-chevron-up">
<path d="m18 15-6-6-6 6" />
</svg>

After

Width:  |  Height:  |  Size: 276 B

View File

@@ -0,0 +1,20 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-database-backup"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<ellipse cx="12" cy="5" rx="9" ry="3" />
<path d="M3 12a9 3 0 0 0 5 2.69" />
<path d="M21 9.3V5" />
<path d="M3 5v14a9 3 0 0 0 6.47 2.88" />
<path d="M12 12v4h4" />
<path d="M13 20a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5c-1.33 0-2.54.54-3.41 1.41L12 16" />
</svg>

After

Width:  |  Height:  |  Size: 560 B

View File

@@ -0,0 +1,18 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-file-plus"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" />
<path d="M14 2v5a1 1 0 0 0 1 1h5" />
<path d="M9 15h6" />
<path d="M12 18v-6" />
</svg>

After

Width:  |  Height:  |  Size: 502 B

View File

@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-folder-cog-icon lucide-folder-cog">
<path d="M10.3 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.98a2 2 0 0 1 1.69.9l.66 1.2A2 2 0 0 0 12 6h8a2 2 0 0 1 2 2v3.3" />
<path d="m14.305 19.53.923-.382" />
<path d="m15.228 16.852-.923-.383" />
<path d="m16.852 15.228-.383-.923" />
<path d="m16.852 20.772-.383.924" />
<path d="m19.148 15.228.383-.923" />
<path d="m19.53 21.696-.382-.924" />
<path d="m20.772 16.852.924-.383" />
<path d="m20.772 19.148.924.383" />
<circle cx="18" cy="18" r="3" />
</svg>

After

Width:  |  Height:  |  Size: 705 B

View File

@@ -0,0 +1,17 @@
<!-- @license lucide-static v0.562.0 - ISC -->
<svg
class="lucide lucide-layout-template"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="18" height="7" x="3" y="3" rx="1" />
<rect width="9" height="7" x="3" y="14" rx="1" />
<rect width="5" height="7" x="16" y="14" rx="1" />
</svg>

After

Width:  |  Height:  |  Size: 452 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-palette" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25" /><path d="M8.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12.5 7.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M16.5 10.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg>

After

Width:  |  Height:  |  Size: 619 B

View File

@@ -39,6 +39,7 @@ import _VenmoColorIcon from './external/color/venmo.svg?component'
import _CurseForgeIcon from './external/curseforge.svg?component'
import _DiscordIcon from './external/discord.svg?component'
import _FacebookIcon from './external/facebook.svg?component'
import _FlathubIcon from './external/flathub.svg?component'
import _GithubIcon from './external/github.svg?component'
import _MinecraftServerIcon from './external/illustrations/minecraft_server_icon.png?url'
import _InstagramIcon from './external/instagram.svg?component'
@@ -93,6 +94,7 @@ export const GithubIcon = _GithubIcon
export const CurseForgeIcon = _CurseForgeIcon
export const DiscordIcon = _DiscordIcon
export const FacebookIcon = _FacebookIcon
export const FlathubIcon = _FlathubIcon
export const InstagramIcon = _InstagramIcon
export const SnapchatIcon = _SnapchatIcon
export const ReelsIcon = _ReelsIcon

View File

@@ -7,13 +7,16 @@
"scripts": {
"lint": "pnpm run icons:validate && eslint . && prettier --check .",
"fix": "pnpm run icons:generate && eslint . --fix && prettier --write .",
"icons:add": "jiti build/add-icons.ts",
"icons:test": "jiti build/generate-exports.ts --test",
"icons:validate": "jiti build/generate-exports.ts --validate",
"icons:generate": "jiti build/generate-exports.ts"
},
"devDependencies": {
"@modrinth/tooling-config": "workspace:*",
"@types/node": "^20.1.0",
"jiti": "^2.4.2",
"lucide-static": "^0.562.0",
"vue": "^3.5.13"
}
}

View File

@@ -0,0 +1,211 @@
.ace-modrinth .ace_gutter {
background: var(--surface-2);
color: var(--color-text-tertiary);
}
.ace-modrinth .ace_print-margin {
width: 1px;
background: var(--surface-5);
}
.ace-modrinth {
background-color: var(--surface-3);
color: var(--color-text-default);
}
.ace-modrinth .ace_cursor {
color: var(--color-brand);
}
.ace-modrinth .ace_marker-layer .ace_selection {
background: var(--color-brand-highlight);
}
.ace-modrinth.ace_multiselect .ace_selection.ace_start {
box-shadow: 0 0 3px 0 var(--surface-3);
}
.ace-modrinth .ace_marker-layer .ace_step {
background: var(--color-orange-highlight);
}
.ace-modrinth .ace_marker-layer .ace_bracket {
margin: -1px 0 0 -1px;
border: 1px solid var(--color-brand);
}
.ace-modrinth .ace_marker-layer .ace_active-line {
background: var(--surface-4);
}
.ace-modrinth .ace_gutter-active-line {
background-color: var(--surface-1);
}
.ace-modrinth .ace_marker-layer .ace_selected-word {
border: 1px solid var(--color-brand-highlight);
}
.ace-modrinth .ace_invisible {
color: var(--color-text-tertiary);
opacity: 0.5;
}
.ace-modrinth .ace_fold {
background-color: var(--color-blue);
border-color: var(--color-text-default);
}
/* Comments */
.ace-modrinth .ace_comment {
color: var(--color-gray);
font-style: italic;
}
/* Strings */
.ace-modrinth .ace_string {
color: var(--color-green);
}
.ace-modrinth .ace_string.ace_regexp {
color: var(--color-orange);
}
/* Constants */
.ace-modrinth .ace_constant.ace_numeric {
color: var(--color-purple);
}
.ace-modrinth .ace_constant.ace_language {
color: var(--color-orange);
}
.ace-modrinth .ace_constant.ace_character {
color: var(--color-orange);
}
.ace-modrinth .ace_constant.ace_other {
color: var(--color-purple);
}
/* Keywords */
.ace-modrinth .ace_keyword {
color: var(--color-red);
}
.ace-modrinth .ace_keyword.ace_operator {
color: var(--color-text-default);
}
/* Storage */
.ace-modrinth .ace_storage {
color: var(--color-red);
}
.ace-modrinth .ace_storage.ace_type {
color: var(--color-blue);
}
/* Entity names */
.ace-modrinth .ace_entity.ace_name.ace_function {
color: var(--color-blue);
}
.ace-modrinth .ace_entity.ace_name.ace_class {
color: var(--color-purple);
}
.ace-modrinth .ace_entity.ace_name.ace_tag {
color: var(--color-red);
}
.ace-modrinth .ace_entity.ace_other.ace_attribute-name {
color: var(--color-orange);
}
/* Variables */
.ace-modrinth .ace_variable {
color: var(--color-text-default);
}
.ace-modrinth .ace_variable.ace_parameter {
color: var(--color-text-default);
font-style: italic;
}
.ace-modrinth .ace_variable.ace_language {
color: var(--color-orange);
}
/* Support */
.ace-modrinth .ace_support.ace_function {
color: var(--color-blue);
}
.ace-modrinth .ace_support.ace_class {
color: var(--color-purple);
}
.ace-modrinth .ace_support.ace_type {
color: var(--color-blue);
}
.ace-modrinth .ace_support.ace_constant {
color: var(--color-purple);
}
/* Invalid */
.ace-modrinth .ace_invalid {
color: var(--color-text-primary);
background-color: var(--color-red-bg);
}
.ace-modrinth .ace_invalid.ace_deprecated {
color: var(--color-text-primary);
background-color: var(--color-orange-bg);
}
/* Punctuation */
.ace-modrinth .ace_punctuation {
color: var(--color-text-tertiary);
}
/* Meta */
.ace-modrinth .ace_meta.ace_tag {
color: var(--color-text-default);
}
/* Markup */
.ace-modrinth .ace_markup.ace_heading {
color: var(--color-red);
font-weight: bold;
}
.ace-modrinth .ace_markup.ace_list {
color: var(--color-orange);
}
.ace-modrinth .ace_markup.ace_bold {
font-weight: bold;
}
.ace-modrinth .ace_markup.ace_italic {
font-style: italic;
}
.ace-modrinth .ace_markup.ace_underline {
text-decoration: underline;
}
/* Indent guide */
.ace-modrinth .ace_indent-guide {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC)
right repeat-y;
opacity: 0.2;
}
.ace-modrinth .ace_indent-guide-active {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC)
right repeat-y;
opacity: 0.4;
}

View File

@@ -46,13 +46,13 @@
}
> :where(
input + *,
.input-group + *,
.textarea-wrapper + *,
.chips + *,
.resizable-textarea-wrapper + *,
.input-div + *
) {
input + *,
.input-group + *,
.textarea-wrapper + *,
.chips + *,
.resizable-textarea-wrapper + *,
.input-div + *
) {
margin-block-start: var(--gap-md);
}

View File

@@ -7,8 +7,9 @@ body {
// Defaults
background-color: var(--color-bg);
color: var(--color-base);
--font-standard: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
--font-standard:
Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto, Cantarell,
Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
--mono-font: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
font-family: var(--font-standard);
font-size: 16px;
@@ -66,15 +67,6 @@ textarea,
border: none;
outline: none;
&:focus,
&:focus-visible {
box-shadow:
inset 0 0 0 transparent,
0 0 0 0.25rem var(--color-brand-shadow);
color: var(--color-contrast);
outline: none;
}
&:disabled,
&[disabled] {
opacity: 0.6;
@@ -94,6 +86,7 @@ textarea,
.cm-content {
white-space: pre-wrap !important;
box-shadow: none;
}
input[type='number'] {

View File

@@ -127,10 +127,12 @@
--shadow-inset-sm: inset 0px -1px 2px hsla(221, 39%, 91%, 0.15);
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
--shadow-raised: 0.3px 0.5px 0.6px hsl(var(--shadow-color) / 0.15),
--shadow-raised:
0.3px 0.5px 0.6px hsl(var(--shadow-color) / 0.15),
1px 2px 2.2px -1.7px hsl(var(--shadow-color) / 0.12),
4.4px 8.8px 9.7px -3.4px hsl(var(--shadow-color) / 0.09);
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
--shadow-floating:
hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, hsla(0, 0%, 0%, 0.1) 0px 2px 4px -1px;
--shadow-card: rgba(50, 50, 100, 0.1) 0px 2px 4px 0px;
@@ -348,7 +350,8 @@ html {
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
--shadow-raised: 0px -2px 4px hsla(221, 39%, 11%, 0.1);
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
--shadow-floating:
hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
--shadow-card: rgba(0, 0, 0, 0.25) 0px 2px 4px 0px;