├── .changeset ├── README.md └── config.json ├── .codesandbox └── tasks.json ├── .editorconfig ├── .eslintrc.js ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 1-bug-report.yml │ ├── 2-feature-request.yml │ └── 3-dev-infra-request.yml ├── PULL_REQUEST_TEMPLATE.md ├── actions │ ├── pnpm-install │ │ └── action.yml │ └── setup-job │ │ └── action.yml ├── stale.yml └── workflows │ ├── main.yml │ ├── prod-deploy.yml │ └── release.yml ├── .gitignore ├── .husky └── commit-msg ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── codegram.iml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── jsLinters │ └── eslint.xml ├── modules.xml ├── prettier.xml ├── vcs.xml └── watcherTasks.xml ├── .lintstagedrc ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .vscode ├── codeimage.code-workspace └── settings.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── apps ├── api │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── .taprc │ ├── CHANGELOG.md │ ├── README.md │ ├── api-types │ │ └── index.d.ts │ ├── docker-compose.dev.yml │ ├── nixpacks.toml │ ├── package.json │ ├── prisma │ │ ├── migrations │ │ │ ├── 20220807214414_init │ │ │ │ └── migration.sql │ │ │ ├── 20220813131834_add_user_email │ │ │ │ └── migration.sql │ │ │ ├── 20220819164911_delete_cascade_user │ │ │ │ └── migration.sql │ │ │ ├── 20220822084135_project_owner_rename_column │ │ │ │ └── migration.sql │ │ │ ├── 20230302182841_project_unique_owner_constraint_336_feature │ │ │ │ └── migration.sql │ │ │ ├── 20230302183231_editor_add_ligatures_option │ │ │ │ └── migration.sql │ │ │ ├── 20230304194315_preset │ │ │ │ └── migration.sql │ │ │ ├── 20230821142152_update_default_frame_radius │ │ │ │ └── migration.sql │ │ │ ├── 20231231115803_add_terminal_border_type_property │ │ │ │ └── migration.sql │ │ │ ├── 20240107110836_add_line_number_start │ │ │ │ └── migration.sql │ │ │ └── migration_lock.toml │ │ └── schema.prisma │ ├── src │ │ ├── app.ts │ │ ├── common │ │ │ ├── domainFunctions │ │ │ │ ├── builder.ts │ │ │ │ ├── functions.d.ts │ │ │ │ ├── handlers.test.ts │ │ │ │ ├── handlers.ts │ │ │ │ └── registry.ts │ │ │ ├── exceptions │ │ │ │ ├── HandlerError.ts │ │ │ │ ├── NotFoundEntityException.ts │ │ │ │ └── UnprocessableEntityException.ts │ │ │ ├── typebox │ │ │ │ ├── enum.ts │ │ │ │ └── nullable.ts │ │ │ └── types │ │ │ │ └── extract-api-types.ts │ │ ├── modules │ │ │ ├── preset │ │ │ │ ├── domain │ │ │ │ │ └── index.ts │ │ │ │ ├── exceptions │ │ │ │ │ ├── ExceedPresetLimitException.ts │ │ │ │ │ └── NotFoundPresetException.ts │ │ │ │ ├── handlers │ │ │ │ │ ├── create.ts │ │ │ │ │ ├── delete.ts │ │ │ │ │ ├── findAll.ts │ │ │ │ │ ├── findById.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── update.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mapper │ │ │ │ │ └── index.ts │ │ │ │ ├── repository │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── preset.repository.ts │ │ │ │ │ └── prisma-preset.repository.ts │ │ │ │ └── schema │ │ │ │ │ ├── preset-create-dto.schema.ts │ │ │ │ │ ├── preset-dto.schema.ts │ │ │ │ │ └── preset-update-dto.schema.ts │ │ │ └── project │ │ │ │ ├── domain │ │ │ │ ├── index.ts │ │ │ │ ├── projectCreateRequest.ts │ │ │ │ ├── projectGetByIdResponse.ts │ │ │ │ └── projectUpdateRequest.ts │ │ │ │ ├── handlers │ │ │ │ └── project.service.ts │ │ │ │ ├── index.ts │ │ │ │ ├── infra │ │ │ │ └── prisma │ │ │ │ │ └── prisma-project.repository.ts │ │ │ │ ├── mapper │ │ │ │ ├── create-project-mapper.ts │ │ │ │ └── get-project-by-id-mapper.ts │ │ │ │ ├── repository │ │ │ │ ├── index.ts │ │ │ │ └── project.repository.ts │ │ │ │ └── schema │ │ │ │ ├── index.ts │ │ │ │ ├── project-create.schema.ts │ │ │ │ ├── project-delete.schema.ts │ │ │ │ ├── project-get-by-id.schema.ts │ │ │ │ ├── project-update.schema.ts │ │ │ │ └── project.schema.ts │ │ ├── plugins │ │ │ ├── auth0.ts │ │ │ ├── cors.ts │ │ │ ├── errorHandler.ts │ │ │ ├── handler.ts │ │ │ ├── healthcheck.ts │ │ │ ├── prisma.ts │ │ │ ├── sensible.ts │ │ │ └── swagger.ts │ │ ├── routes │ │ │ └── v1 │ │ │ │ ├── preset │ │ │ │ ├── create.ts │ │ │ │ ├── delete.ts │ │ │ │ ├── getAll.ts │ │ │ │ ├── getById.ts │ │ │ │ └── update.ts │ │ │ │ └── project │ │ │ │ ├── clone.ts │ │ │ │ ├── create.ts │ │ │ │ ├── delete.ts │ │ │ │ ├── getAllByUserId.ts │ │ │ │ ├── getById.ts │ │ │ │ ├── update.ts │ │ │ │ └── updateName.ts │ │ ├── schemas │ │ │ └── index.ts │ │ └── server.ts │ ├── test │ │ ├── __internal__ │ │ │ └── presetUtils.ts │ │ ├── common │ │ │ └── domainFunctions │ │ │ │ └── builder.test.ts │ │ ├── helper.ts │ │ ├── helpers │ │ │ ├── auth0Mock.ts │ │ │ └── seed.ts │ │ ├── modules │ │ │ ├── preset │ │ │ │ ├── data-utils.ts │ │ │ │ ├── handlers │ │ │ │ │ ├── create.test.ts │ │ │ │ │ ├── dependencies.ts │ │ │ │ │ ├── findById.test.ts │ │ │ │ │ └── getAll.test.ts │ │ │ │ └── mapper │ │ │ │ │ └── presetMapper.test.ts │ │ │ └── project │ │ │ │ ├── mapper │ │ │ │ ├── create-project-mapper.test.ts │ │ │ │ └── get-project-by-id-mapper.test.ts │ │ │ │ └── service │ │ │ │ └── project.service.test.ts │ │ ├── plugins │ │ │ ├── auth0.test.ts │ │ │ └── cors.test.ts │ │ ├── routes │ │ │ └── v1 │ │ │ │ ├── preset │ │ │ │ ├── create.integration.test.ts │ │ │ │ ├── delete.integration.test.ts │ │ │ │ ├── getAll.integration.test.ts │ │ │ │ ├── getById.integration.test.ts │ │ │ │ └── update.integration.test.ts │ │ │ │ └── project │ │ │ │ ├── clone.integration.test.ts │ │ │ │ ├── create.integration.test.ts │ │ │ │ ├── delete.integration.test.ts │ │ │ │ ├── getAllByUserId.integration.test.ts │ │ │ │ ├── getById.integration.test.ts │ │ │ │ ├── update.integration.test.ts │ │ │ │ └── updateName.integration.test.ts │ │ ├── setup-integration.ts │ │ ├── setup-unit.ts │ │ └── tsconfig.json │ ├── tsconfig.dts.json │ ├── tsconfig.json │ ├── tsconfig.schema.json │ ├── tsup.config.ts │ └── vitest.config.ts ├── codeimage │ ├── .eslintignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── changelog │ │ ├── 1-4-0_08-08-2023.mdx │ │ ├── 1-4-3_11-08-2023.mdx │ │ ├── 1-5-0_12-09-2023.mdx │ │ ├── 1-6-0_04-27-2024.mdx │ │ ├── 1-7-0_06-29-2024.mdx │ │ ├── 1-8-4_12-23-2024.mdx │ │ ├── 1-9-0_02-02-2025.mdx │ │ └── data │ │ │ ├── 1-5-0 │ │ │ ├── constant.ts │ │ │ ├── font-picker.mp4 │ │ │ ├── window-style.mp4 │ │ │ └── xcode-theme.mp4 │ │ │ ├── 1-6-0 │ │ │ ├── new-border-option.mp4 │ │ │ └── starting-line-number.mp4 │ │ │ ├── 1-7-0 │ │ │ └── shareable_presets.png │ │ │ └── 1-9-0 │ │ │ └── export-active-tab.png │ ├── index.html │ ├── package.json │ ├── public │ │ ├── assets │ │ │ ├── blank.html │ │ │ ├── codeimage-logo-blue-svg-v1.svg │ │ │ ├── codeimage-logo-white.svg │ │ │ ├── favicon.ico │ │ │ ├── favicon.svg │ │ │ └── fonts │ │ │ │ ├── IBM_Plex_Mono │ │ │ │ ├── IBMPlexMono-Bold.ttf │ │ │ │ ├── IBMPlexMono-BoldItalic.ttf │ │ │ │ ├── IBMPlexMono-ExtraLight.ttf │ │ │ │ ├── IBMPlexMono-ExtraLightItalic.ttf │ │ │ │ ├── IBMPlexMono-Italic.ttf │ │ │ │ ├── IBMPlexMono-Light.ttf │ │ │ │ ├── IBMPlexMono-LightItalic.ttf │ │ │ │ ├── IBMPlexMono-Medium.ttf │ │ │ │ ├── IBMPlexMono-MediumItalic.ttf │ │ │ │ ├── IBMPlexMono-Regular.ttf │ │ │ │ ├── IBMPlexMono-SemiBold.ttf │ │ │ │ ├── IBMPlexMono-SemiBoldItalic.ttf │ │ │ │ ├── IBMPlexMono-Thin.ttf │ │ │ │ ├── IBMPlexMono-ThinItalic.ttf │ │ │ │ └── OFL.txt │ │ │ │ ├── agave │ │ │ │ └── Agave-Regular.ttf │ │ │ │ ├── geist_mono │ │ │ │ └── GeistMono[wght].ttf │ │ │ │ └── monaspace │ │ │ │ ├── MonaspaceArgonVarVF[wght,wdth,slnt].ttf │ │ │ │ ├── MonaspaceKryptonVarVF[wght,wdth,slnt].ttf │ │ │ │ ├── MonaspaceNeonVarVF[wght,wdth,slnt].ttf │ │ │ │ ├── MonaspaceRadonVarVF[wght,wdth,slnt].ttf │ │ │ │ └── MonaspaceXenonVarVF[wght,wdth,slnt].ttf │ │ ├── mockServiceWorker.js │ │ ├── pwa │ │ │ ├── apple-icon-180.png │ │ │ ├── manifest-icon-192.maskable.png │ │ │ └── manifest-icon-512.maskable.png │ │ └── sitemap.xml │ ├── src │ │ ├── assets │ │ │ ├── apple-icon-180.png │ │ │ ├── codeimage-card.png │ │ │ ├── codeimage-logo.svg │ │ │ ├── favicon.svg │ │ │ ├── logo-white.svg │ │ │ └── styles │ │ │ │ ├── _inter.scss │ │ │ │ ├── _reset.scss │ │ │ │ └── app.scss │ │ ├── client.d.ts │ │ ├── components │ │ │ ├── BottomBar │ │ │ │ ├── BottomBar.css.ts │ │ │ │ └── BottomBar.tsx │ │ │ ├── Changelog │ │ │ │ ├── Changelog.css.ts │ │ │ │ ├── Changelog.tsx │ │ │ │ ├── ChangelogItem.css.ts │ │ │ │ ├── ChangelogItem.tsx │ │ │ │ └── resolveChangelog.ts │ │ │ ├── CustomEditor │ │ │ │ ├── CanvasEditor.tsx │ │ │ │ ├── CustomEditor.tsx │ │ │ │ ├── CustomEditorPreview.tsx │ │ │ │ └── PreviewExportEditor.tsx │ │ │ ├── FeatureBadge │ │ │ │ ├── FeatureBadge.css.ts │ │ │ │ ├── FeatureBadge.tsx │ │ │ │ ├── FeatureCheckBanner.tsx │ │ │ │ ├── UnsupportedFeatureBanner.css.ts │ │ │ │ ├── browserSvgs │ │ │ │ │ ├── chrome.png │ │ │ │ │ ├── edge.png │ │ │ │ │ ├── firefox.png │ │ │ │ │ ├── opera.png │ │ │ │ │ └── safari.svg │ │ │ │ └── compatibility │ │ │ │ │ ├── api.ts │ │ │ │ │ └── types.ts │ │ │ ├── Footer │ │ │ │ ├── Footer.css.ts │ │ │ │ └── Footer.tsx │ │ │ ├── Frame │ │ │ │ ├── Frame.css.ts │ │ │ │ ├── Frame.tsx │ │ │ │ ├── FrameHandler.css.ts │ │ │ │ ├── FrameHandler.tsx │ │ │ │ ├── FrameSkeleton.css.ts │ │ │ │ ├── FrameSkeleton.tsx │ │ │ │ ├── ManagedFrame.tsx │ │ │ │ └── PreviewFrame.tsx │ │ │ ├── Icons │ │ │ │ ├── CheckCircle.tsx │ │ │ │ ├── Clipboard.tsx │ │ │ │ ├── CloseIcon.tsx │ │ │ │ ├── CloudIcon.tsx │ │ │ │ ├── Code.tsx │ │ │ │ ├── CodeImageLogo.tsx │ │ │ │ ├── CodeImageLogoV2.tsx │ │ │ │ ├── Collection.tsx │ │ │ │ ├── ColorSwatch.tsx │ │ │ │ ├── DotVertical.tsx │ │ │ │ ├── Download.tsx │ │ │ │ ├── EmptyBox.tsx │ │ │ │ ├── EmptyCircle.tsx │ │ │ │ ├── Exclamation.tsx │ │ │ │ ├── ExternalLink.tsx │ │ │ │ ├── Folder.tsx │ │ │ │ ├── Hint.tsx │ │ │ │ ├── Pencil.tsx │ │ │ │ ├── PlusIcon.tsx │ │ │ │ ├── SettingsIcon.tsx │ │ │ │ ├── ShareIcon.tsx │ │ │ │ └── SparklesIcon.tsx │ │ │ ├── KeyboardShortcuts │ │ │ │ ├── KeyboardShortcuts.css.ts │ │ │ │ └── KeyboardShortcuts.tsx │ │ │ ├── LoadingOverlay │ │ │ │ └── Skeleton.tsx │ │ │ ├── Presets │ │ │ │ ├── EmptyPresetFallback │ │ │ │ │ ├── EmptyPresetFallback.css.ts │ │ │ │ │ └── EmptyPresetFallback.tsx │ │ │ │ ├── PresetPreview │ │ │ │ │ └── PresetPreview.tsx │ │ │ │ ├── PresetSwitcher │ │ │ │ │ ├── PresetSwitcher.css.ts │ │ │ │ │ ├── PresetSwitcher.tsx │ │ │ │ │ └── PresetTooltipContent.tsx │ │ │ │ └── PresetUpdateDialog.tsx │ │ │ ├── PropertyEditor │ │ │ │ ├── EditorForm.tsx │ │ │ │ ├── EditorSidebar.css.ts │ │ │ │ ├── EditorSidebar.tsx │ │ │ │ ├── EditorStyleForm.tsx │ │ │ │ ├── FrameStyleForm.tsx │ │ │ │ ├── PanelDivider.tsx │ │ │ │ ├── PanelHeader.tsx │ │ │ │ ├── PanelRow.tsx │ │ │ │ ├── SidebarPopover │ │ │ │ │ ├── SidebarPopover.css.ts │ │ │ │ │ ├── SidebarPopover.tsx │ │ │ │ │ └── SidebarPopoverTitle.tsx │ │ │ │ ├── SidebarPopoverHost.css.ts │ │ │ │ ├── SidebarPopoverHost.tsx │ │ │ │ ├── SuspenseEditorItem.tsx │ │ │ │ ├── WindowStyleForm.tsx │ │ │ │ └── controls │ │ │ │ │ ├── AspectRatioPicker │ │ │ │ │ ├── AspectRatioPicker.tsx │ │ │ │ │ └── AspetRatioPicker.css.ts │ │ │ │ │ ├── ColorPicker │ │ │ │ │ ├── ColorPicker.tsx │ │ │ │ │ ├── ColorPickerPresetItem.tsx │ │ │ │ │ ├── CustomColorPicker.css.ts │ │ │ │ │ └── CustomColorPicker.tsx │ │ │ │ │ ├── FontPicker │ │ │ │ │ ├── FontPicker.css.ts │ │ │ │ │ ├── FontPicker.tsx │ │ │ │ │ ├── FontPickerListbox.tsx │ │ │ │ │ └── FontSystemPicker.tsx │ │ │ │ │ ├── ImagePicker │ │ │ │ │ ├── ImagePicker.css.ts │ │ │ │ │ ├── ImagePicker.tsx │ │ │ │ │ ├── ImagePickerInput.tsx │ │ │ │ │ └── ImagePickerList.tsx │ │ │ │ │ └── TerminalControlField │ │ │ │ │ ├── TerminalControlField.css.ts │ │ │ │ │ ├── TerminalControlField.tsx │ │ │ │ │ ├── TerminalControlFieldSkeleton.css.ts │ │ │ │ │ └── TerminalControlFieldSkeleton.tsx │ │ │ ├── Scaffold │ │ │ │ ├── Canvas │ │ │ │ │ ├── Canvas.css.ts │ │ │ │ │ └── Canvas.tsx │ │ │ │ ├── Scaffold.css.ts │ │ │ │ ├── Scaffold.tsx │ │ │ │ └── Sidebar │ │ │ │ │ ├── Sidebar.css.ts │ │ │ │ │ └── Sidebar.tsx │ │ │ ├── Terminal │ │ │ │ ├── DynamicTerminal │ │ │ │ │ └── DynamicTerminal.tsx │ │ │ │ ├── GlassReflection │ │ │ │ │ ├── TerminalGlassReflection.css.ts │ │ │ │ │ └── TerminalGlassReflection.tsx │ │ │ │ ├── MacOsTerminal │ │ │ │ │ ├── MacOsTerminal.css.ts │ │ │ │ │ ├── MacOsTerminal.tsx │ │ │ │ │ ├── MacOsTerminalGrayTheme.tsx │ │ │ │ │ └── MacOsTerminalOutlineTheme.tsx │ │ │ │ ├── Tabs │ │ │ │ │ ├── Tab │ │ │ │ │ │ ├── DraggableWindowTab.tsx │ │ │ │ │ │ ├── Tab.css.ts │ │ │ │ │ │ └── WindowTab.tsx │ │ │ │ │ ├── TabAddButton │ │ │ │ │ │ ├── TabAddButton.css.ts │ │ │ │ │ │ └── TabAddButton.tsx │ │ │ │ │ ├── TabIcon │ │ │ │ │ │ ├── TabIcon.css.ts │ │ │ │ │ │ └── TabIcon.tsx │ │ │ │ │ ├── TabName │ │ │ │ │ │ ├── TabName.css.ts │ │ │ │ │ │ └── TabName.tsx │ │ │ │ │ ├── TerminalWindowTabList.tsx │ │ │ │ │ ├── TerminalWindowTabListPreview.tsx │ │ │ │ │ └── createTabTheme.ts │ │ │ │ ├── TerminalHost.tsx │ │ │ │ ├── WindowsTerminal │ │ │ │ │ ├── WindowsTerminal.css.ts │ │ │ │ │ ├── WindowsTerminal.tsx │ │ │ │ │ └── WindowsTerminalControls.tsx │ │ │ │ └── terminal.css.ts │ │ │ ├── ThemeSwitcher │ │ │ │ ├── ThemeBox.tsx │ │ │ │ ├── ThemeBoxSkeleton.css.ts │ │ │ │ ├── ThemeBoxSkeleton.tsx │ │ │ │ ├── ThemeSwitcher.css.ts │ │ │ │ └── ThemeSwitcher.tsx │ │ │ ├── Toolbar │ │ │ │ ├── CopyToClipboardButton.tsx │ │ │ │ ├── ExportButton.tsx │ │ │ │ ├── ExportContent.css.ts │ │ │ │ ├── ExportContent.tsx │ │ │ │ ├── ExportNewTabButton.tsx │ │ │ │ ├── ExportSettingsButton.tsx │ │ │ │ ├── FrameToolbar.css.ts │ │ │ │ ├── FrameToolbar.tsx │ │ │ │ ├── GenerateLinkButton.tsx │ │ │ │ ├── SettingsDialog.css.ts │ │ │ │ ├── SettingsDialog.tsx │ │ │ │ ├── ShareButton.tsx │ │ │ │ ├── Toolbar.css.ts │ │ │ │ ├── Toolbar.tsx │ │ │ │ ├── ToolbarSettings.tsx │ │ │ │ └── ToolbarSnippetName.tsx │ │ │ └── UserBadge │ │ │ │ ├── UserBadge.css.ts │ │ │ │ └── UserBadge.tsx │ │ ├── core │ │ │ ├── configuration.ts │ │ │ ├── configuration │ │ │ │ ├── font.ts │ │ │ │ ├── shadow.ts │ │ │ │ └── terminal-themes.ts │ │ │ ├── constants │ │ │ │ ├── auth0.ts │ │ │ │ ├── auth0Mock.ts │ │ │ │ ├── identity.ts │ │ │ │ ├── non-nullable.ts │ │ │ │ ├── noop.ts │ │ │ │ └── umami.ts │ │ │ ├── directives │ │ │ │ ├── clickOutside.ts │ │ │ │ ├── exportExclude.ts │ │ │ │ └── highlight.ts │ │ │ ├── helpers │ │ │ │ ├── aspectRatio.ts │ │ │ │ ├── create-ref.ts │ │ │ │ ├── date.ts │ │ │ │ ├── getScale.ts │ │ │ │ ├── mapToDictionary.ts │ │ │ │ └── string.ts │ │ │ ├── hooks │ │ │ │ ├── async-action.ts │ │ │ │ ├── createControlledDialog.ts │ │ │ │ ├── createPlatformProps.ts │ │ │ │ ├── isMobile.tsx │ │ │ │ ├── resizable.ts │ │ │ │ └── use-webshare.tsx │ │ │ ├── modules │ │ │ │ ├── dnd │ │ │ │ │ ├── ConstrainDragAxis.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ └── localFontAccessApi │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── font.ts │ │ │ │ │ └── fontMetrics.ts │ │ │ └── operators │ │ │ │ ├── create-mutation-observer.ts │ │ │ │ ├── create-resize-observer.ts │ │ │ │ └── selectSlice.ts │ │ ├── data-access │ │ │ ├── api.ts │ │ │ ├── client.ts │ │ │ ├── preset.ts │ │ │ └── project.ts │ │ ├── hooks │ │ │ ├── createPrettierFormatter.ts │ │ │ ├── export-snippet.ts │ │ │ ├── use-export-image.ts │ │ │ ├── use-hotkey.ts │ │ │ ├── use-indexed-db.tsx │ │ │ ├── use-local-fonts.ts │ │ │ └── use-tab-icon.ts │ │ ├── i18n │ │ │ ├── notFound.ts │ │ │ ├── bottombar.ts │ │ │ ├── dashboard.ts │ │ │ ├── index.ts │ │ │ ├── presets.ts │ │ │ ├── sidebar.ts │ │ │ └── ui.ts │ │ ├── index.tsx │ │ ├── mdx │ │ │ ├── Video.tsx │ │ │ ├── components.css.ts │ │ │ └── components.tsx │ │ ├── mocks │ │ │ ├── browser.ts │ │ │ ├── db.ts │ │ │ ├── persist.ts │ │ │ └── projectMockHandlers.ts │ │ ├── pages │ │ │ ├── Dashboard │ │ │ │ ├── Dashboard.css.ts │ │ │ │ ├── Dashboard.tsx │ │ │ │ ├── components │ │ │ │ │ ├── CreateNewProjectButton │ │ │ │ │ │ └── CreateNewProjectButton.tsx │ │ │ │ │ ├── DashboardHeader │ │ │ │ │ │ ├── DashboardHeader.css.ts │ │ │ │ │ │ └── DashboardHeader.tsx │ │ │ │ │ ├── ProjectItem │ │ │ │ │ │ ├── ProjectItem.css.ts │ │ │ │ │ │ └── ProjectItem.tsx │ │ │ │ │ ├── ProjectItemSkeleton │ │ │ │ │ │ ├── ProjectItemSkeleton.css.ts │ │ │ │ │ │ └── ProjectItemSkeleton.tsx │ │ │ │ │ ├── ProjectList │ │ │ │ │ │ ├── ProjectEmptyListMessage.tsx │ │ │ │ │ │ ├── ProjectErrorListFallback.tsx │ │ │ │ │ │ ├── ProjectList.css.ts │ │ │ │ │ │ └── ProjectList.tsx │ │ │ │ │ └── ProjectToolbar │ │ │ │ │ │ ├── ProjectToolbar.css.ts │ │ │ │ │ │ └── ProjectToolbar.tsx │ │ │ │ └── dashboard.state.ts │ │ │ ├── Editor │ │ │ │ ├── App.css.ts │ │ │ │ ├── App.tsx │ │ │ │ ├── Editor.tsx │ │ │ │ └── components │ │ │ │ │ ├── EditorReadOnlyBanner.css.ts │ │ │ │ │ ├── EditorReadOnlyBanner.tsx │ │ │ │ │ ├── EditorSkeleton.tsx │ │ │ │ │ └── LeftSidebar.tsx │ │ │ └── NotFound │ │ │ │ ├── NotFoundPage.css.ts │ │ │ │ └── NotFoundPage.tsx │ │ ├── state │ │ │ ├── assets │ │ │ │ ├── AssetsImage.tsx │ │ │ │ └── assets.ts │ │ │ ├── auth │ │ │ │ └── auth0.ts │ │ │ ├── canvas.ts │ │ │ ├── editor │ │ │ │ ├── activeEditor.ts │ │ │ │ ├── config.store.ts │ │ │ │ ├── config │ │ │ │ │ └── localFont.ts │ │ │ │ ├── createEditorSync.ts │ │ │ │ ├── editor.ts │ │ │ │ ├── frame.ts │ │ │ │ ├── index.ts │ │ │ │ ├── model.ts │ │ │ │ └── terminal.ts │ │ │ ├── effects │ │ │ │ ├── onCopyToClipboard.tsx │ │ │ │ └── onThemeChange.tsx │ │ │ ├── frame │ │ │ │ └── model.ts │ │ │ ├── index.ts │ │ │ ├── plugins │ │ │ │ ├── bindStateBuilderResource.ts │ │ │ │ ├── local-storage.ts │ │ │ │ ├── unique-id.ts │ │ │ │ ├── withEntityPlugin.ts │ │ │ │ └── withIndexedDbPlugin.ts │ │ │ ├── presets │ │ │ │ ├── bridge.ts │ │ │ │ ├── presets.ts │ │ │ │ └── types.ts │ │ │ ├── theme │ │ │ │ ├── theme.store.ts │ │ │ │ ├── themeRegistry.ts │ │ │ │ └── useFilteredThemes.tsx │ │ │ ├── ui.ts │ │ │ └── version │ │ │ │ └── version.store.ts │ │ ├── sw.ts │ │ ├── theme │ │ │ └── global.css.ts │ │ ├── ui │ │ │ ├── Alert │ │ │ │ ├── Alert.css.ts │ │ │ │ └── Alert.tsx │ │ │ ├── ConfirmDialog │ │ │ │ ├── ConfirmDialog.tsx │ │ │ │ └── RenameContentDialog.tsx │ │ │ ├── DynamicSizedContainer │ │ │ │ └── DynamicSizedContainer.tsx │ │ │ ├── ExperimentalChip │ │ │ │ ├── ExperimentalChip.css.ts │ │ │ │ └── ExperimentalChip.tsx │ │ │ ├── ExperimentalFeatureTooltip │ │ │ │ ├── ExperimentalFeatureTooltip.css.ts │ │ │ │ └── ExperimentalFeatureTooltip.tsx │ │ │ ├── GitHubLoginButton │ │ │ │ ├── GitHubLoginButton.css.ts │ │ │ │ └── GitHubLoginButton.tsx │ │ │ ├── SegmentedField │ │ │ │ └── SegmentedField.tsx │ │ │ ├── Skeleton │ │ │ │ ├── Skeleton.css.ts │ │ │ │ ├── Skeleton.tsx │ │ │ │ └── SkeletonDivider.tsx │ │ │ └── snackbarHostAppStyle.css.ts │ │ └── umami.d.ts │ ├── tsconfig.json │ ├── vercel.json │ └── vite.config.ts └── website │ ├── .gitignore │ ├── .lighthouserc.json │ ├── CHANGELOG.md │ ├── README.md │ ├── add-css-stylesheet.ts │ ├── extract-static-css.ts │ ├── package.json │ ├── public │ ├── apple-touch-icon.png │ ├── brand │ │ ├── codeimage-logo-blue-svg-v1.svg │ │ └── codeimage_logo_final.png │ ├── example-codeimage.png │ ├── favicon-192x192.png │ ├── favicon-512x512.png │ ├── favicon.ico │ ├── favicon.svg │ ├── fonts │ │ ├── Mona-Sans-Bold.woff2 │ │ ├── Mona-Sans-Medium.woff2 │ │ ├── Mona-Sans-Regular.woff2 │ │ ├── Mona-Sans-SemiBold.woff2 │ │ └── Mona-Sans.woff2 │ ├── github-logo.svg │ ├── img.png │ ├── landing │ │ ├── codeimage_preview.png │ │ ├── codeimage_preview_desktop.webp │ │ ├── codeimage_preview_lite.png │ │ ├── codeimage_preview_mobile.webp │ │ └── codeimage_preview_mobile_ultra.webp │ ├── manifest.webmanifest │ ├── projects-showcase.png │ ├── projects-showcase.webp │ └── sitemap.xml │ ├── src │ ├── components │ │ ├── CodeImageLogo │ │ │ ├── CodeImageLogo.tsx │ │ │ ├── CodeImageLogoSvg.tsx │ │ │ ├── codeimage-logo-blue-low-v1.png │ │ │ └── codeimage-logo-blue-xxxs.webp │ │ ├── FeatureCard │ │ │ ├── FeatureCard.css.ts │ │ │ └── FeatureCard.tsx │ │ ├── Footer │ │ │ ├── Footer.css.ts │ │ │ └── Footer.tsx │ │ ├── GitHubButton │ │ │ ├── GitHubButton.css.ts │ │ │ └── GitHubButton.tsx │ │ ├── Header │ │ │ ├── Header.css.ts │ │ │ └── Header.tsx │ │ ├── Landing │ │ │ ├── ComingSoon │ │ │ │ ├── ComingSoon.css.ts │ │ │ │ └── ComingSoon.tsx │ │ │ ├── EditorSteps │ │ │ │ ├── CodeEditor │ │ │ │ │ ├── CodeEditor.css.ts │ │ │ │ │ ├── CodeEditor.tsx │ │ │ │ │ ├── CodeEditorPreviewBlock.tsx │ │ │ │ │ ├── editor-core.ts │ │ │ │ │ ├── editor-theme.ts │ │ │ │ │ └── lang-javascript-plugin.ts │ │ │ │ ├── EditorScene │ │ │ │ │ ├── CircularProgress │ │ │ │ │ │ ├── CircularProgress.css.ts │ │ │ │ │ │ └── CircularProgress.tsx │ │ │ │ │ ├── DynamicBackgroundExpansion │ │ │ │ │ │ ├── DynamicBackgroundExpansion.css.ts │ │ │ │ │ │ └── DynamicBackgroundExpansion.tsx │ │ │ │ │ ├── EditorScene.css.ts │ │ │ │ │ ├── EditorScene.tsx │ │ │ │ │ ├── GlassReflection │ │ │ │ │ │ ├── TerminalGlassReflection.css.ts │ │ │ │ │ │ └── TerminalGlassReflection.tsx │ │ │ │ │ ├── ScrollDownMouse │ │ │ │ │ │ ├── ScrollDownMouse.css.ts │ │ │ │ │ │ └── ScrollDownMouse.tsx │ │ │ │ │ ├── Snippet.css.ts │ │ │ │ │ ├── SnippetControls │ │ │ │ │ │ ├── SnippetControls.css.ts │ │ │ │ │ │ └── SnippetControls.tsx │ │ │ │ │ └── TwitterCard │ │ │ │ │ │ ├── TwitterCard.css.ts │ │ │ │ │ │ └── TwitterCard.tsx │ │ │ │ ├── EditorSteps.css.ts │ │ │ │ ├── EditorSteps.tsx │ │ │ │ ├── StepCard │ │ │ │ │ ├── StepCard.css.ts │ │ │ │ │ └── StepCard.tsx │ │ │ │ ├── StepCardScene │ │ │ │ │ ├── StepCardScene.css.ts │ │ │ │ │ └── StepCardScene.tsx │ │ │ │ └── scene.tsx │ │ │ ├── OpenSource │ │ │ │ ├── OpenSource.css.ts │ │ │ │ └── OpenSource.tsx │ │ │ ├── Projects │ │ │ │ ├── Projects.css.ts │ │ │ │ └── Projects.tsx │ │ │ └── Showcase │ │ │ │ ├── Showcase.css.ts │ │ │ │ └── Showcase.tsx │ │ ├── Main │ │ │ ├── MainPage.css.ts │ │ │ └── MainPage.tsx │ │ └── Umami │ │ │ └── UmamiScript.tsx │ ├── core │ │ ├── constants.ts │ │ ├── hydration │ │ │ ├── CustomHydratable.tsx │ │ │ ├── createHydratable.tsx │ │ │ ├── createHydration.ts │ │ │ ├── schedule.ts │ │ │ └── strategy.ts │ │ └── object.ts │ ├── entry-client.tsx │ ├── entry-server.tsx │ ├── root.tsx │ ├── routes │ │ └── index.tsx │ ├── theme │ │ ├── breakpoints.ts │ │ ├── gradients.css.ts │ │ ├── responsive.ts │ │ ├── root.css.ts │ │ ├── supportLch.ts │ │ └── theme.css.ts │ └── ui.ts │ ├── tsconfig.json │ ├── vercel-build-output.ts │ └── vite.config.ts ├── assets ├── banner.png ├── codeimage_card.png ├── codesandbox_fork.png ├── dependency_graph.png ├── jetbrains.svg └── showcase_1.png ├── banner.png ├── codeimage-logo-black.png ├── codeimage-logo-white.png ├── commitlint.config.js ├── package.json ├── packages ├── atomic-state │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── createDerivedObservable.ts │ │ ├── createDerivedSetter.ts │ │ ├── createStore.ts │ │ ├── createStoreSetters.ts │ │ ├── createTrackObserver.ts │ │ ├── experimental │ │ │ ├── effects │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── store-types.ts │ │ ├── getStoreInternals.ts │ │ └── index.tsx │ ├── tsconfig.dts.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── vitest.config.ts ├── config │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── .lintstagedrc │ │ ├── lib │ │ │ ├── base │ │ │ │ ├── aspectRatio.ts │ │ │ │ ├── colors.ts │ │ │ │ ├── languages.ts │ │ │ │ └── locales.ts │ │ │ ├── core │ │ │ │ └── createConfiguration.ts │ │ │ ├── icons │ │ │ │ ├── css.svg │ │ │ │ └── txt.svg │ │ │ └── types │ │ │ │ ├── configuration.ts │ │ │ │ ├── language-def.ts │ │ │ │ └── terminal-def.ts │ │ └── public-api.ts │ ├── tsconfig.dts.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── vite.config.ts ├── dom-export │ ├── .eslintignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── lib │ │ │ ├── applyStyleFromOptions.ts │ │ │ ├── cloneNode.ts │ │ │ ├── clonePseudoElements.ts │ │ │ ├── cloneSafe.ts │ │ │ ├── cloneStyle.ts │ │ │ ├── dataurl.ts │ │ │ ├── embedImages.ts │ │ │ ├── embedResources.ts │ │ │ ├── embedWebFonts.ts │ │ │ ├── getBlobFromURL.ts │ │ │ ├── index.ts │ │ │ ├── iosResourceFix.ts │ │ │ ├── options.ts │ │ │ └── util.ts │ │ └── public-api.ts │ ├── test │ │ ├── embedWebFonts.test.ts │ │ └── embedWebFontsTestPage.html │ ├── tsconfig.dts.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ ├── vite.config.ts │ └── vitest.config.ts ├── highlight │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── assets │ │ ├── arc-dark.png │ │ ├── aura-dark.png │ │ ├── coldark-cold.png │ │ ├── coldark-dark.png │ │ ├── dracula.png │ │ ├── duotone-dark.png │ │ ├── duotone-sea.png │ │ ├── holi-dark.png │ │ ├── light.png │ │ ├── material-light.png │ │ ├── material-ocean.png │ │ ├── material-palenight.png │ │ ├── material-volcano.png │ │ ├── night-owl.png │ │ ├── one-dark.png │ │ ├── synthwave84.png │ │ └── vscode-dark.png │ ├── dev │ │ ├── Editor │ │ │ ├── Editor.css.ts │ │ │ ├── Editor.tsx │ │ │ ├── preview.ts │ │ │ └── themes.ts │ │ ├── global.css.ts │ │ ├── index.css.ts │ │ ├── index.html │ │ ├── index.tsx │ │ ├── reset.scss │ │ ├── themeStore.ts │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── package.json │ ├── rollup.config.js │ ├── scripts │ │ └── generate-theme.cts │ ├── src │ │ ├── lib │ │ │ ├── core │ │ │ │ ├── build-theme.ts │ │ │ │ ├── custom-theme.ts │ │ │ │ ├── define-editor-theme.ts │ │ │ │ └── index.ts │ │ │ ├── plugins │ │ │ │ ├── autocomplete-style.ts │ │ │ │ ├── cursor-style.ts │ │ │ │ ├── highlight-style.ts │ │ │ │ ├── line-numbers-style.ts │ │ │ │ └── selection-style.ts │ │ │ └── themes │ │ │ │ ├── arcDark │ │ │ │ ├── arcDark.ts │ │ │ │ └── index.ts │ │ │ │ ├── auraDark │ │ │ │ ├── aura.ts │ │ │ │ └── index.ts │ │ │ │ ├── coldarkCold │ │ │ │ ├── coldark-cold.ts │ │ │ │ └── index.ts │ │ │ │ ├── coldarkDark │ │ │ │ ├── coldark-dark.ts │ │ │ │ └── index.ts │ │ │ │ ├── dracula │ │ │ │ ├── dracula.ts │ │ │ │ └── index.ts │ │ │ │ ├── duotoneDark │ │ │ │ ├── duotoneDark.ts │ │ │ │ └── index.ts │ │ │ │ ├── duotoneSea │ │ │ │ ├── duotoneSea.ts │ │ │ │ └── index.ts │ │ │ │ ├── fleetDark │ │ │ │ ├── dark.json │ │ │ │ ├── fleetDark.ts │ │ │ │ └── index.ts │ │ │ │ ├── githubDark │ │ │ │ ├── githubDark.ts │ │ │ │ └── index.ts │ │ │ │ ├── githubDarkDimmed │ │ │ │ ├── githubDarkDimmed.ts │ │ │ │ └── index.ts │ │ │ │ ├── githubLight │ │ │ │ ├── githubLight.ts │ │ │ │ └── index.ts │ │ │ │ ├── holi │ │ │ │ ├── holi.ts │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── light │ │ │ │ ├── index.ts │ │ │ │ └── light.ts │ │ │ │ ├── materialLight │ │ │ │ ├── index.ts │ │ │ │ └── material-light.ts │ │ │ │ ├── materialOcean │ │ │ │ ├── index.ts │ │ │ │ └── theme.ts │ │ │ │ ├── materialPalenight │ │ │ │ ├── index.ts │ │ │ │ └── materialPalenight.ts │ │ │ │ ├── materialVolcano │ │ │ │ ├── index.ts │ │ │ │ └── materialVolcano.ts │ │ │ │ ├── moonlight │ │ │ │ ├── index.ts │ │ │ │ └── moonlight.ts │ │ │ │ ├── nightOwl │ │ │ │ ├── index.ts │ │ │ │ └── nightOwl.ts │ │ │ │ ├── oneDark │ │ │ │ ├── index.ts │ │ │ │ └── oneDark.ts │ │ │ │ ├── panda │ │ │ │ ├── index.ts │ │ │ │ └── panda.ts │ │ │ │ ├── poimandres │ │ │ │ ├── index.ts │ │ │ │ └── poimandres.ts │ │ │ │ ├── shadeOfPurple │ │ │ │ ├── index.ts │ │ │ │ └── shadeOfPurple.ts │ │ │ │ ├── synthwave84 │ │ │ │ ├── index.ts │ │ │ │ └── synthwave84.ts │ │ │ │ ├── vitesseDark │ │ │ │ ├── index.ts │ │ │ │ └── vitesseDark.ts │ │ │ │ ├── vsCodeDark │ │ │ │ ├── index.ts │ │ │ │ └── vsCodeDark.ts │ │ │ │ ├── xCodeDark │ │ │ │ ├── index.ts │ │ │ │ └── xCodeDark.ts │ │ │ │ └── xCodeLight │ │ │ │ ├── index.ts │ │ │ │ └── xCodeLight.ts │ │ └── public-api.ts │ ├── tsconfig.dts.json │ ├── tsconfig.esm.json │ └── tsconfig.json ├── locale │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── lib │ │ │ ├── path.ts │ │ │ └── use-i18n.ts │ │ └── public-api.ts │ ├── tsconfig.dts.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ └── vite.config.ts ├── prisma-models │ ├── .gitignore │ ├── package.json │ ├── scripts │ │ └── build.ts │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ui │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── README.md │ ├── dev │ │ ├── demo │ │ │ ├── Button.tsx │ │ │ ├── SegmentedControl.tsx │ │ │ └── TextField.tsx │ │ ├── global.css.ts │ │ ├── index.html │ │ ├── index.tsx │ │ ├── reset.scss │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── package.json │ ├── rollup.config.ts │ ├── src │ │ ├── index.tsx │ │ ├── lib │ │ │ ├── floating │ │ │ │ └── floating-portal.tsx │ │ │ ├── hooks │ │ │ │ ├── arrayFromRange.ts │ │ │ │ ├── index.ts │ │ │ │ ├── pagination │ │ │ │ │ ├── createPagedData.ts │ │ │ │ │ ├── getLastPage.ts │ │ │ │ │ └── index.ts │ │ │ │ └── useFloating.tsx │ │ │ ├── primitives │ │ │ │ ├── Badge │ │ │ │ │ ├── Badge.css.ts │ │ │ │ │ ├── Badge.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Box │ │ │ │ │ ├── Box.css.ts │ │ │ │ │ ├── Box.tsx │ │ │ │ │ ├── Stack.css.ts │ │ │ │ │ ├── Stack.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Button │ │ │ │ │ ├── Button.css.ts │ │ │ │ │ ├── Button.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Dropdown │ │ │ │ │ ├── Dropdown.css.ts │ │ │ │ │ ├── DropdownItem.tsx │ │ │ │ │ ├── DropdownMenu.tsx │ │ │ │ │ ├── DropdownPortal.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Field │ │ │ │ │ ├── FlexField.css.ts │ │ │ │ │ ├── FlexField.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Group │ │ │ │ │ ├── Group.css.ts │ │ │ │ │ ├── Group.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Icon │ │ │ │ │ ├── RemoteSvgIcon.tsx │ │ │ │ │ ├── SvgIcon.css.ts │ │ │ │ │ ├── SvgIcon.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── IconButton │ │ │ │ │ ├── IconButton.css.ts │ │ │ │ │ ├── IconButton.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Label │ │ │ │ │ ├── FieldLabel.css.ts │ │ │ │ │ ├── FieldLabel.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Link │ │ │ │ │ ├── Link.css.ts │ │ │ │ │ ├── Link.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Loader │ │ │ │ │ ├── Loader.css.ts │ │ │ │ │ ├── Loading.tsx │ │ │ │ │ ├── LoadingCircle.css.ts │ │ │ │ │ ├── LoadingCircle.tsx │ │ │ │ │ ├── LoadingOverlay.css.ts │ │ │ │ │ ├── LoadingOverlay.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── PortalHost │ │ │ │ │ ├── PortalHost.css.ts │ │ │ │ │ ├── PortalHost.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── RadioBlock │ │ │ │ │ ├── RadioBlock.css.ts │ │ │ │ │ ├── RadioBlock.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── RangeField │ │ │ │ │ ├── RangeField.css.ts │ │ │ │ │ ├── RangeField.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── SegmentedField │ │ │ │ │ ├── SegmentedField.css.ts │ │ │ │ │ ├── SegmentedField.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Snackbar │ │ │ │ │ ├── Snackbar.css.ts │ │ │ │ │ ├── Snackbar.tsx │ │ │ │ │ ├── SnackbarHost.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── patch-solid-toast.ts │ │ │ │ ├── Text │ │ │ │ │ ├── Text.css.ts │ │ │ │ │ ├── Text.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── useText.tsx │ │ │ │ ├── TextField │ │ │ │ │ ├── TextField.css.ts │ │ │ │ │ ├── TextField.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Toggle │ │ │ │ │ ├── Toggle.css.ts │ │ │ │ │ ├── Toggle.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Transition │ │ │ │ │ ├── Transition.css.ts │ │ │ │ │ ├── Transition.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── theme │ │ │ │ ├── base.css.ts │ │ │ │ ├── colors.ts │ │ │ │ ├── global2.css.ts │ │ │ │ ├── index.ts │ │ │ │ ├── spacing.ts │ │ │ │ ├── sprinkles.css.ts │ │ │ │ ├── theme.css.ts │ │ │ │ ├── variables.css.ts │ │ │ │ └── with-theme-mode.ts │ │ │ ├── themes │ │ │ │ ├── dark-theme.css.ts │ │ │ │ └── light-theme.css.ts │ │ │ ├── tokens │ │ │ │ ├── createCodeImageTheme.ts │ │ │ │ ├── index.ts │ │ │ │ └── tokens.tsx │ │ │ └── utils │ │ │ │ ├── factory.tsx │ │ │ │ ├── index.ts │ │ │ │ └── mapToProperty.ts │ │ └── vite-env.d.ts │ ├── tools │ │ ├── build.ts │ │ ├── preserve-jsx-imports.ts │ │ └── with-solid.ts │ ├── tsconfig.dts.json │ ├── tsconfig.json │ ├── tsconfig.source.json │ └── vite.config.ts └── vanilla-extract │ ├── .eslintignore │ ├── .gitignore │ ├── .lintstagedrc │ ├── CHANGELOG.md │ ├── LICENSE.seek.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ ├── esbuild │ │ └── vanillaCssTsFilesLoader.ts │ ├── index.ts │ └── vite-plugin │ │ ├── index.ts │ │ └── postcss.ts │ └── tsconfig.json ├── patches └── csstype@3.1.1.patch ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── env-utils.ts ├── ignore-release.js ├── make-env.ts ├── patch-solid-exports.ts ├── sync-package.ts └── vercel-output-build.ts ├── tsconfig.json └── vercel.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.4/schema.json", 3 | "changelog": ["@changesets/changelog-github", { "repo": "riccardoperra/codeimage" }], 4 | "commit": true, 5 | "linked": [], 6 | "access": "restricted", 7 | "baseBranch": "main", 8 | "updateInternalDependencies": "patch", 9 | "ignore": [] 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | indent_style = space 9 | indent_size = 2 -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # ================================================================================== 2 | # ================================================================================== 3 | # @codeimage codeowners 4 | # ================================================================================== 5 | # ================================================================================== 6 | # 7 | # 8 | # More info: https://help.github.com/articles/about-codeowners/ 9 | # 10 | 11 | * @riccardoperra 12 | # will be requested for review when someone opens a pull request 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: riccardoperra 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature-request.yml: -------------------------------------------------------------------------------- 1 | name: '🚀 - Feature Request' 2 | title: '🚀 - ' 3 | description: Suggest a feature for Codeimage 4 | labels: ['feature', 'state: need triage'] 5 | 6 | body: 7 | - type: dropdown 8 | id: affected-packages 9 | attributes: 10 | label: Which @codeimage/* package(s) are relevant/releated to the feature request? 11 | options: 12 | - codeimage 13 | - config 14 | - locale 15 | - highlight 16 | - ui 17 | - Don't known / other 18 | multiple: true 19 | 20 | - type: textarea 21 | id: description 22 | attributes: 23 | label: Description 24 | placeholder: | 25 | Proposed solution. 26 | Alternatives considered. 27 | validations: 28 | required: true 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-dev-infra-request.yml: -------------------------------------------------------------------------------- 1 | name: '🤖 - Dev Infrastructure Request' 2 | title: '🤖 - ' 3 | description: Suggest a feature to improve code, worfklow for @codeimage development 4 | labels: ['dev-infra', 'state: need triage'] 5 | 6 | body: 7 | - type: textarea 8 | id: description 9 | attributes: 10 | label: Description 11 | placeholder: | 12 | Proposed solution. 13 | Alternatives considered. 14 | validations: 15 | required: true 16 | -------------------------------------------------------------------------------- /.github/actions/setup-job/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup CI Step' 2 | description: 'Checkout PR and use same node version for jobs' 3 | 4 | runs: 5 | using: 'composite' 6 | 7 | steps: 8 | - name: Use Node.js 22 9 | uses: actions/setup-node@v4 10 | with: 11 | node-version: 22 12 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 120 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 120 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout PR 14 | uses: actions/checkout@v4 15 | - name: 📥 Setup 16 | uses: ./.github/actions/setup-job 17 | - name: 📥 Monorepo install 18 | uses: ./.github/actions/pnpm-install 19 | 20 | - name: Create Release Pull Request or Publish to npm 21 | id: changesets 22 | uses: changesets/action@v1 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | version: pnpm changeset:pr 27 | title: "chore(release): version packages" 28 | commit: 'chore(release): version packages' 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vercel 4 | **/*.env 5 | .env 6 | .env.* 7 | ./**/*.env 8 | ./**/*.env.* 9 | .idea 10 | .pnpm-store/ 11 | .DS_STORE 12 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/codegram.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/jsLinters/eslint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/prettier.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.md": "prettier --write" 3 | } 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact=true 2 | save-prefix= 3 | strict-peer-dependencies=false 4 | 5 | shell-emulator=true 6 | enable-pre-post-scripts=false 7 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v16.13.2 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "quoteProps": "as-needed", 4 | "printWidth": 80, 5 | "singleQuote": true, 6 | "arrowParens": "avoid", 7 | "trailingComma": "all", 8 | "bracketSpacing": false, 9 | "endOfLine": "auto" 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/codeimage.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.bracketPairColorization.enabled": false, 4 | "typescript.tsdk": "node_modules/typescript/lib" 5 | } -------------------------------------------------------------------------------- /apps/api/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /apps/api/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx,js,jsx}": [ 3 | "pnpm lint", 4 | "pnpm pre-commit-prettier", 5 | "pnpm pre-commit-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /apps/api/.taprc: -------------------------------------------------------------------------------- 1 | test-env: [ 2 | TS_NODE_FILES=true, 3 | TS_NODE_PROJECT=./test/tsconfig.json 4 | ] 5 | -------------------------------------------------------------------------------- /apps/api/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with [Fastify-CLI](https://www.npmjs.com/package/fastify-cli) 2 | 3 | This project was bootstrapped with Fastify-CLI. 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `pnpm dev` 10 | 11 | To start the app in dev mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | ### `pnpm start` 15 | 16 | For production mode 17 | 18 | ### `pnpm test` 19 | 20 | Run the test cases. 21 | 22 | ## Learn More 23 | 24 | To learn Fastify, check out the [Fastify documentation](https://www.fastify.io/docs/latest/). 25 | -------------------------------------------------------------------------------- /apps/api/api-types/index.d.ts: -------------------------------------------------------------------------------- 1 | export type { 2 | CreateProjectApi, 3 | DeleteProjectApi, 4 | UpdateProjectApi, 5 | UpdateProjectNameApi, 6 | GetProjectByIdApi, 7 | CloneProjectApi, 8 | CreatePresetApi, 9 | DeletePresetApi, 10 | GetPresetByIdApi, 11 | UpdatePresetApi, 12 | GetAllPresetApi, 13 | } from '../dist/schemas/index.js'; 14 | -------------------------------------------------------------------------------- /apps/api/docker-compose.dev.yml: -------------------------------------------------------------------------------- 1 | # docker-compose -f docker-compose.dev.yml -p codeimage up -d 2 | 3 | version: '3.8' 4 | 5 | services: 6 | db: 7 | image: postgres:13-alpine 8 | restart: unless-stopped 9 | volumes: 10 | - postgres_data:/var/lib/postgresql/data/ 11 | ports: 12 | - '5432:5432' 13 | environment: 14 | - POSTGRES_USER=postgres 15 | - POSTGRES_PASSWORD=postgres 16 | - POSTGRES_DB=codeimage 17 | test_db: 18 | image: postgres:13-alpine 19 | restart: always 20 | ports: 21 | - '5433:5432' 22 | environment: 23 | POSTGRES_USER: postgres 24 | POSTGRES_PASSWORD: postgres 25 | POSTGRES_DB: codeimage_test 26 | 27 | volumes: 28 | postgres_data: null 29 | -------------------------------------------------------------------------------- /apps/api/nixpacks.toml: -------------------------------------------------------------------------------- 1 | # nixpacks.toml 2 | providers = ["node"] 3 | 4 | [phases.setup] 5 | nixPkgs = ["nodejs"] 6 | 7 | [phases.build] 8 | cmds = ["ls"] 9 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20220813131834_add_user_email/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `provider` on the `User` table. All the data in the column will be lost. 5 | - A unique constraint covering the columns `[email]` on the table `User` will be added. If there are existing duplicate values, this will fail. 6 | - Added the required column `email` to the `User` table without a default value. This is not possible if the table is not empty. 7 | 8 | */ 9 | -- AlterTable 10 | ALTER TABLE "User" DROP COLUMN "provider", 11 | ADD COLUMN "email" TEXT NOT NULL; 12 | 13 | -- CreateIndex 14 | CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); 15 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20220819164911_delete_cascade_user/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "Project" DROP CONSTRAINT "Project_userId_fkey"; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Project" ADD CONSTRAINT "Project_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20230302182841_project_unique_owner_constraint_336_feature/migration.sql: -------------------------------------------------------------------------------- 1 | -- AddForeignKey 2 | ALTER TABLE "Project" ADD CONSTRAINT "Project_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 3 | 4 | -- RenameIndex 5 | ALTER INDEX "Project_id_ownerId_idx" RENAME TO "Project_id_ownerId_key"; 6 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20230302183231_editor_add_ligatures_option/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "SnippetEditorOptions" ADD COLUMN "enableLigatures" BOOLEAN NOT NULL DEFAULT true; 3 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20230304194315_preset/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "Preset" ( 3 | "id" TEXT NOT NULL, 4 | "name" TEXT NOT NULL, 5 | "data" JSONB NOT NULL, 6 | "version" BIGINT NOT NULL DEFAULT 1, 7 | "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 8 | "updatedAt" TIMESTAMP(3) NOT NULL, 9 | "ownerId" TEXT NOT NULL, 10 | 11 | CONSTRAINT "Preset_pkey" PRIMARY KEY ("id") 12 | ); 13 | 14 | -- CreateIndex 15 | CREATE INDEX "Preset_name_ownerId_idx" ON "Preset"("name", "ownerId"); 16 | 17 | -- CreateIndex 18 | CREATE UNIQUE INDEX "Preset_id_ownerId_key" ON "Preset"("id", "ownerId"); 19 | 20 | -- AddForeignKey 21 | ALTER TABLE "Preset" ADD CONSTRAINT "Preset_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 22 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20230821142152_update_default_frame_radius/migration.sql: -------------------------------------------------------------------------------- 1 | UPDATE "SnippetFrame" 2 | SET radius = 8 3 | where radius is not null; 4 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20231231115803_add_terminal_border_type_property/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "SnippetTerminal" ADD COLUMN "borderType" TEXT; 3 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20240107110836_add_line_number_start/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "SnippetEditorTab" ADD COLUMN "lineNumberStart" INTEGER NOT NULL DEFAULT 1; 3 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "postgresql" -------------------------------------------------------------------------------- /apps/api/src/common/domainFunctions/registry.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DomainHandlerMap, 3 | GenericHandler, 4 | ResolvedDomainHandlerMap, 5 | } from '@api/domain'; 6 | import {getHandlerMetadata} from './handlers.js'; 7 | 8 | export class HandlerRegistry { 9 | #events = new Map(); 10 | 11 | get handlers(): ResolvedDomainHandlerMap { 12 | return Object.fromEntries( 13 | this.#events.entries(), 14 | ) as ResolvedDomainHandlerMap; 15 | } 16 | 17 | add(handler: GenericHandler): void { 18 | const metadata = getHandlerMetadata(handler); 19 | this.#events.set(metadata.name, handler); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/api/src/common/exceptions/HandlerError.ts: -------------------------------------------------------------------------------- 1 | import {FastifyError} from 'fastify'; 2 | import {constants} from 'http2'; 3 | 4 | type HttpStatusCode = { 5 | readonly [K in keyof typeof constants as K extends `HTTP_STATUS_${string}` 6 | ? K 7 | : never]: typeof constants[K]; 8 | }; 9 | 10 | export abstract class HandlerError< 11 | Args extends Record | void = void, 12 | > 13 | extends Error 14 | implements FastifyError 15 | { 16 | code = this.constructor.name; 17 | 18 | static httpStatusCode = constants as HttpStatusCode; 19 | 20 | constructor(args?: Args) { 21 | super(); 22 | this.message = this.createMessage(args as Args); 23 | Error.captureStackTrace(this, this.constructor); 24 | } 25 | 26 | abstract createMessage(args: Args): string; 27 | } 28 | -------------------------------------------------------------------------------- /apps/api/src/common/exceptions/NotFoundEntityException.ts: -------------------------------------------------------------------------------- 1 | import {HandlerError} from './HandlerError.js'; 2 | 3 | export abstract class NotFoundEntityException< 4 | Args extends Record | void = void, 5 | > extends HandlerError { 6 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 7 | abstract createMessage(args: Args): string; 8 | } 9 | -------------------------------------------------------------------------------- /apps/api/src/common/exceptions/UnprocessableEntityException.ts: -------------------------------------------------------------------------------- 1 | import {HandlerError} from './HandlerError.js'; 2 | 3 | export abstract class UnprocessableEntityException< 4 | Args extends Record | void = void, 5 | > extends HandlerError { 6 | statusCode = HandlerError.httpStatusCode.HTTP_STATUS_UNPROCESSABLE_ENTITY; 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 9 | abstract createMessage(args: Args): string; 10 | } 11 | -------------------------------------------------------------------------------- /apps/api/src/common/typebox/enum.ts: -------------------------------------------------------------------------------- 1 | import {TString, Type} from '@sinclair/typebox'; 2 | 3 | export const enumLiteral = (values: T[]): TString => { 4 | const literals = values.map(value => Type.Literal(value)); 5 | // TODO: validation should work but type must work as a string... 6 | return Type.Intersect([ 7 | Type.Union(literals), 8 | Type.String(), 9 | ]) as unknown as TString; 10 | }; 11 | -------------------------------------------------------------------------------- /apps/api/src/common/typebox/nullable.ts: -------------------------------------------------------------------------------- 1 | import {SchemaOptions, TSchema, Type} from '@sinclair/typebox'; 2 | 3 | export const Nullable = (tType: T, optional = true) => { 4 | const options: SchemaOptions | undefined = Reflect.has(tType, 'default') 5 | ? {default: tType.default} 6 | : undefined; 7 | 8 | const resolvedType = Type.Union([tType, Type.Null()], options); 9 | 10 | if (optional) { 11 | return Type.Optional(resolvedType); 12 | } 13 | return resolvedType; 14 | }; 15 | -------------------------------------------------------------------------------- /apps/api/src/common/types/extract-api-types.ts: -------------------------------------------------------------------------------- 1 | import {Static, TSchema} from '@sinclair/typebox'; 2 | import {FastifySchema} from 'fastify'; 3 | 4 | type StaticSchemaOrType = T extends TSchema ? Static : T; 5 | 6 | interface GetApiRequest { 7 | body?: StaticSchemaOrType; 8 | querystring?: StaticSchemaOrType; 9 | params?: StaticSchemaOrType; 10 | headers?: StaticSchemaOrType; 11 | } 12 | 13 | type GetApiResponse = T['response'] extends { 14 | 200: infer U; 15 | } 16 | ? StaticSchemaOrType 17 | : never; 18 | 19 | export interface GetApiTypes { 20 | request: GetApiRequest; 21 | response: GetApiResponse; 22 | } 23 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/domain/index.ts: -------------------------------------------------------------------------------- 1 | import {Preset} from '@codeimage/prisma-models'; 2 | 3 | export type PresetCreateRequest = Pick< 4 | Preset, 5 | 'name' | 'data' | 'ownerId' | 'version' 6 | >; 7 | 8 | export type PresetUpdateRequest = Pick; 9 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/exceptions/ExceedPresetLimitException.ts: -------------------------------------------------------------------------------- 1 | import {UnprocessableEntityException} from '../../../common/exceptions/UnprocessableEntityException.js'; 2 | 3 | export class ExceedPresetLimitException extends UnprocessableEntityException<{ 4 | limit: number; 5 | }> { 6 | limit: number; 7 | 8 | constructor(options: {limit: number}) { 9 | super(); 10 | this.limit = options.limit; 11 | } 12 | 13 | createMessage(): string { 14 | return `Preset limit per account exceeded`; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/exceptions/NotFoundPresetException.ts: -------------------------------------------------------------------------------- 1 | import {NotFoundEntityException} from '../../../common/exceptions/NotFoundEntityException.js'; 2 | 3 | type Params = { 4 | id: string; 5 | ownerId: string; 6 | }; 7 | 8 | export class NotFoundPresetException extends NotFoundEntityException { 9 | createMessage({id, ownerId}: Params): string { 10 | return `Preset with id ${id} for user ${ownerId} not found`; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/handlers/delete.ts: -------------------------------------------------------------------------------- 1 | import {HandlerBuilder} from '../../../common/domainFunctions/builder.js'; 2 | import {PresetHandlerDependencies} from './index.js'; 3 | 4 | export const remove = 5 | HandlerBuilder.withDependencies() 6 | .withName('deletePreset') 7 | .withImplementation(({repository}, {handlers}) => { 8 | return async (userId: string, id: string) => { 9 | const preset = await handlers.findPresetById(userId, id); 10 | 11 | return await repository.deletePreset(preset.id); 12 | }; 13 | }) 14 | .build(); 15 | 16 | declare module '@api/domain' { 17 | interface DomainHandlerMap { 18 | deletePreset: typeof remove; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/handlers/findAll.ts: -------------------------------------------------------------------------------- 1 | import {HandlerBuilder} from '../../../common/domainFunctions/builder.js'; 2 | import {PresetDto} from '../schema/preset-dto.schema.js'; 3 | import {PresetHandlerDependencies} from './index.js'; 4 | 5 | export const findAll = 6 | HandlerBuilder.withDependencies() 7 | .withName('findAllPresets') 8 | .withImplementation(({repository, mapper}) => { 9 | return async (ownerId: string): Promise => { 10 | const preset = await repository.findAllByOwnerId(ownerId); 11 | return preset.map(mapper.fromEntityToDto); 12 | }; 13 | }) 14 | .build(); 15 | 16 | declare module '@api/domain' { 17 | interface DomainHandlerMap { 18 | findAllPresets: typeof findAll; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/handlers/index.ts: -------------------------------------------------------------------------------- 1 | import {FastifyInstance} from 'fastify'; 2 | import {PresetMapper} from '../mapper/index.js'; 3 | import type {PresetRepository} from '../repository/index.js'; 4 | 5 | export type PresetHandlerDependencies = { 6 | repository: PresetRepository; 7 | mapper: PresetMapper; 8 | config: FastifyInstance['config']; 9 | }; 10 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/mapper/index.ts: -------------------------------------------------------------------------------- 1 | import {Preset} from '@codeimage/prisma-models'; 2 | import {PresetDataDto, PresetDto} from '../schema/preset-dto.schema.js'; 3 | 4 | export interface PresetMapper { 5 | fromEntityToDto(entity: Preset): PresetDto; 6 | } 7 | 8 | export class PresetMapper implements PresetMapper { 9 | fromEntityToDto(entity: Preset): PresetDto { 10 | return { 11 | id: entity.id, 12 | name: entity.name, 13 | version: Number(entity.version), 14 | createdAt: entity.createdAt, 15 | updatedAt: entity.updatedAt, 16 | data: entity.data as PresetDataDto, 17 | } as const; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/repository/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preset.repository.js'; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/repository/preset.repository.ts: -------------------------------------------------------------------------------- 1 | import {Preset} from '@codeimage/prisma-models'; 2 | import {PresetCreateRequest, PresetUpdateRequest} from '../domain/index.js'; 3 | 4 | export interface PresetRepository { 5 | findByIdAndOwnerId(id: string, ownerId: string): Promise; 6 | 7 | findAllByOwnerId(ownerId: string): Promise; 8 | 9 | countByOwnerId(ownerId: string): Promise; 10 | 11 | create(data: PresetCreateRequest): Promise; 12 | 13 | update(id: string, data: PresetUpdateRequest): Promise; 14 | 15 | deletePreset(id: string): Promise; 16 | } 17 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/schema/preset-create-dto.schema.ts: -------------------------------------------------------------------------------- 1 | import {Static, Type as t} from '@sinclair/typebox'; 2 | import {PresetDataSchema} from './preset-dto.schema.js'; 3 | 4 | export const PresetCreateDtoSchema = t.Object({ 5 | name: t.String(), 6 | data: PresetDataSchema, 7 | }); 8 | 9 | export type PresetCreateDto = Static; 10 | -------------------------------------------------------------------------------- /apps/api/src/modules/preset/schema/preset-update-dto.schema.ts: -------------------------------------------------------------------------------- 1 | import {Static, Type as t} from '@sinclair/typebox'; 2 | 3 | export const PresetUpdateDtoSchema = t.Object({ 4 | name: t.String(), 5 | data: t.Object({}), 6 | }); 7 | 8 | export type PresetUpdateDto = Static; 9 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/domain/index.ts: -------------------------------------------------------------------------------- 1 | export * from './projectCreateRequest.js'; 2 | export * from './projectUpdateRequest.js'; 3 | export * from './projectGetByIdResponse.js'; 4 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/domain/projectCreateRequest.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Project, 3 | SnippetEditorOptions, 4 | SnippetEditorTab, 5 | SnippetFrame, 6 | SnippetTerminal, 7 | } from '@codeimage/prisma-models'; 8 | 9 | type IdAndProjectId = 'id' | 'projectId'; 10 | 11 | export interface ProjectCreateRequest { 12 | name: Project['name']; 13 | editorOptions: Omit; 14 | terminal: Omit; 15 | frame: Omit; 16 | editors: Omit[]; 17 | } 18 | 19 | export type ProjectCreateResponse = Project & { 20 | editorOptions: SnippetEditorOptions; 21 | terminal: SnippetTerminal; 22 | frame: SnippetFrame; 23 | editorTabs: SnippetEditorTab[]; 24 | }; 25 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/domain/projectGetByIdResponse.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Project, 3 | SnippetEditorOptions, 4 | SnippetEditorTab, 5 | SnippetFrame, 6 | SnippetTerminal, 7 | } from '@codeimage/prisma-models'; 8 | 9 | export type ProjectGetByIdResponse = Project & { 10 | editorOptions: SnippetEditorOptions; 11 | terminal: SnippetTerminal; 12 | frame: SnippetFrame; 13 | editorTabs: SnippetEditorTab[]; 14 | }; 15 | 16 | export type PartialProjectGetByIdResponse = Project & { 17 | editorTabs: Pick[]; 18 | }; 19 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/repository/index.ts: -------------------------------------------------------------------------------- 1 | export * from './project.repository.js'; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/schema/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | ProjectCreateRequestSchema, 3 | type ProjectCreateRequest, 4 | type ProjectCreateResponse, 5 | ProjectCreateResponseSchema, 6 | } from './project-create.schema.js'; 7 | 8 | export { 9 | type ProjectUpdateRequest, 10 | type ProjectUpdateResponse, 11 | ProjectUpdateRequestSchema, 12 | ProjectUpdateResponseSchema, 13 | } from './project-update.schema.js'; 14 | 15 | export { 16 | ProjectDeleteResponseSchema, 17 | type ProjectDeleteResponse, 18 | } from './project-delete.schema.js'; 19 | 20 | export { 21 | ProjectGetByIdResponseSchema, 22 | PartialProjectGetByIdResponseSchema, 23 | type ProjectGetByIdResponse, 24 | type ProjectCompleteResponse, 25 | } from './project-get-by-id.schema.js'; 26 | -------------------------------------------------------------------------------- /apps/api/src/modules/project/schema/project-delete.schema.ts: -------------------------------------------------------------------------------- 1 | import {Static, Type} from '@sinclair/typebox'; 2 | import {BaseProjectResponseSchema} from './project.schema.js'; 3 | 4 | export const ProjectDeleteResponseSchema = Type.Intersect( 5 | [BaseProjectResponseSchema], 6 | { 7 | title: 'ProjectDeleteResponse', 8 | }, 9 | ); 10 | 11 | export type ProjectDeleteResponse = Static; 12 | -------------------------------------------------------------------------------- /apps/api/src/plugins/cors.ts: -------------------------------------------------------------------------------- 1 | import fastifyCors from '@fastify/cors'; 2 | import fp from 'fastify-plugin'; 3 | 4 | export default fp(async fastify => { 5 | const config = fastify.config.ALLOWED_ORIGINS; 6 | 7 | if (!config) { 8 | return; 9 | } 10 | 11 | const origins = config.split(',').map(str => str.trim()); 12 | const origin = origins.includes('*') ? '*' : origins; 13 | 14 | fastify.register(fastifyCors, {origin}); 15 | }); 16 | -------------------------------------------------------------------------------- /apps/api/src/plugins/handler.ts: -------------------------------------------------------------------------------- 1 | import fp from 'fastify-plugin'; 2 | import {HandlerRegistry} from '../common/domainFunctions/registry.js'; 3 | 4 | export default fp(async fastify => { 5 | fastify.decorate('handlerRegistry', new HandlerRegistry()); 6 | }); 7 | 8 | declare module 'fastify' { 9 | interface FastifyInstance { 10 | handlerRegistry: HandlerRegistry; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/api/src/plugins/healthcheck.ts: -------------------------------------------------------------------------------- 1 | import fastifyHealthcheck from 'fastify-healthcheck'; 2 | import fp from 'fastify-plugin'; 3 | 4 | export default fp(async fastify => { 5 | return fastify.register(fastifyHealthcheck); 6 | }); 7 | -------------------------------------------------------------------------------- /apps/api/src/plugins/prisma.ts: -------------------------------------------------------------------------------- 1 | import {PrismaClient} from '@codeimage/prisma-models'; 2 | import {FastifyPluginAsync} from 'fastify'; 3 | import fp from 'fastify-plugin'; 4 | 5 | declare module 'fastify' { 6 | interface FastifyInstance { 7 | prisma: PrismaClient; 8 | } 9 | } 10 | 11 | const prismaPlugin: FastifyPluginAsync = fp( 12 | async server => { 13 | const prisma = new PrismaClient({ 14 | datasources: { 15 | db: { 16 | url: server.config.DATABASE_URL, 17 | }, 18 | }, 19 | }); 20 | 21 | await prisma.$connect(); 22 | 23 | server.decorate('prisma', prisma); 24 | 25 | server.addHook('onClose', async server => { 26 | await server.prisma.$disconnect(); 27 | }); 28 | }, 29 | {name: 'prisma'}, 30 | ); 31 | 32 | export default prismaPlugin; 33 | -------------------------------------------------------------------------------- /apps/api/src/plugins/sensible.ts: -------------------------------------------------------------------------------- 1 | import sensible, {SensibleOptions} from '@fastify/sensible'; 2 | import fp from 'fastify-plugin'; 3 | 4 | /** 5 | * This plugins adds some utilities to handle http errors 6 | * 7 | * @see https://github.com/fastify/fastify-sensible 8 | */ 9 | export default fp(async fastify => { 10 | fastify.register(sensible); 11 | }); 12 | -------------------------------------------------------------------------------- /apps/api/src/routes/v1/project/getAllByUserId.ts: -------------------------------------------------------------------------------- 1 | import {FastifyPluginAsync} from 'fastify'; 2 | import {ProjectGetByIdResponse} from '../../../modules/project/schema/index.js'; 3 | 4 | const getAllByUserIdRoute: FastifyPluginAsync = async fastify => { 5 | fastify.get( 6 | '/', 7 | { 8 | preValidation: (req, reply) => fastify.authorize(req, reply), 9 | schema: { 10 | tags: ['Project'], 11 | summary: 'Get all CodeImage projects by the current user', 12 | }, 13 | }, 14 | async (request): Promise => { 15 | const {appUser} = request; 16 | return fastify.projectService.findAllByUserId(appUser.id); 17 | }, 18 | ); 19 | }; 20 | 21 | export default getAllByUserIdRoute; 22 | -------------------------------------------------------------------------------- /apps/api/test/__internal__/presetUtils.ts: -------------------------------------------------------------------------------- 1 | import {Value} from '@sinclair/typebox/value'; 2 | import {PresetDataSchema} from '../../src/modules/preset/schema/preset-dto.schema.js'; 3 | 4 | export const testPresetUtils = { 5 | buildPresetData() { 6 | return Value.Create(PresetDataSchema); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /apps/api/test/common/domainFunctions/builder.test.ts: -------------------------------------------------------------------------------- 1 | import * as sinon from 'sinon'; 2 | import {assert, test} from 'vitest'; 3 | import {HandlerBuilder} from '../../../src/common/domainFunctions/builder.js'; 4 | 5 | test('create handler', async () => { 6 | const fn = sinon.fake(); 7 | 8 | const handler = HandlerBuilder.withDependencies() 9 | .withName('name') 10 | .withImplementation(deps => (arg: any) => fn(arg, deps)) 11 | .build(); 12 | 13 | handler('test-deps', {} as any)(1); 14 | 15 | assert(fn.calledWith(1, 'test-deps')); 16 | }); 17 | -------------------------------------------------------------------------------- /apps/api/test/helpers/auth0Mock.ts: -------------------------------------------------------------------------------- 1 | import {User} from '@codeimage/prisma-models'; 2 | import {TestContext} from 'vitest'; 3 | import {mockAuthProvider} from '../../src/plugins/auth0.js'; 4 | 5 | export const auth0Mock = (t: TestContext & T) => 6 | mockAuthProvider(t.user); 7 | -------------------------------------------------------------------------------- /apps/api/test/modules/preset/data-utils.ts: -------------------------------------------------------------------------------- 1 | import {Preset} from '@codeimage/prisma-models'; 2 | 3 | export class PresetTestDataUtils { 4 | static buildPreset(id: string, name: string, ownerId: string, data: {} = {}) { 5 | return { 6 | id, 7 | name, 8 | createdAt: new Date(), 9 | updatedAt: new Date(), 10 | version: BigInt(1), 11 | data, 12 | ownerId, 13 | } as Preset; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/api/test/setup-unit.ts: -------------------------------------------------------------------------------- 1 | import * as dotEnv from 'dotenv'; 2 | import path from 'node:path'; 3 | import {fileURLToPath} from 'node:url'; 4 | 5 | export function setup() { 6 | const __filename = fileURLToPath(import.meta.url); 7 | const __dirname = path.dirname(__filename); 8 | 9 | dotEnv.config({path: `${__dirname}/../.env.test`}).parsed; 10 | } 11 | -------------------------------------------------------------------------------- /apps/api/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "moduleResolution": "Node16", 6 | "module": "ES2022", 7 | "target": "ES2022" 8 | }, 9 | "include": [ 10 | "../src/**/*.ts", 11 | "**/*.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /apps/api/tsconfig.dts.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "emitDeclarationOnly": true, 6 | "declarationMap": false, 7 | "outDir": "./dist", 8 | "moduleResolution": "NodeNext", 9 | "module": "NodeNext", 10 | "target": "ES2022" 11 | } 12 | } -------------------------------------------------------------------------------- /apps/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "fastify-tsconfig", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "resolveJsonModule": false, 6 | "declarationMap": true, 7 | "allowSyntheticDefaultImports": true, 8 | "sourceMap": true, 9 | "moduleResolution": "NodeNext", 10 | "module": "NodeNext", 11 | "target": "ES2022", 12 | "typeRoots": ["./src/common/domainFunctions/functions.d.ts"] 13 | }, 14 | "include": ["./src/**/*.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /apps/api/tsconfig.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "emitDeclarationOnly": true, 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/api/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['./src/**/*.ts'], 5 | bundle: false, 6 | platform: 'node', 7 | target: 'node18', 8 | format: ['esm'], 9 | sourcemap: true, 10 | clean: true, 11 | dts: false, 12 | }); 13 | -------------------------------------------------------------------------------- /apps/codeimage/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /apps/codeimage/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx,js,jsx}": [ 3 | "pnpm lint", 4 | "pnpm pre-commit-prettier", 5 | "pnpm pre-commit-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /apps/codeimage/changelog/1-4-3_11-08-2023.mdx: -------------------------------------------------------------------------------- 1 | # v1.4.3 2 | 3 | This new version introduce the [JetBrains Fleet](https://www.jetbrains.com/fleet/) Dark Theme in the CodeImage editor! 4 | 5 | ![Snippet using jetbrains fleet theme](https://github.com/riccardoperra/codeimage/assets/37072694/0f346e31-92ec-4176-991d-d6aa2ae9e225) 6 | -------------------------------------------------------------------------------- /apps/codeimage/changelog/1-7-0_06-29-2024.mdx: -------------------------------------------------------------------------------- 1 | import {mdxComponents} from '../src/mdx/components'; 2 | import shareablePresets from './data/1-7-0/shareable_presets.png'; 3 | 4 | # v1.7.0 5 | 6 | 🎨 Shareable presets 7 | 8 | This new CodeImage update bring a way to share your presets via link. 9 | 10 | Everyone that paste the link into their browser will automatically get your preset into their workspace. 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/codeimage/changelog/1-9-0_02-02-2025.mdx: -------------------------------------------------------------------------------- 1 | import {mdxComponents} from '../src/mdx/components'; 2 | import exportActiveTab from './data/1-9-0/export-active-tab.png'; 3 | 4 | 5 | 6 | # v1.9.0 7 | 8 | Export only active tab 9 | 10 | This new version of CodeImage introduces a new option during image export. 11 | 12 | While `Show only active tab` option is active, non-active tabs will be hidden on 13 | exported image. 14 | 15 | 16 | -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-5-0/constant.ts: -------------------------------------------------------------------------------- 1 | export const localFontAccessApiBrowserCompatibilityLink = 2 | 'https://developer.mozilla.org/en-US/docs/Web/API/Local_Font_Access_API#browser_compatibility'; 3 | -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-5-0/font-picker.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-5-0/font-picker.mp4 -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-5-0/window-style.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-5-0/window-style.mp4 -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-5-0/xcode-theme.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-5-0/xcode-theme.mp4 -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-6-0/new-border-option.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-6-0/new-border-option.mp4 -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-6-0/starting-line-number.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-6-0/starting-line-number.mp4 -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-7-0/shareable_presets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-7-0/shareable_presets.png -------------------------------------------------------------------------------- /apps/codeimage/changelog/data/1-9-0/export-active-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/changelog/data/1-9-0/export-active-tab.png -------------------------------------------------------------------------------- /apps/codeimage/public/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/favicon.ico -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Bold.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-BoldItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLight.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-Thin.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/IBM_Plex_Mono/IBMPlexMono-ThinItalic.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/agave/Agave-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/agave/Agave-Regular.ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/geist_mono/GeistMono[wght].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/geist_mono/GeistMono[wght].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/monaspace/MonaspaceArgonVarVF[wght,wdth,slnt].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/monaspace/MonaspaceArgonVarVF[wght,wdth,slnt].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/monaspace/MonaspaceKryptonVarVF[wght,wdth,slnt].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/monaspace/MonaspaceKryptonVarVF[wght,wdth,slnt].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/monaspace/MonaspaceNeonVarVF[wght,wdth,slnt].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/monaspace/MonaspaceNeonVarVF[wght,wdth,slnt].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/monaspace/MonaspaceRadonVarVF[wght,wdth,slnt].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/monaspace/MonaspaceRadonVarVF[wght,wdth,slnt].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/assets/fonts/monaspace/MonaspaceXenonVarVF[wght,wdth,slnt].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/assets/fonts/monaspace/MonaspaceXenonVarVF[wght,wdth,slnt].ttf -------------------------------------------------------------------------------- /apps/codeimage/public/pwa/apple-icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/pwa/apple-icon-180.png -------------------------------------------------------------------------------- /apps/codeimage/public/pwa/manifest-icon-192.maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/pwa/manifest-icon-192.maskable.png -------------------------------------------------------------------------------- /apps/codeimage/public/pwa/manifest-icon-512.maskable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/public/pwa/manifest-icon-512.maskable.png -------------------------------------------------------------------------------- /apps/codeimage/public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | https://app.codeimage.dev/ 8 | 2022-13-12 9 | 10 | https://app.codeimage.dev/assets/codeimage-logo-blue-svg-v1 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /apps/codeimage/src/assets/apple-icon-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/assets/apple-icon-180.png -------------------------------------------------------------------------------- /apps/codeimage/src/assets/codeimage-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/assets/codeimage-card.png -------------------------------------------------------------------------------- /apps/codeimage/src/assets/logo-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/codeimage/src/assets/styles/_inter.scss: -------------------------------------------------------------------------------- 1 | @use "inter-ui/default" as inter-ui-def with ( 2 | $inter-font-display: swap, 3 | $inter-font-path: 'inter-ui/Inter (web)' 4 | ); 5 | @use "inter-ui/variable" as inter-ui-var with ( 6 | $inter-font-display: swap, 7 | $inter-font-path: 'inter-ui/Inter (web)' 8 | ); 9 | 10 | @include inter-ui-def.weight-300(); 11 | @include inter-ui-def.weight-400(); 12 | @include inter-ui-def.weight-500(); 13 | @include inter-ui-def.weight-600(); 14 | @include inter-ui-def.weight-700(); 15 | @include inter-ui-def.weight-800(); 16 | @include inter-ui-var.default(); 17 | -------------------------------------------------------------------------------- /apps/codeimage/src/assets/styles/_reset.scss: -------------------------------------------------------------------------------- 1 | @import 'modern-normalize/modern-normalize.css'; 2 | 3 | // Tailwind Preflight 4 | // https://tailwindcss.com/docs/preflight#extending-preflight 5 | 6 | blockquote, 7 | dl, 8 | dd, 9 | h1, 10 | h2, 11 | h3, 12 | h4, 13 | h5, 14 | h6, 15 | hr, 16 | figure, 17 | p, 18 | pre { 19 | margin: 0; 20 | } 21 | 22 | h1, 23 | h2, 24 | h3, 25 | h4, 26 | h5, 27 | h6 { 28 | font-size: inherit; 29 | font-weight: inherit; 30 | } 31 | 32 | ol, 33 | ul { 34 | list-style: none; 35 | margin: 0; 36 | padding: 0; 37 | } 38 | -------------------------------------------------------------------------------- /apps/codeimage/src/assets/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import "reset"; 2 | @import "inter"; 3 | 4 | html, body { 5 | overflow: hidden; 6 | } 7 | 8 | * { 9 | box-sizing: border-box; 10 | } 11 | 12 | body { 13 | margin: 0; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | height: 100%; 17 | touch-action: none; 18 | position: relative; 19 | overscroll-behavior-y: none; 20 | } 21 | -------------------------------------------------------------------------------- /apps/codeimage/src/client.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface ImportMetaEnv { 4 | readonly VITE_PUBLIC_AUTH0_DOMAIN: string; 5 | readonly VITE_PUBLIC_AUTH0_CLIENT_ID: string; 6 | readonly VITE_PUBLIC_MY_CALLBACK_URL: string; 7 | readonly VITE_PUBLIC_AUTH0_AUDIENCE: string; 8 | readonly VITE_ENABLE_MSW: boolean; 9 | readonly VITE_MOCK_AUTH: boolean; 10 | readonly VITE_API_BASE_URL: string | null; 11 | readonly VITE_PRESET_LIMIT: number; 12 | readonly VITE_PRESET_LIMIT_GUEST: number; 13 | } 14 | 15 | interface ImportMeta { 16 | readonly env: ImportMetaEnv; 17 | } 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Changelog/Changelog.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const changelogList = style({ 4 | alignContent: 'flex-start', 5 | alignItems: 'flex-start', 6 | display: 'flex', 7 | flex: 'none', 8 | flexDirection: 'column', 9 | flexWrap: 'nowrap', 10 | gap: '80px', 11 | height: 'min-content', 12 | justifyContent: 'flex-start', 13 | overflow: 'visible', 14 | position: 'relative', 15 | width: '100%', 16 | }); 17 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/FeatureBadge.css.ts: -------------------------------------------------------------------------------- 1 | import {themeTokens, themeVars} from '@codeui/kit'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const badge = style({ 5 | fontSize: '10px', 6 | color: themeVars.brandLink, 7 | backgroundColor: themeVars.brandSoft, 8 | display: 'inline-flex', 9 | alignItems: 'center', 10 | justifyContent: 'center', 11 | padding: `${themeTokens.spacing['1']} ${themeTokens.spacing['2']}`, 12 | position: 'absolute', 13 | left: '100%', 14 | top: '50%', 15 | transform: `translateX(2px) translateY(-50%)`, 16 | borderRadius: themeTokens.radii.lg, 17 | whiteSpace: 'nowrap', 18 | }); 19 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/browserSvgs/chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/components/FeatureBadge/browserSvgs/chrome.png -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/browserSvgs/edge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/components/FeatureBadge/browserSvgs/edge.png -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/browserSvgs/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/components/FeatureBadge/browserSvgs/firefox.png -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/browserSvgs/opera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/codeimage/src/components/FeatureBadge/browserSvgs/opera.png -------------------------------------------------------------------------------- /apps/codeimage/src/components/FeatureBadge/compatibility/api.ts: -------------------------------------------------------------------------------- 1 | import {Identifier} from './types'; 2 | 3 | export function getWindowMdnCompatibilityApi() { 4 | return fetch( 5 | 'https://raw.githubusercontent.com/mdn/browser-compat-data/main/api/Window.json', 6 | ).then(res => res.json() as Promise<{api: {Window: Identifier['Window']}}>); 7 | } 8 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Footer/Footer.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {themeVars} from '@codeimage/ui'; 3 | 4 | export const wrapper = style({ 5 | position: 'absolute', 6 | bottom: 0, 7 | right: 0, 8 | zIndex: themeVars.zIndex['20'], 9 | color: themeVars.dynamicColors.descriptionTextColor, 10 | width: 'auto', 11 | }); 12 | 13 | export const link = style({ 14 | userSelect: 'none', 15 | ':hover': { 16 | textDecoration: 'underline', 17 | }, 18 | selectors: { 19 | '&:not([href])': { 20 | cursor: 'default', 21 | }, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/CheckCircle.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function CheckCircle(props: SvgIconProps) { 4 | return ( 5 | 6 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/Clipboard.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function ClipboardIcon(props: SvgIconProps) { 4 | return ( 5 | 6 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/CloseIcon.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export const CloseIcon = (props: SvgIconProps) => { 4 | return ( 5 | 11 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/CloudIcon.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function CloudIcon(props: SvgIconProps) { 4 | return ( 5 | 6 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/Code.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export const CodeIcon = (props: SvgIconProps) => { 4 | return ( 5 | 11 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/Collection.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function CollectionIcon(props: SvgIconProps) { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/ColorSwatch.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export const ColorSwatchIcon = (props: SvgIconProps) => { 4 | return ( 5 | 11 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/Download.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export const DownloadIcon = (props: SvgIconProps) => { 4 | return ( 5 | 6 | 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/EmptyCircle.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function EmptyCircle(props: SvgIconProps) { 4 | return ( 5 | 12 | 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/Pencil.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function PencilAlt(props: SvgIconProps) { 4 | return ( 5 | 11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/PlusIcon.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function PlusIcon(props: SvgIconProps) { 4 | return ( 5 | 6 | 7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Icons/ShareIcon.tsx: -------------------------------------------------------------------------------- 1 | import {SvgIcon, SvgIconProps} from '@codeimage/ui'; 2 | 3 | export function ShareIcon(props: SvgIconProps) { 4 | return ( 5 | 11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/LoadingOverlay/Skeleton.tsx: -------------------------------------------------------------------------------- 1 | export const Skeleton = () => { 2 | return
; 3 | }; 4 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/EditorForm.tsx: -------------------------------------------------------------------------------- 1 | import {Box} from '@codeimage/ui'; 2 | import {createPlatformProps} from '@core/hooks/createPlatformProps'; 3 | import {ParentComponent} from 'solid-js'; 4 | import * as styles from './EditorSidebar.css'; 5 | 6 | export const EditorForm: ParentComponent = props => { 7 | const platformProps = createPlatformProps(); 8 | 9 | return ( 10 | 11 | {props.children} 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/EditorSidebar.tsx: -------------------------------------------------------------------------------- 1 | import {DynamicSizedContainer} from '@ui/DynamicSizedContainer/DynamicSizedContainer'; 2 | import {EditorStyleForm} from './EditorStyleForm'; 3 | import {FrameStyleForm} from './FrameStyleForm'; 4 | import {PanelDivider} from './PanelDivider'; 5 | import {WindowStyleForm} from './WindowStyleForm'; 6 | 7 | export const EditorSidebar = () => { 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 |
23 | 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/PanelDivider.tsx: -------------------------------------------------------------------------------- 1 | import {VoidComponent} from 'solid-js'; 2 | import * as styles from './EditorSidebar.css'; 3 | 4 | export const PanelDivider: VoidComponent = () => { 5 | return
; 6 | }; 7 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/PanelHeader.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './EditorSidebar.css'; 2 | import {Text} from '@codeimage/ui'; 3 | import {Component} from 'solid-js'; 4 | 5 | interface PanelHeaderProps { 6 | label: string; 7 | } 8 | 9 | export const PanelHeader: Component = props => { 10 | return ( 11 |
12 | 13 | {props.label} 14 | 15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/SidebarPopover/SidebarPopover.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '@codeimage/ui'; 2 | import {responsiveStyle, themeTokens} from '@codeui/kit'; 3 | import {style} from '@vanilla-extract/css'; 4 | 5 | export const sidebarPopover = style([ 6 | { 7 | width: '360px', 8 | maxWidth: '360px', 9 | display: 'flex', 10 | flexDirection: 'column', 11 | gap: themeTokens.spacing['3'], 12 | }, 13 | responsiveStyle({ 14 | md: { 15 | maxWidth: 'initial', 16 | }, 17 | }), 18 | ]); 19 | 20 | export const experimentalFlag = style({ 21 | color: themeVars.dynamicColors.descriptionTextColor, 22 | fontSize: themeVars.fontSize.xs, 23 | }); 24 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/SidebarPopoverHost.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {scaffoldVars} from '../Scaffold/Scaffold.css'; 3 | 4 | export const wrapper = style({ 5 | marginLeft: `calc(${scaffoldVars.panelWidth} + 10px)`, 6 | position: 'absolute', 7 | maxWidth: scaffoldVars.panelWidth, 8 | height: '0px', 9 | width: '0px', 10 | zIndex: 5, 11 | }); 12 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/SidebarPopoverHost.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './SidebarPopoverHost.css'; 2 | 3 | export const SIDEBAR_POPOVER_HOST_ID = 'sidebar-popover-host'; 4 | 5 | export function SidebarPopoverHost() { 6 | return
; 7 | } 8 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/SuspenseEditorItem.tsx: -------------------------------------------------------------------------------- 1 | import {getEditorSyncAdapter} from '@codeimage/store/editor/createEditorSync'; 2 | import {JSX, ParentProps, Suspense} from 'solid-js'; 3 | 4 | export function SuspenseEditorItem( 5 | props: ParentProps<{fallback: JSX.Element}>, 6 | ) { 7 | const {loadedSnippet} = getEditorSyncAdapter()!; 8 | 9 | const render = () => { 10 | loadedSnippet(); 11 | return true; 12 | }; 13 | 14 | return ( 15 | {render() && props.children} 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/controls/TerminalControlField/TerminalControlField.css.ts: -------------------------------------------------------------------------------- 1 | import {textFieldStyles, themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const input = style([ 5 | textFieldStyles.baseField, 6 | { 7 | paddingLeft: themeVars.spacing['2'], 8 | paddingRight: themeVars.spacing['2'], 9 | flex: 1, 10 | justifyContent: 'space-between', 11 | userSelect: 'none', 12 | display: 'flex', 13 | alignItems: 'center', 14 | gap: themeVars.spacing['3'], 15 | }, 16 | ]); 17 | 18 | export const inputIcon = style({ 19 | flexShrink: 0, 20 | }); 21 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/controls/TerminalControlField/TerminalControlFieldSkeleton.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const wrapper = style({ 5 | height: '50px', 6 | display: 'flex', 7 | paddingLeft: themeVars.spacing['2'], 8 | paddingRight: themeVars.spacing['2'], 9 | borderRadius: themeVars.borderRadius.md, 10 | alignItems: 'center', 11 | }); 12 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/PropertyEditor/controls/TerminalControlField/TerminalControlFieldSkeleton.tsx: -------------------------------------------------------------------------------- 1 | import {SkeletonLine} from '@ui/Skeleton/Skeleton'; 2 | import * as styles from './TerminalControlFieldSkeleton.css'; 3 | 4 | export function TerminalControlSkeleton() { 5 | return ( 6 |
7 | 8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Scaffold/Canvas/Canvas.tsx: -------------------------------------------------------------------------------- 1 | import {FlowProps} from 'solid-js'; 2 | import * as styles from './Canvas.css'; 3 | 4 | // eslint-disable-next-line @typescript-eslint/ban-types 5 | type CanvasProps = {}; 6 | 7 | export function Canvas(props: FlowProps) { 8 | return ( 9 |
10 |
{props.children}
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Scaffold/Scaffold.css.ts: -------------------------------------------------------------------------------- 1 | import {createTheme, style} from '@vanilla-extract/css'; 2 | 3 | export const [scaffoldTheme, scaffoldVars] = createTheme({ 4 | toolbarHeight: '52px', 5 | panelWidth: '280px', 6 | virtualHeightFallback: '1vh', 7 | }); 8 | 9 | export const scaffold = style([ 10 | scaffoldTheme, 11 | { 12 | height: '100%', 13 | }, 14 | ]); 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Scaffold/Sidebar/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import {Box} from '@codeimage/ui'; 2 | import {ParentComponent} from 'solid-js'; 3 | import * as styles from './Sidebar.css'; 4 | import {SidebarVariants} from './Sidebar.css'; 5 | 6 | export const Sidebar: ParentComponent = props => { 7 | return ( 8 | 13 | {props.children} 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Terminal/GlassReflection/TerminalGlassReflection.tsx: -------------------------------------------------------------------------------- 1 | import {Box} from '@codeimage/ui'; 2 | import * as styles from './TerminalGlassReflection.css'; 3 | 4 | export const TerminalGlassReflection = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Terminal/MacOsTerminal/MacOsTerminalGrayTheme.tsx: -------------------------------------------------------------------------------- 1 | import {ParentComponent} from 'solid-js'; 2 | import {BaseTerminalProps} from '../TerminalHost'; 3 | import {MacOsTerminal} from './MacOsTerminal'; 4 | 5 | export const MacOsTerminalGrayTheme: ParentComponent< 6 | BaseTerminalProps 7 | > = props => { 8 | return ; 9 | }; 10 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Terminal/MacOsTerminal/MacOsTerminalOutlineTheme.tsx: -------------------------------------------------------------------------------- 1 | import {ParentComponent} from 'solid-js'; 2 | import {BaseTerminalProps} from '../TerminalHost'; 3 | import {MacOsTerminal} from './MacOsTerminal'; 4 | 5 | export const MacOsTerminalOutlineTheme: ParentComponent< 6 | BaseTerminalProps 7 | > = props => { 8 | return ; 9 | }; 10 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Terminal/Tabs/TabAddButton/TabAddButton.tsx: -------------------------------------------------------------------------------- 1 | import {VoidProps} from 'solid-js'; 2 | import {exportExclude as _exportExclude} from '@core/directives/exportExclude'; 3 | import {PlusIcon} from '../../../Icons/PlusIcon'; 4 | import * as styles from './TabAddButton.css'; 5 | 6 | export interface TabAddButtonProps { 7 | onAdd: () => void; 8 | disabled: boolean; 9 | } 10 | 11 | export function TabAddButton(props: VoidProps) { 12 | const exportExclude = _exportExclude; 13 | 14 | return ( 15 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Terminal/Tabs/TabIcon/TabIcon.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const tabIcon = style([ 5 | { 6 | display: 'inline-flex', 7 | marginRight: themeVars.spacing['2'], 8 | selectors: { 9 | '[data-lite] &': { 10 | fontSize: '11px', 11 | }, 12 | }, 13 | }, 14 | ]); 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/ThemeSwitcher/ThemeBoxSkeleton.css.ts: -------------------------------------------------------------------------------- 1 | import {backgroundColorVar, themeVars, withThemeMode} from '@codeimage/ui'; 2 | import {darkGrayScale} from '@codeimage/ui/themes/darkTheme'; 3 | import {style} from '@vanilla-extract/css'; 4 | import {themeBox} from './ThemeSwitcher.css'; 5 | 6 | export const wrapper = style([ 7 | themeBox, 8 | { 9 | selectors: { 10 | ...withThemeMode({ 11 | light: { 12 | vars: { 13 | [backgroundColorVar]: themeVars.backgroundColor.gray['100'], 14 | }, 15 | }, 16 | dark: { 17 | vars: { 18 | [backgroundColorVar]: darkGrayScale.gray2, 19 | }, 20 | }, 21 | }), 22 | }, 23 | }, 24 | ]); 25 | 26 | export const content = style({ 27 | padding: '20px', 28 | }); 29 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/ThemeSwitcher/ThemeBoxSkeleton.tsx: -------------------------------------------------------------------------------- 1 | import {SkeletonLine} from '@ui/Skeleton/Skeleton'; 2 | import {SkeletonDivider} from '@ui/Skeleton/SkeletonDivider'; 3 | import * as styles from './ThemeBoxSkeleton.css'; 4 | 5 | export function ThemeBoxSkeleton() { 6 | return ( 7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Toolbar/ExportContent.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const exportContent = style({ 4 | width: '240px', 5 | }); 6 | 7 | export const exportContentPopover = style({ 8 | maxWidth: 'unset', 9 | }); 10 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/Toolbar/SettingsDialog.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const dialogLeftPanel = style({ 5 | flex: '0 0 20%', 6 | borderRight: `1px solid ${themeVars.dynamicColors.dialog.titleBorderColor}`, 7 | display: 'flex', 8 | flexDirection: 'column', 9 | gap: themeVars.spacing['3'], 10 | marginRight: themeVars.spacing['12'], 11 | }); 12 | 13 | export const dialogContent = style({ 14 | flex: 1, 15 | width: '100%', 16 | minWidth: '0px', 17 | '@media': { 18 | 'screen and (max-width: 768px)': { 19 | width: '80vw', 20 | }, 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /apps/codeimage/src/components/UserBadge/UserBadge.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const badge = style({ 5 | backgroundColor: themeVars.backgroundColor.blue['600'], 6 | color: themeVars.backgroundColor.white, 7 | overflow: 'hidden', 8 | position: 'relative', 9 | cursor: 'pointer', 10 | }); 11 | 12 | export const badgePicture = style({ 13 | width: '100%', 14 | position: 'absolute', 15 | height: '100%', 16 | }); 17 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/constants/identity.ts: -------------------------------------------------------------------------------- 1 | export function identity(item: T): T { 2 | return item; 3 | } 4 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/constants/non-nullable.ts: -------------------------------------------------------------------------------- 1 | export function nonNullable( 2 | value: T | undefined | null, 3 | ): value is NonNullable { 4 | return value !== null && value !== undefined; 5 | } 6 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/constants/noop.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-empty-function 2 | export function noop(): void {} 3 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/constants/umami.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | umami: Umami; 4 | } 5 | } 6 | 7 | const isDev = import.meta.env.DEV; 8 | 9 | function getUmamiMock() { 10 | const umamiMock: Umami = {} as Umami; 11 | 12 | if (isDev) { 13 | umamiMock.track = (( 14 | event_name: string, 15 | event_data?: {[key: string]: string | number}, 16 | ) => { 17 | console.groupCollapsed(`[DEV] Umami track event`); 18 | console.log({ 19 | event_name, 20 | event_data, 21 | }); 22 | console.groupEnd(); 23 | }) as typeof umamiMock.track; 24 | } else { 25 | umamiMock.track = () => void 0; 26 | } 27 | 28 | return umamiMock; 29 | } 30 | 31 | export function getUmami() { 32 | return window?.umami ?? getUmamiMock(); 33 | } 34 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/directives/clickOutside.ts: -------------------------------------------------------------------------------- 1 | import {Accessor, onCleanup} from 'solid-js'; 2 | 3 | export default function clickOutside( 4 | el: HTMLElement, 5 | accessor: Accessor<() => void>, 6 | ) { 7 | const onClick = (e: MouseEvent) => 8 | !el.contains(e.target as Node | null) && accessor()?.(); 9 | document.body.addEventListener('click', onClick); 10 | 11 | onCleanup(() => document.body.removeEventListener('click', onClick)); 12 | } 13 | 14 | declare module 'solid-js' { 15 | // eslint-disable-next-line @typescript-eslint/no-namespace 16 | namespace JSX { 17 | interface Directives { 18 | clickOutside: () => void; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/helpers/string.ts: -------------------------------------------------------------------------------- 1 | export const toTitleCase = (str: string) => { 2 | return str.replace(/(^|\s)\S/g, t => t.toUpperCase()); 3 | }; 4 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/hooks/isMobile.tsx: -------------------------------------------------------------------------------- 1 | type AppMode = 'full' | 'mobile'; 2 | 3 | export function useModality(): AppMode { 4 | // const phone = useMediaQuery(`screen and (max-width: 768px)`); 5 | const phone = window.matchMedia('screen and (max-width: 768px)').matches; 6 | return phone ? 'mobile' : 'full'; 7 | } 8 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/modules/dnd/index.ts: -------------------------------------------------------------------------------- 1 | export {type DragEventParam, type DndRect} from './types'; 2 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/modules/dnd/types.ts: -------------------------------------------------------------------------------- 1 | import {DragEventHandler} from '@thisbeyond/solid-dnd/dist/types/drag-drop-context'; 2 | 3 | export interface DndRect { 4 | left?: number; 5 | top?: number; 6 | right?: number; 7 | bottom?: number; 8 | } 9 | 10 | export type DragEventParam = Parameters[0]; 11 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/operators/create-mutation-observer.ts: -------------------------------------------------------------------------------- 1 | import {Observable} from 'rxjs'; 2 | 3 | const createMutationObserverFactory = () => { 4 | return (element: HTMLElement, options?: MutationObserverInit) => 5 | new ReactiveMutationObserver(element, options); 6 | }; 7 | 8 | class ReactiveMutationObserver extends Observable< 9 | ReadonlyArray 10 | > { 11 | constructor(element: HTMLElement, options?: MutationObserverInit) { 12 | let observer: MutationObserver; 13 | 14 | super(subscriber => { 15 | observer = new MutationObserver(entries => subscriber.next(entries)); 16 | observer.observe(element, options); 17 | return () => observer.disconnect(); 18 | }); 19 | } 20 | } 21 | 22 | export const mutationObserverFactory$ = createMutationObserverFactory(); 23 | -------------------------------------------------------------------------------- /apps/codeimage/src/core/operators/create-resize-observer.ts: -------------------------------------------------------------------------------- 1 | import {Observable} from 'rxjs'; 2 | 3 | const createResizeObserverFactory = () => { 4 | return (element: HTMLElement, options?: ResizeObserverOptions) => 5 | new ReactiveResizeObserver(element, options); 6 | }; 7 | 8 | class ReactiveResizeObserver extends Observable< 9 | ReadonlyArray 10 | > { 11 | constructor(element: HTMLElement, options?: ResizeObserverOptions) { 12 | let observer: ResizeObserver; 13 | 14 | super(subscriber => { 15 | observer = new ResizeObserver(entries => subscriber.next(entries)); 16 | observer.observe(element, options); 17 | return () => observer.disconnect(); 18 | }); 19 | } 20 | } 21 | 22 | export const resizeObserverFactory$ = createResizeObserverFactory(); 23 | -------------------------------------------------------------------------------- /apps/codeimage/src/data-access/api.ts: -------------------------------------------------------------------------------- 1 | import * as projectApi from './project'; 2 | 3 | export const API = { 4 | project: projectApi, 5 | } as const; 6 | -------------------------------------------------------------------------------- /apps/codeimage/src/hooks/use-hotkey.ts: -------------------------------------------------------------------------------- 1 | import tinykeys, {KeyBindingMap, KeyBindingOptions} from 'tinykeys'; 2 | import {useModality} from '../core/hooks/isMobile'; 3 | import {noop} from '../core/constants/noop'; 4 | import {onCleanup} from 'solid-js'; 5 | 6 | export function useHotkey( 7 | target: Window | HTMLElement, 8 | keyBindingMap: KeyBindingMap, 9 | options?: KeyBindingOptions, 10 | ): () => void { 11 | const modality = useModality(); 12 | 13 | if (modality === 'mobile') return noop; 14 | 15 | const unsubscribe = tinykeys(target, keyBindingMap, options); 16 | onCleanup(() => unsubscribe()); 17 | 18 | return unsubscribe; 19 | } 20 | -------------------------------------------------------------------------------- /apps/codeimage/src/hooks/use-indexed-db.tsx: -------------------------------------------------------------------------------- 1 | import * as idb from 'idb-keyval'; 2 | 3 | export function useIdb() { 4 | return idb; 5 | } 6 | -------------------------------------------------------------------------------- /apps/codeimage/src/i18n/ notFound.ts: -------------------------------------------------------------------------------- 1 | export const notFound = { 2 | it: { 3 | notFound: { 4 | title: '404', 5 | description: 'La risorsa che stai cercando non esiste', 6 | goToHome: 'Torna alla home', 7 | }, 8 | }, 9 | en: { 10 | notFound: { 11 | title: '404', 12 | description: 'The resource you are looking for does not exists', 13 | goToHome: 'Go to home', 14 | }, 15 | }, 16 | de: { 17 | notFound: { 18 | title: '404', 19 | description: 'The resource you are looking for does not exists', 20 | goToHome: 'Go to home', 21 | }, 22 | }, 23 | es: { 24 | notFound: { 25 | title: '404', 26 | description: 'The resource you are looking for does not exists', 27 | goToHome: 'Go to home', 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /apps/codeimage/src/i18n/bottombar.ts: -------------------------------------------------------------------------------- 1 | export const bottomBar = { 2 | it: { 3 | bottomBar: { 4 | themes: 'Temi', 5 | styles: 'Stili', 6 | editor: 'Editor', 7 | }, 8 | }, 9 | en: { 10 | bottomBar: { 11 | themes: 'Themes', 12 | styles: 'Styles', 13 | editor: 'Editor', 14 | }, 15 | }, 16 | de: { 17 | bottomBar: { 18 | themes: 'Themen', 19 | styles: 'Stile', 20 | editor: 'Editor', 21 | }, 22 | }, 23 | es: { 24 | bottomBar: { 25 | themes: 'Temas', 26 | styles: 'Estilos', 27 | editor: 'Editor', 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /apps/codeimage/src/mocks/browser.ts: -------------------------------------------------------------------------------- 1 | import {setupWorker} from 'msw'; 2 | import {db} from './db'; 3 | import {persistMswjs} from './persist'; 4 | import projectHandlers from './projectMockHandlers'; 5 | 6 | export const worker = setupWorker(...projectHandlers); 7 | persistMswjs(db); 8 | -------------------------------------------------------------------------------- /apps/codeimage/src/pages/Dashboard/components/ProjectItemSkeleton/ProjectItemSkeleton.css.ts: -------------------------------------------------------------------------------- 1 | import {backgroundColorVar, themeVars, withThemeMode} from '@codeimage/ui'; 2 | import {darkGrayScale} from '@codeimage/ui/themes/darkTheme'; 3 | import {style} from '@vanilla-extract/css'; 4 | import {item} from '../ProjectItem/ProjectItem.css'; 5 | 6 | export const itemSkeleton = style([ 7 | item, 8 | { 9 | selectors: { 10 | ...withThemeMode({ 11 | light: { 12 | vars: { 13 | [backgroundColorVar]: themeVars.backgroundColor.gray['100'], 14 | }, 15 | }, 16 | dark: { 17 | vars: { 18 | [backgroundColorVar]: darkGrayScale.gray2, 19 | }, 20 | }, 21 | }), 22 | }, 23 | }, 24 | ]); 25 | -------------------------------------------------------------------------------- /apps/codeimage/src/pages/Dashboard/components/ProjectItemSkeleton/ProjectItemSkeleton.tsx: -------------------------------------------------------------------------------- 1 | import {SkeletonLine} from '@ui/Skeleton/Skeleton'; 2 | import {SkeletonDivider} from '@ui/Skeleton/SkeletonDivider'; 3 | import * as styles from './ProjectItemSkeleton.css'; 4 | 5 | export function ProjectItemSkeleton() { 6 | return ( 7 |
  • 8 | 9 | 10 | 11 | 12 |
  • 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/pages/Dashboard/components/ProjectToolbar/ProjectToolbar.css.ts: -------------------------------------------------------------------------------- 1 | import {textStyles, themeVars} from '@codeimage/ui'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const title = style([ 5 | textStyles.fontSize['2xl'], 6 | textStyles.fontWeight.medium, 7 | ]); 8 | 9 | export const container = style({ 10 | marginBottom: themeVars.spacing['6'], 11 | 12 | '@media': { 13 | 'screen and (max-width: 768px)': { 14 | marginBottom: themeVars.spacing['2'], 15 | }, 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/pages/Editor/Editor.tsx: -------------------------------------------------------------------------------- 1 | import {EditorSyncProvider} from '@codeimage/store/editor/createEditorSync'; 2 | import {useParams} from '@solidjs/router'; 3 | import {lazy} from 'solid-js'; 4 | 5 | const App = lazy(() => import('./App')); 6 | 7 | export default function Editor() { 8 | const params = useParams(); 9 | return ( 10 | 11 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /apps/codeimage/src/state/frame/model.ts: -------------------------------------------------------------------------------- 1 | export interface FrameState { 2 | background: string | null; 3 | padding: number; 4 | radius: number; 5 | visible: boolean; 6 | opacity: number; 7 | autoWidth: boolean; 8 | scale: number; 9 | width: number; 10 | height: number; 11 | aspectRatio: string | null; 12 | } 13 | 14 | export type PersistedFrameState = Pick< 15 | FrameState, 16 | 'background' | 'padding' | 'radius' | 'visible' | 'opacity' 17 | >; 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/state/index.ts: -------------------------------------------------------------------------------- 1 | import {Container} from 'statebuilder'; 2 | import {createRoot} from 'solid-js'; 3 | 4 | const container = createRoot(() => Container.create()); 5 | 6 | export const provideAppState: typeof container.get = state => 7 | container.get(state); 8 | -------------------------------------------------------------------------------- /apps/codeimage/src/state/plugins/unique-id.ts: -------------------------------------------------------------------------------- 1 | import {createUniqueId as $createUniqueId} from 'solid-js'; 2 | 3 | export function createUniqueId(v = 0): string { 4 | const id = $createUniqueId(); 5 | return `${id}$${v ?? 0}`; 6 | } 7 | 8 | export function versionateId(id: string): string { 9 | const [uid, version = null] = id.split('$'); 10 | if (!uid || version === null) { 11 | console.warn(`[DEV] Unable to versionate ${id} id`); 12 | return id; 13 | } 14 | return `${uid}$${parseInt(version, 10) + 1}`; 15 | } 16 | 17 | export const generateUid = (a = '') => { 18 | return a 19 | ? /* eslint-disable no-bitwise */ 20 | ((Number(a) ^ (Math.random() * 16)) >> (Number(a) / 4)).toString(16) 21 | : `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, generateUid); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/codeimage/src/state/presets/types.ts: -------------------------------------------------------------------------------- 1 | import {GetPresetByIdApi} from '@codeimage/api/api-types'; 2 | 3 | export type ApiPreset = GetPresetByIdApi['response']; 4 | export type PresetData = ApiPreset['data']; 5 | 6 | export type Preset = Omit & { 7 | data: PresetData; 8 | }; 9 | 10 | export type PresetsArray = Array; 11 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/ExperimentalChip/ExperimentalChip.css.ts: -------------------------------------------------------------------------------- 1 | import {themeTokens, themeVars} from '@codeui/kit'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const chip = style({ 5 | fontSize: '14px', 6 | color: themeVars.brandLink, 7 | backgroundColor: themeVars.brandSoftAccentActive, 8 | border: `1px solid ${themeVars.brandSoft}`, 9 | display: 'inline-flex', 10 | alignItems: 'center', 11 | justifyContent: 'center', 12 | padding: `${themeTokens.spacing['2']} ${themeTokens.spacing['3']}`, 13 | borderRadius: themeTokens.radii.lg, 14 | whiteSpace: 'nowrap', 15 | gap: themeTokens.spacing['2'], 16 | marginLeft: themeTokens.spacing['3'], 17 | }); 18 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/ExperimentalChip/ExperimentalChip.tsx: -------------------------------------------------------------------------------- 1 | import {ExperimentalIcon} from '@ui/ExperimentalFeatureTooltip/ExperimentalFeatureTooltip'; 2 | import * as styles from './ExperimentalChip.css'; 3 | 4 | export function ExperimentalChip() { 5 | return ( 6 | 7 | 8 | Experimental 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/ExperimentalFeatureTooltip/ExperimentalFeatureTooltip.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const tooltip = style({ 4 | maxWidth: '350px', 5 | }); 6 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/GitHubLoginButton/GitHubLoginButton.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const button = style({ 4 | backgroundColor: 'rgb(47, 51, 55)', 5 | color: 'rgb(255, 255, 255)', 6 | border: '1px solid rgb(47, 51, 55)', 7 | cursor: 'pointer', 8 | 9 | ':hover': { 10 | background: 'rgb(29,33,35)', 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/Skeleton/SkeletonDivider.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from '@ui/Skeleton/Skeleton.css'; 2 | import {assignInlineVars} from '@vanilla-extract/dynamic'; 3 | import {VoidProps} from 'solid-js'; 4 | 5 | interface SkeletonDividerProps { 6 | height: string; 7 | } 8 | 9 | export function SkeletonDivider(props: VoidProps) { 10 | return ( 11 |
    17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /apps/codeimage/src/ui/snackbarHostAppStyle.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const snackbarHostAppStyleCss = style({ 4 | inset: 'calc(20px + 60px) !important', 5 | }); 6 | -------------------------------------------------------------------------------- /apps/codeimage/src/umami.d.ts: -------------------------------------------------------------------------------- 1 | declare const umami: Umami; 2 | 3 | // https://umami.is/docs/tracker-functions 4 | interface Umami { 5 | track(view_properties?: {website: string; [key: string]: string}): void; 6 | track( 7 | event_name: string, 8 | event_data?: {[key: string]: string | number}, 9 | ): void; 10 | } 11 | -------------------------------------------------------------------------------- /apps/codeimage/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "importHelpers": true, 6 | "resolveJsonModule": true, 7 | "jsxImportSource": "solid-js", 8 | "types": [ 9 | "vite/client", 10 | "vite-plugin-pwa/client", 11 | "@types/mdx" 12 | ], 13 | "lib": [ 14 | "ESNext", 15 | "dom", 16 | "dom.iterable", 17 | "es2019", 18 | "WebWorker" 19 | ], 20 | "paths": { 21 | "@codeimage/store/*": [ 22 | "./src/state/*" 23 | ], 24 | "@core/*": [ 25 | "./src/core/*" 26 | ], 27 | "@ui/*": [ 28 | "./src/ui/*" 29 | ] 30 | } 31 | }, 32 | "include": [ 33 | "./src/**/*", 34 | "./scripts/**/*" 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /apps/codeimage/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { 4 | "source": "/(.*)", 5 | "destination": "/" 6 | } 7 | ], 8 | "github": { 9 | "enabled": false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/website/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | dist 3 | .solid 4 | .output 5 | .vercel 6 | .netlify 7 | netlify 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | *.launch 17 | .settings/ 18 | 19 | # Temp 20 | gitignore 21 | 22 | # System Files 23 | .DS_Store 24 | Thumbs.db 25 | -------------------------------------------------------------------------------- /apps/website/.lighthouserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ci": { 3 | "collect": { 4 | "url": [ 5 | "http://localhost/" 6 | ], 7 | "staticDistDir": "dist/public", 8 | "numberOfRuns": 3 9 | }, 10 | "upload": { 11 | "target": "temporary-public-storage" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/website/add-css-stylesheet.ts: -------------------------------------------------------------------------------- 1 | import {readFileSync, writeFileSync} from 'node:fs'; 2 | import {join} from 'node:path'; 3 | 4 | import manifest from './dist/public/manifest.json'; 5 | 6 | const htmlSourcePath = join('./dist/public/index.html'); 7 | 8 | const htmlSource = readFileSync(join('./dist/public/index.html'), { 9 | encoding: 'utf-8', 10 | }); 11 | 12 | let patchedSource = htmlSource; 13 | 14 | const entry = manifest['style.css'].file; 15 | 16 | patchedSource = patchedSource.replace( 17 | ``, 18 | ``, 19 | ); 20 | 21 | writeFileSync(htmlSourcePath, patchedSource); 22 | -------------------------------------------------------------------------------- /apps/website/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/apple-touch-icon.png -------------------------------------------------------------------------------- /apps/website/public/brand/codeimage_logo_final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/brand/codeimage_logo_final.png -------------------------------------------------------------------------------- /apps/website/public/example-codeimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/example-codeimage.png -------------------------------------------------------------------------------- /apps/website/public/favicon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/favicon-192x192.png -------------------------------------------------------------------------------- /apps/website/public/favicon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/favicon-512x512.png -------------------------------------------------------------------------------- /apps/website/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/favicon.ico -------------------------------------------------------------------------------- /apps/website/public/fonts/Mona-Sans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/fonts/Mona-Sans-Bold.woff2 -------------------------------------------------------------------------------- /apps/website/public/fonts/Mona-Sans-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/fonts/Mona-Sans-Medium.woff2 -------------------------------------------------------------------------------- /apps/website/public/fonts/Mona-Sans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/fonts/Mona-Sans-Regular.woff2 -------------------------------------------------------------------------------- /apps/website/public/fonts/Mona-Sans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/fonts/Mona-Sans-SemiBold.woff2 -------------------------------------------------------------------------------- /apps/website/public/fonts/Mona-Sans.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/fonts/Mona-Sans.woff2 -------------------------------------------------------------------------------- /apps/website/public/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/img.png -------------------------------------------------------------------------------- /apps/website/public/landing/codeimage_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/landing/codeimage_preview.png -------------------------------------------------------------------------------- /apps/website/public/landing/codeimage_preview_desktop.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/landing/codeimage_preview_desktop.webp -------------------------------------------------------------------------------- /apps/website/public/landing/codeimage_preview_lite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/landing/codeimage_preview_lite.png -------------------------------------------------------------------------------- /apps/website/public/landing/codeimage_preview_mobile.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/landing/codeimage_preview_mobile.webp -------------------------------------------------------------------------------- /apps/website/public/landing/codeimage_preview_mobile_ultra.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/landing/codeimage_preview_mobile_ultra.webp -------------------------------------------------------------------------------- /apps/website/public/manifest.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "icons": [ 3 | { "src": "/favicon-192x192.png", "type": "image/png", "sizes": "192x192" }, 4 | { "src": "/favicon-512x512.png", "type": "image/png", "sizes": "512x512" } 5 | ] 6 | } -------------------------------------------------------------------------------- /apps/website/public/projects-showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/projects-showcase.png -------------------------------------------------------------------------------- /apps/website/public/projects-showcase.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/public/projects-showcase.webp -------------------------------------------------------------------------------- /apps/website/public/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | https://codeimage.dev/ 12 | 2022-12-13T21:09:45+00:00 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/website/src/components/CodeImageLogo/CodeImageLogo.tsx: -------------------------------------------------------------------------------- 1 | import {JSX} from 'solid-js'; 2 | import {useAssets} from 'solid-js/web'; 3 | import logo from './codeimage-logo-blue-xxxs.webp'; 4 | 5 | export const CodeImageLogoSvgRemote = (props: JSX.IntrinsicElements['img']) => { 6 | useAssets(() => ); 7 | 8 | return ( 9 | 10 | 11 | {'CodeImage 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /apps/website/src/components/CodeImageLogo/codeimage-logo-blue-low-v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/src/components/CodeImageLogo/codeimage-logo-blue-low-v1.png -------------------------------------------------------------------------------- /apps/website/src/components/CodeImageLogo/codeimage-logo-blue-xxxs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riccardoperra/codeimage/83d3875ac996d6d8b14c147c5bc9a4c9ea35d0db/apps/website/src/components/CodeImageLogo/codeimage-logo-blue-xxxs.webp -------------------------------------------------------------------------------- /apps/website/src/components/Landing/EditorSteps/CodeEditor/CodeEditor.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const loading = style({ 4 | position: 'absolute', 5 | right: '1rem', 6 | top: '1rem', 7 | }); 8 | 9 | export const preview = style({ 10 | fontFamily: 'Jetbrains Mono, monospace', 11 | backgroundColor: 'unset', 12 | color: 'white', 13 | width: '100%', 14 | height: '100%', 15 | overflow: 'hidden', 16 | margin: 0, 17 | }); 18 | -------------------------------------------------------------------------------- /apps/website/src/components/Landing/EditorSteps/CodeEditor/CodeEditorPreviewBlock.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './CodeEditor.css'; 2 | 3 | interface CodeEditorPreviewBlockProps { 4 | code: string; 5 | } 6 | 7 | export function CodeEditorPreviewBlock(props: CodeEditorPreviewBlockProps) { 8 | return
    ;
     9 | }
    10 | 
    
    
    --------------------------------------------------------------------------------
    /apps/website/src/components/Landing/EditorSteps/CodeEditor/editor-core.ts:
    --------------------------------------------------------------------------------
     1 | import {EditorState} from '@codemirror/state';
     2 | import {EditorView} from '@codemirror/view';
     3 | import {
     4 |   createCodeMirror,
     5 |   createCompartmentExtension,
     6 |   createEditorControlledValue,
     7 |   createEditorReadonly,
     8 |   createLazyCompartmentExtension,
     9 | } from 'solid-codemirror';
    10 | import {theme} from './editor-theme';
    11 | 
    12 | export {
    13 |   createEditorReadonly,
    14 |   createLazyCompartmentExtension,
    15 |   createEditorControlledValue,
    16 |   createCodeMirror,
    17 |   EditorView,
    18 |   createCompartmentExtension,
    19 |   EditorState,
    20 |   theme,
    21 | };
    22 | 
    
    
    --------------------------------------------------------------------------------
    /apps/website/src/components/Landing/EditorSteps/CodeEditor/lang-javascript-plugin.ts:
    --------------------------------------------------------------------------------
    1 | import {
    2 |   javascriptLanguage,
    3 |   jsxLanguage as $jsxLanguage,
    4 | } from '@codemirror/lang-javascript';
    5 | 
    6 | export const jsxLanguage = [javascriptLanguage, $jsxLanguage];
    7 | 
    
    
    --------------------------------------------------------------------------------
    /apps/website/src/components/Landing/EditorSteps/EditorScene/CircularProgress/CircularProgress.css.ts:
    --------------------------------------------------------------------------------
     1 | import {style} from '@vanilla-extract/css';
     2 | 
     3 | export const container = style({
     4 |   display: 'flex',
     5 |   alignItems: 'center',
     6 |   width: '100%',
     7 |   height: '100%',
     8 |   justifyContent: 'center',
     9 |   position: 'relative',
    10 | });
    11 | 
    12 | export const progressBar = style({
    13 |   position: 'absolute',
    14 |   top: 0,
    15 |   left: 0,
    16 |   right: 0,
    17 |   height: '10px',
    18 |   backgroundColor: 'rgb(255, 255, 255, 1)',
    19 |   width: '100%',
    20 |   transform: 'scaleX(0)',
    21 |   transformOrigin: '0%',
    22 | });
    23 | 
    
    
    --------------------------------------------------------------------------------
    /apps/website/src/components/Landing/EditorSteps/EditorScene/CircularProgress/CircularProgress.tsx:
    --------------------------------------------------------------------------------
     1 | import {Ref} from 'solid-js';
     2 | import * as styles from './CircularProgress.css';
     3 | 
     4 | interface CircularProgressProps {
     5 |   progress: number;
     6 |   ref: Ref;
     7 | }
     8 | 
     9 | export function CircularProgress(props: CircularProgressProps) {
    10 |   return (
    11 |     
    12 |
    13 |
    14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /apps/website/src/components/Landing/EditorSteps/EditorScene/GlassReflection/TerminalGlassReflection.tsx: -------------------------------------------------------------------------------- 1 | import {Box} from '@codeimage/ui'; 2 | import * as styles from './TerminalGlassReflection.css'; 3 | 4 | export const TerminalGlassReflection = () => { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /apps/website/src/components/Landing/EditorSteps/EditorScene/ScrollDownMouse/ScrollDownMouse.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './ScrollDownMouse.css'; 2 | 3 | export function ScrollDownMouse() { 4 | return
    ; 5 | } 6 | -------------------------------------------------------------------------------- /apps/website/src/components/Umami/UmamiScript.tsx: -------------------------------------------------------------------------------- 1 | import {NoHydration} from 'solid-js/web'; 2 | 3 | export function UmamiScript() { 4 | const websiteId = import.meta.env.VITE_UMAMI_WEBSITE_ID; 5 | const scriptSrc = import.meta.env.VITE_UMAMI_SCRIPT_SRC; 6 | 7 | if (!websiteId || !scriptSrc) return null; 8 | 9 | return ( 10 | 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/highlight/dev/themeStore.ts: -------------------------------------------------------------------------------- 1 | import {createSignal} from 'solid-js'; 2 | import {AVAILABLE_THEMES} from './Editor/themes'; 3 | 4 | export function createThemeStore() { 5 | const [themeId, internalSetThemeId] = createSignal(getInitialValue()); 6 | 7 | function getInitialValue() { 8 | return ( 9 | localStorage.getItem('highlight_theme_default') ?? AVAILABLE_THEMES[0].id 10 | ); 11 | } 12 | 13 | const theme = () => AVAILABLE_THEMES.find(theme => theme.id === themeId())!; 14 | 15 | return [ 16 | theme, 17 | (themeId: string) => { 18 | internalSetThemeId(themeId); 19 | localStorage.setItem('highlight_theme_default', themeId); 20 | }, 21 | ] as const; 22 | } 23 | -------------------------------------------------------------------------------- /packages/highlight/dev/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noUnusedLocals": true, 5 | "sourceMap": true, 6 | "jsx": "preserve", 7 | "resolveJsonModule": true, 8 | "jsxImportSource": "solid-js", 9 | "preserveSymlinks": true, 10 | "types": [ 11 | "@types/node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/highlight/dev/vite.config.ts: -------------------------------------------------------------------------------- 1 | import {vanillaExtractPlugin} from '@codeimage/vanilla-extract'; 2 | import {defineConfig, Plugin} from 'vite'; 3 | import solidPlugin from 'vite-plugin-solid'; 4 | import {withStaticVercelPreview} from '../../../scripts/vercel-output-build'; 5 | 6 | export const viteConfig = defineConfig({ 7 | plugins: [ 8 | vanillaExtractPlugin() as unknown as Plugin, 9 | solidPlugin(), 10 | withStaticVercelPreview() as unknown as Plugin, 11 | ], 12 | optimizeDeps: { 13 | // Add both @codemirror/state and @codemirror/view to included deps to optimize 14 | include: [ 15 | '@codemirror/state', 16 | '@codemirror/view', 17 | '@codemirror/lang-javascript', 18 | ], 19 | }, 20 | }); 21 | 22 | export default viteConfig; 23 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './custom-theme'; 2 | export * from './build-theme'; 3 | export * from './define-editor-theme'; 4 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/plugins/cursor-style.ts: -------------------------------------------------------------------------------- 1 | import {EditorView} from '@codemirror/view'; 2 | 3 | export interface StyledCursorOptions { 4 | color: string; 5 | } 6 | 7 | export function styledCursor(options: StyledCursorOptions) { 8 | return EditorView.theme({ 9 | '.cm-cursor, .cm-dropCursor': {borderLeftColor: options.color}, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/plugins/line-numbers-style.ts: -------------------------------------------------------------------------------- 1 | import {EditorView} from '@codemirror/view'; 2 | 3 | export interface StyledLineNumbersOptions { 4 | color: string; 5 | } 6 | 7 | export function styledLineNumbers(options: StyledLineNumbersOptions) { 8 | return EditorView.theme({ 9 | '.cm-lineNumbers .cm-gutterElement': {color: options.color}, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/plugins/selection-style.ts: -------------------------------------------------------------------------------- 1 | import {EditorView} from '@codemirror/view'; 2 | 3 | export interface StyledSelectionOptions { 4 | backgroundColor: string; 5 | color: string; 6 | activeLine?: string; 7 | } 8 | 9 | export function styledSelection(options: StyledSelectionOptions) { 10 | return EditorView.theme({ 11 | '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': 12 | { 13 | background: options.backgroundColor, 14 | }, 15 | '.cm-activeLine': { 16 | backgroundColor: options.activeLine ?? 'unset', 17 | }, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/arcDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {arcDark, palette} from './arcDark'; 3 | 4 | export const arcDarkTheme = createTheme({ 5 | id: 'arkDark', 6 | editorTheme: arcDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'Arc Dark', 10 | previewBackground: `linear-gradient(to right bottom, #393939, #343435, #2f3030, #2b2b2c, #262727)`, 11 | terminal: { 12 | main: palette.background, 13 | text: palette.grayLight, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/auraDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {aura, palette} from './aura'; 3 | 4 | export const auraTheme = createTheme({ 5 | id: 'aura', 6 | editorTheme: aura, 7 | properties: { 8 | darkMode: true, 9 | label: 'Aura Dark', 10 | previewBackground: `linear-gradient(135deg, rgba(171,73,222,1) 0%,rgba(73,84,222,1) 100%)`, 11 | terminal: { 12 | main: palette.background, 13 | text: palette.purple, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/coldarkCold/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {coldarkCold} from './coldark-cold'; 3 | 4 | export const coldarkColdTheme = createTheme({ 5 | id: 'coldarkCold', 6 | editorTheme: coldarkCold, 7 | properties: { 8 | darkMode: false, 9 | label: 'Coldark Cold', 10 | previewBackground: 11 | 'linear-gradient(140deg, rgb(165, 142, 251), rgb(233, 191, 248))', 12 | terminal: { 13 | main: '#fae7ff', 14 | text: '#111b27', 15 | tabs: { 16 | inactiveTabBackground: '#e5d4e9', 17 | }, 18 | }, 19 | }, 20 | } as const); 21 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/coldarkDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {coldarkDark, palette} from './coldark-dark'; 3 | 4 | export const coldarkDarkTheme = createTheme({ 5 | id: 'coldarkDark', 6 | editorTheme: coldarkDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'Coldark Dark', 10 | previewBackground: 11 | 'linear-gradient(to left top, #162b46, #192c45, #1c2e45, #1e2f44, #213043)', 12 | terminal: { 13 | main: '#111b27', 14 | text: palette.white, 15 | }, 16 | }, 17 | } as const); 18 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/dracula/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {dracula, palette} from './dracula'; 3 | 4 | export const draculaTheme = createTheme({ 5 | id: 'dracula', 6 | editorTheme: dracula, 7 | properties: { 8 | darkMode: true, 9 | label: 'Dracula', 10 | previewBackground: `linear-gradient(135deg, rgba(171,73,222,1) 0%,rgba(73,84,222,1) 100%)`, 11 | terminal: { 12 | main: palette.background, 13 | text: palette.purple, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/duotoneDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {duotoneDark, palette} from './duotoneDark'; 3 | 4 | export const duotoneDarkTheme = createTheme({ 5 | id: 'duotoneDark', 6 | editorTheme: duotoneDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'Duotone Dark', 10 | previewBackground: palette.salmon, 11 | terminal: { 12 | main: '#2D2B38', 13 | text: palette.white, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/duotoneSea/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {duotoneSea} from './duotoneSea'; 3 | 4 | export const duotoneSeaTheme = createTheme({ 5 | id: 'duotoneSea', 6 | editorTheme: duotoneSea, 7 | properties: { 8 | darkMode: true, 9 | label: 'Duotone Sea', 10 | previewBackground: 11 | 'linear-gradient(to right bottom, #1e737e, #186b76, #13636d, #0d5b65, #06535d)', 12 | terminal: { 13 | main: '#1D262F', 14 | text: '#D6E9FF', 15 | }, 16 | }, 17 | } as const); 18 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/fleetDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {fleetDark, palette} from './fleetDark'; 3 | 4 | export const fleetDarkTheme = createTheme({ 5 | id: 'fleetDark', 6 | editorTheme: fleetDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'Fleet Dark', 10 | previewBackground: `linear-gradient(152deg, rgb(87% 61% 43%) 0%, rgb(49% 14% 95%) 100%)`, 11 | terminal: { 12 | main: palette.background, 13 | text: '#fff', 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/githubDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import libColors from '@primer/primitives/dist/ts/colors/dark'; 3 | import {githubDark} from './githubDark'; 4 | 5 | export const githubDarkTheme = createTheme({ 6 | id: 'githubDark', 7 | editorTheme: githubDark, 8 | properties: { 9 | darkMode: true, 10 | label: 'GitHub Dark', 11 | previewBackground: 'linear-gradient(135deg, #E233FF 0%, #FF6B00 100%)', 12 | terminal: { 13 | main: libColors.codemirror.bg, 14 | text: libColors.codemirror.text, 15 | tabs: { 16 | inactiveTabBackground: libColors.scale.gray[7], 17 | }, 18 | }, 19 | }, 20 | } as const); 21 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/githubDarkDimmed/index.ts: -------------------------------------------------------------------------------- 1 | import libColors from '@primer/primitives/dist/ts/colors/dark_dimmed'; 2 | import {createTheme} from '../../core'; 3 | import {githubDarkDimmed} from './githubDarkDimmed'; 4 | 5 | export const githubDarkDimmedTheme = createTheme({ 6 | id: 'githubDarkDimmed', 7 | editorTheme: githubDarkDimmed, 8 | properties: { 9 | darkMode: true, 10 | label: 'GitHub Dark Dimmed', 11 | previewBackground: 12 | 'linear-gradient(140deg, rgb(241 160 61), rgb(192 74 65), rgb(115, 52, 52))', 13 | terminal: { 14 | main: libColors.codemirror.bg, 15 | text: libColors.codemirror.text, 16 | tabs: { 17 | inactiveTabBackground: libColors.scale.gray[7], 18 | }, 19 | }, 20 | }, 21 | } as const); 22 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/githubLight/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import libColors from '@primer/primitives/dist/ts/colors/light'; 3 | import {githubLight} from './githubLight'; 4 | 5 | export const githubLightTheme = createTheme({ 6 | id: 'githubLight', 7 | editorTheme: githubLight, 8 | properties: { 9 | darkMode: false, 10 | label: 'GitHub Light', 11 | previewBackground: 12 | 'linear-gradient(-45deg, rgba(73,84,222,1) 0%,rgba(73,221,216,1) 100%)', 13 | terminal: { 14 | main: libColors.codemirror.bg, 15 | text: libColors.codemirror.text, 16 | tabs: { 17 | inactiveTabBackground: libColors.scale.gray[1], 18 | }, 19 | }, 20 | }, 21 | } as const); 22 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/holi/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {holi} from './holi'; 3 | 4 | export const holiTheme = createTheme({ 5 | id: 'holiTheme', 6 | editorTheme: holi, 7 | properties: { 8 | darkMode: true, 9 | label: 'Holi Dark', 10 | previewBackground: '#122f6d', 11 | terminal: { 12 | main: '#030314', 13 | text: '#FFF', 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/light/index.ts: -------------------------------------------------------------------------------- 1 | export * from './light'; 2 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/light/light.ts: -------------------------------------------------------------------------------- 1 | import {defaultHighlightStyle, syntaxHighlighting} from '@codemirror/language'; 2 | import {createTheme} from '../../core'; 3 | 4 | export const lightTheme = createTheme({ 5 | id: 'oneLight', 6 | editorTheme: [syntaxHighlighting(defaultHighlightStyle, {fallback: true})], 7 | properties: { 8 | darkMode: false, 9 | label: 'One light', 10 | previewBackground: 'linear-gradient(62deg, #8EC5FC 0%, #E0C3FC 100%)', 11 | terminal: { 12 | main: '#ffffff', 13 | text: '#000000', 14 | tabs: { 15 | inactiveTabBackground: '#e5e5e5', 16 | }, 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/materialLight/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {materialLight} from './material-light'; 3 | 4 | export const materialLightTheme = createTheme({ 5 | id: 'materialLightTheme', 6 | editorTheme: materialLight, 7 | properties: { 8 | darkMode: false, 9 | label: 'Material Light', 10 | previewBackground: 'linear-gradient(135deg, #54D2EF 0%, #2AA6DA 100%)', 11 | terminal: { 12 | main: '#ffffff', 13 | text: '#90a4ae', 14 | tabs: { 15 | inactiveTabBackground: '#e5e5e5', 16 | textColor: '#000', 17 | }, 18 | }, 19 | }, 20 | } as const); 21 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/materialOcean/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {materialOcean, palette} from './theme'; 3 | 4 | export const materialOceanTheme = createTheme({ 5 | id: 'materialOcean', 6 | editorTheme: materialOcean, 7 | properties: { 8 | darkMode: true, 9 | label: 'Material Ocean', 10 | previewBackground: `linear-gradient(to right bottom, #2be7b5, #1edea2, #16d58f, #13cb7c, #16c268, #0db866, #04ae64, #00a462, #00976c, #008971, #007b72, #006d6d)`, 11 | terminal: { 12 | main: palette.backgroundAlt, 13 | text: palette.white, 14 | tabs: { 15 | inactiveTabBackground: '#152025', 16 | }, 17 | }, 18 | }, 19 | } as const); 20 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/materialPalenight/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {materialPalenight, palette} from './materialPalenight'; 3 | 4 | export const materialPalenightTheme = createTheme({ 5 | id: 'materialPalenight', 6 | editorTheme: materialPalenight, 7 | properties: { 8 | darkMode: true, 9 | label: 'Material Palenight', 10 | previewBackground: 'linear-gradient(135deg, #54D2EF 0%, #2AA6DA 100%)', 11 | terminal: { 12 | main: '#24293B', 13 | text: palette.gray, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/materialVolcano/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {materialVolcano, palette} from './materialVolcano'; 3 | 4 | export const materialVolcanoTheme = createTheme({ 5 | id: 'materialVolcano', 6 | editorTheme: materialVolcano, 7 | properties: { 8 | darkMode: true, 9 | label: 'Material Volcano', 10 | previewBackground: 11 | 'linear-gradient(140deg, rgb(241, 160, 61), rgb(192, 74, 65), rgb(115, 52, 52))', 12 | terminal: { 13 | main: palette.background, 14 | text: palette.white, 15 | tabs: { 16 | background: '#501316', 17 | activeTabBackground: palette.background, 18 | inactiveTabBackground: '#3d0606', 19 | textColor: palette.white, 20 | }, 21 | }, 22 | }, 23 | } as const); 24 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/moonlight/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {moonlight, palette} from './moonlight'; 3 | 4 | export const moonlightTheme = createTheme({ 5 | id: 'moonlight', 6 | editorTheme: moonlight, 7 | properties: { 8 | darkMode: true, 9 | label: 'Moonlight', 10 | previewBackground: `linear-gradient(135deg, #6a3cc0 0%, #240573 100%)`, 11 | terminal: { 12 | main: palette.foreground, 13 | text: '#e4f3fa', 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/nightOwl/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {nightOwl} from './nightOwl'; 3 | 4 | export const nightOwlTheme = createTheme({ 5 | id: 'nightOwlTheme', 6 | editorTheme: nightOwl, 7 | properties: { 8 | darkMode: true, 9 | label: 'Night Owl', 10 | previewBackground: 11 | 'linear-gradient(140deg, rgb(9, 171, 241), rgb(5, 105, 148), rgb(4, 84, 118), rgb(6, 119, 167))', 12 | terminal: { 13 | main: '#041c31', 14 | text: '#D0D8E5', 15 | tabs: { 16 | background: '#132d43', 17 | inactiveTabBackground: '#021525', 18 | }, 19 | }, 20 | }, 21 | } as const); 22 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/oneDark/index.ts: -------------------------------------------------------------------------------- 1 | export * from './oneDark'; 2 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/oneDark/oneDark.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {oneDark} from '@codemirror/theme-one-dark'; 3 | 4 | export const oneDarkTheme = createTheme({ 5 | id: 'oneDark', 6 | editorTheme: oneDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'One dark', 10 | previewBackground: '#814CE2', 11 | terminal: { 12 | main: '#282c34', 13 | text: '#e5c07b', 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/panda/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {panda, palette} from './panda'; 3 | 4 | export const pandaTheme = createTheme({ 5 | id: 'panda', 6 | editorTheme: panda, 7 | properties: { 8 | darkMode: true, 9 | label: 'Panda', 10 | previewBackground: `#1a1a1a`, 11 | terminal: { 12 | main: palette.background, 13 | text: palette.text, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/poimandres/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {poimandres, palette} from './poimandres'; 3 | 4 | export const poimandresTheme = createTheme({ 5 | id: 'poimandres', 6 | editorTheme: poimandres, 7 | properties: { 8 | darkMode: true, 9 | label: 'Poimandres', 10 | previewBackground: 11 | 'linear-gradient(140deg, rgb(165, 142, 251), rgb(65, 206, 189))', 12 | terminal: { 13 | main: palette.bg, 14 | text: palette.darkerGray, 15 | }, 16 | }, 17 | } as const); 18 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/shadeOfPurple/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {shadeOfPurple, palette} from './shadeOfPurple'; 3 | 4 | export const shadeOfPurpleTheme = createTheme({ 5 | id: 'shadeOfPurple', 6 | editorTheme: shadeOfPurple, 7 | properties: { 8 | darkMode: true, 9 | label: 'Shades Of Purple', 10 | previewBackground: `#8663ed`, 11 | terminal: { 12 | main: palette.foreground, 13 | text: palette.text, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/synthwave84/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {palette, synthwave84} from './synthwave84'; 3 | 4 | export const synthwave84Theme = createTheme({ 5 | id: 'synthwave84', 6 | editorTheme: synthwave84, 7 | properties: { 8 | darkMode: true, 9 | label: "Synthwave '84", 10 | previewBackground: `linear-gradient(to right top, #7f469d, #8242aa, #833db7, #8338c4, #8233d2, #8a35da, #9336e2, #9b38ea, #af41ee, #c24af2, #d554f7, #e65ffb)`, 11 | terminal: { 12 | main: palette.background, 13 | text: palette.white, 14 | tabs: { 15 | inactiveTabBackground: '#1f1637', 16 | }, 17 | }, 18 | }, 19 | } as const); 20 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/vitesseDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {vitesseDark, palette} from './vitesseDark'; 3 | 4 | export const vitesseDarkTheme = createTheme({ 5 | id: 'vitesseDark', 6 | editorTheme: vitesseDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'Vitesse Dark', 10 | previewBackground: `linear-gradient(0deg, #6394bf, #a1b567)`, 11 | terminal: { 12 | main: palette.foreground, 13 | text: palette.string, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/vsCodeDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {vsCodeDark, background} from './vsCodeDark'; 3 | 4 | export const vsCodeDarkTheme = createTheme({ 5 | id: 'vsCodeDarkTheme', 6 | editorTheme: vsCodeDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'VSCode Dark', 10 | previewBackground: 11 | 'linear-gradient(to right bottom, #1cb1f2, #00a9f2, #00a0f2, #0097f1, #008def, #0086f1, #007ff2, #0078f2, #0071f6, #006afa, #0062fd, #0059ff)', 12 | terminal: { 13 | main: background, 14 | text: '#FFF', 15 | }, 16 | }, 17 | } as const); 18 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/xCodeDark/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {palette, xCodeDark} from './xCodeDark'; 3 | 4 | export const xCodeDarkTheme = createTheme({ 5 | id: 'xCodeDark', 6 | editorTheme: xCodeDark, 7 | properties: { 8 | darkMode: true, 9 | label: 'XCode Dark', 10 | previewBackground: `linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%)`, 11 | terminal: { 12 | main: palette.foreground, 13 | text: palette.text, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/lib/themes/xCodeLight/index.ts: -------------------------------------------------------------------------------- 1 | import {createTheme} from '../../core'; 2 | import {xCodeLight, palette} from './xCodeLight'; 3 | 4 | export const xCodeLightTheme = createTheme({ 5 | id: 'xCodeLight', 6 | editorTheme: xCodeLight, 7 | properties: { 8 | darkMode: false, 9 | label: 'XCode Light', 10 | previewBackground: `linear-gradient(to right bottom, #ffcc99, #f6bd83, #edad6e, #e49e59, #da8f44)`, 11 | terminal: { 12 | main: palette.foreground, 13 | text: palette.text, 14 | }, 15 | }, 16 | } as const); 17 | -------------------------------------------------------------------------------- /packages/highlight/src/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from './lib/core'; 2 | -------------------------------------------------------------------------------- /packages/highlight/tsconfig.dts.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": false, 6 | "emitDeclarationOnly": true, 7 | "outDir": "./dist" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/highlight/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "outDir": "./dist/esm" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/highlight/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js", 6 | "types": ["@types/node"] 7 | }, 8 | "include": [ 9 | "./src", 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/locale/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/locale/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist-ssr 4 | *.local 5 | -------------------------------------------------------------------------------- /packages/locale/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx,js,jsx,json}": [ 3 | "pnpm lint", 4 | "pnpm pre-commit-prettier", 5 | "pnpm pre-commit-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/locale/README.md: -------------------------------------------------------------------------------- 1 | ### @codeimage/Locale 2 | 3 | This is just a wrapper of [`solid-i18n`](https://github.com/davedbase/solid-primitives/tree/main/packages/i18n) with strict typings 4 | -------------------------------------------------------------------------------- /packages/locale/src/lib/path.ts: -------------------------------------------------------------------------------- 1 | type Path = Target extends string 2 | ? Prefix 3 | : Path< 4 | Target[keyof Target], 5 | `${Prefix extends '' ? '' : `${Prefix}.`}${Extract}` 6 | >; 7 | 8 | export type ExtractLocaleKeys = T extends Record 9 | ? U 10 | : never; 11 | 12 | export type LocaleKeys = Path>; 13 | -------------------------------------------------------------------------------- /packages/locale/src/public-api.ts: -------------------------------------------------------------------------------- 1 | export {I18nContext, createI18nContext} from '@solid-primitives/i18n'; 2 | 3 | export * from './lib/path'; 4 | export * from './lib/use-i18n'; 5 | -------------------------------------------------------------------------------- /packages/locale/tsconfig.dts.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": false, 6 | "emitDeclarationOnly": true, 7 | "outDir": "./dist" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/locale/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": false, 5 | "outDir": "./dist/esm" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/locale/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "preserve", 5 | "jsxImportSource": "solid-js", 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /packages/locale/vite.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'vite'; 2 | import path from 'path'; 3 | import dts from 'vite-plugin-dts'; 4 | import solidPlugin from 'vite-plugin-solid'; 5 | 6 | module.exports = defineConfig({ 7 | build: { 8 | lib: { 9 | entry: path.resolve(__dirname, 'src/public-api.ts'), 10 | name: '@codeimage/locale', 11 | fileName: 'locale', 12 | formats: ['es'], 13 | }, 14 | cssCodeSplit: true, 15 | rollupOptions: { 16 | external: ['solid-js', '@solid-primitives/i18n'], 17 | output: {}, 18 | }, 19 | }, 20 | plugins: [solidPlugin(), dts()], 21 | }); 22 | -------------------------------------------------------------------------------- /packages/prisma-models/.gitignore: -------------------------------------------------------------------------------- 1 | generated 2 | -------------------------------------------------------------------------------- /packages/prisma-models/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@codeimage/prisma-models", 3 | "version": "0.0.1", 4 | "description": "", 5 | "types": "./dist/index.d.ts", 6 | "exports": { 7 | ".": { 8 | "node": "./dist/index.js", 9 | "import": "./dist/index.js", 10 | "types": "./dist/index.d.ts" 11 | } 12 | }, 13 | "typesVersions": { 14 | "*": { 15 | "./": [ 16 | "./dist/index.d.ts" 17 | ] 18 | } 19 | }, 20 | "scripts": { 21 | "test": "echo \"Error: no test specified\" && exit 1", 22 | "build": "tsx ./scripts/build.ts", 23 | "build:ts": "tsc" 24 | }, 25 | "keywords": [], 26 | "author": "Riccardo Perra", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "typescript": "~5.3.2" 30 | } 31 | } -------------------------------------------------------------------------------- /packages/prisma-models/scripts/build.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'node:child_process'; 2 | import * as fs from 'node:fs'; 3 | 4 | const generatedTypes = fs.existsSync('./generated'); 5 | if (!generatedTypes) { 6 | console.warn("Prisma types has not been generated. Skipping build"); 7 | process.exit(0); 8 | } 9 | 10 | execSync(`pnpm run build:ts`, { stdio: 'inherit' }) -------------------------------------------------------------------------------- /packages/prisma-models/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../generated/client'; 2 | -------------------------------------------------------------------------------- /packages/prisma-models/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "outDir": "dist", 5 | "target": "ESNext", 6 | "module": "CommonJS", 7 | "moduleResolution": "node", 8 | "declaration": true, 9 | "sourceMap": false 10 | }, 11 | "include": [ 12 | "src/**/*" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/ui/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/ui/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /packages/ui/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "**.{ts,tsx,js,jsx,json}": [ 3 | "pnpm lint", 4 | "pnpm pre-commit-prettier", 5 | "pnpm pre-commit-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/ui/dev/global.css.ts: -------------------------------------------------------------------------------- 1 | import {globalStyle} from '@vanilla-extract/css'; 2 | import {themeVars} from '../src/lib/theme/global2.css'; 3 | 4 | globalStyle('html, body', { 5 | fontFamily: 'Albert Sans, sans-serif', 6 | backgroundColor: themeVars.dynamicColors.panel.background, 7 | color: themeVars.dynamicColors.baseText, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ui/dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Solid App 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/ui/dev/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "noUnusedLocals": true, 5 | "sourceMap": true, 6 | "jsx": "preserve", 7 | "resolveJsonModule": true, 8 | "jsxImportSource": "solid-js", 9 | "preserveSymlinks": true, 10 | "types": [ 11 | "@types/node" 12 | ] 13 | }, 14 | "include": [ 15 | "./**/*", 16 | "../src/**/*" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/ui/dev/vite.config.ts: -------------------------------------------------------------------------------- 1 | import {vanillaExtractPlugin} from '@codeimage/vanilla-extract'; 2 | import {defineConfig} from 'vite'; 3 | import solidPlugin from 'vite-plugin-solid'; 4 | import {withStaticVercelPreview} from '../../../scripts/vercel-output-build'; 5 | 6 | export const viteConfig = defineConfig({ 7 | plugins: [solidPlugin(), vanillaExtractPlugin(), withStaticVercelPreview()], 8 | }); 9 | 10 | export default viteConfig; 11 | -------------------------------------------------------------------------------- /packages/ui/src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './lib/theme'; 2 | export * from './lib/primitives'; 3 | export * from './lib/hooks'; 4 | export * from './lib/tokens'; 5 | 6 | export { 7 | createFloatingPortalNode, 8 | FloatingPortal, 9 | } from './lib/floating/floating-portal'; 10 | -------------------------------------------------------------------------------- /packages/ui/src/lib/hooks/arrayFromRange.ts: -------------------------------------------------------------------------------- 1 | export const arrayFomRange = (start: number, end: number) => { 2 | const length = end - start + 1; 3 | return Array.from({length}, (_, i) => start + i); 4 | }; 5 | -------------------------------------------------------------------------------- /packages/ui/src/lib/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export {useFloating} from './useFloating'; 2 | export type {UseFloatingOptions} from './useFloating'; 3 | export {createPagedData, getLastPage} from './pagination'; 4 | export {arrayFomRange} from './arrayFromRange'; 5 | -------------------------------------------------------------------------------- /packages/ui/src/lib/hooks/pagination/getLastPage.ts: -------------------------------------------------------------------------------- 1 | import {Accessor} from 'solid-js'; 2 | /** 3 | * Util to get last Page of our pagination 4 | * @param data Accessor with all data not paginated 5 | * @param pageSize Accessor with number of elements we want per page 6 | * @returns number with the last page of our pagination 7 | * 8 | * @example 9 | * 10 | * getLastPate(dashboard.filteredData, dashboard.pageSize) 11 | */ 12 | export const getLastPage = ( 13 | data: Accessor, 14 | pageSize: Accessor, 15 | ) => { 16 | const last = Math.ceil(data().length / pageSize()); 17 | return last === 0 ? 1 : last; 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ui/src/lib/hooks/pagination/index.ts: -------------------------------------------------------------------------------- 1 | export {arrayFomRange} from '../arrayFromRange'; 2 | export {getLastPage} from './getLastPage'; 3 | export {createPagedData} from './createPagedData'; 4 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Badge/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Badge'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Box/Box.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {themeVars} from '../../theme'; 3 | 4 | export const boxBase = style({ 5 | '::-webkit-scrollbar': { 6 | width: '18px', 7 | }, 8 | 9 | '::-webkit-scrollbar-track': { 10 | backgroundColor: 'transparent', 11 | }, 12 | '::-webkit-scrollbar-thumb': { 13 | backgroundColor: themeVars.dynamicColors.scrollBar.backgroundColor, 14 | borderRadius: themeVars.borderRadius.full, 15 | border: '6px solid transparent', 16 | backgroundClip: 'content-box', 17 | transition: 'background-color .2s', 18 | }, 19 | 20 | selectors: { 21 | '&::-webkit-scrollbar-thumb:hover': { 22 | backgroundColor: themeVars.dynamicColors.scrollBar.hoverBackgroundColor, 23 | }, 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Box/Stack.css.ts: -------------------------------------------------------------------------------- 1 | import {createTheme, style} from '@vanilla-extract/css'; 2 | 3 | export const [stackTheme, stackThemeVars] = createTheme({ 4 | spacing: '0px', 5 | }); 6 | 7 | export const stack = style([ 8 | stackTheme, 9 | { 10 | display: 'flex', 11 | // flexWrap: 'nowrap', 12 | }, 13 | ]); 14 | 15 | export const hStack = style([ 16 | stack, 17 | { 18 | flexDirection: 'row', 19 | columnGap: stackThemeVars.spacing, 20 | alignItems: 'center', 21 | }, 22 | ]); 23 | 24 | export const vStack = style([ 25 | stack, 26 | {flexDirection: 'column', rowGap: stackThemeVars.spacing}, 27 | ]); 28 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Box/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Box'; 2 | export * from './Stack'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Button/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Button'; 2 | export * as buttonStyles from './Button.css'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Dropdown/DropdownItem.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './Dropdown.css'; 2 | import {JSXElement} from 'solid-js'; 3 | import clsx from 'clsx'; 4 | import {MenuItem, MenuItemProps} from 'solid-headless'; 5 | 6 | type DropdownItemProps = MenuItemProps<'button'> & { 7 | active?: boolean; 8 | }; 9 | 10 | export function DropdownItem(props: DropdownItemProps): JSXElement { 11 | return ( 12 | 18 | {props.children} 19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Dropdown/DropdownPortal.tsx: -------------------------------------------------------------------------------- 1 | import {ParentComponent, Show} from 'solid-js'; 2 | import {Dynamic, Portal} from 'solid-js/web'; 3 | 4 | type DropdownPortalProps = { 5 | isOpen: boolean; 6 | mount: HTMLElement | null; 7 | }; 8 | 9 | export const DropdownPortal: ParentComponent = props => { 10 | return ( 11 | 12 | 16 | {props.children} 17 | 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Dropdown/index.ts: -------------------------------------------------------------------------------- 1 | export * as dropdownStyles from './Dropdown.css'; 2 | export * from './DropdownItem'; 3 | export * from './DropdownMenu'; 4 | // export * from './DropdownPanel'; 5 | export * from './DropdownPortal'; 6 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Field/FlexField.tsx: -------------------------------------------------------------------------------- 1 | import {PropsWithChildren} from 'solid-js'; 2 | import {styled} from '../../utils'; 3 | import {FlexFieldVariants, wrapper} from './FlexField.css'; 4 | 5 | export function FlexField(props: PropsWithChildren) { 6 | return ( 7 | 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Field/index.ts: -------------------------------------------------------------------------------- 1 | export {FlexField} from './FlexField'; 2 | export * as flexFieldStyles from './FlexField.css'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Group/Group.css.ts: -------------------------------------------------------------------------------- 1 | import {recipe, RecipeVariants} from '@vanilla-extract/recipes'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const base = style({ 5 | display: 'inline-flex', 6 | flex: 1, 7 | }); 8 | 9 | export const group = recipe({ 10 | base: base, 11 | 12 | variants: { 13 | orientation: { 14 | horizontal: { 15 | flexDirection: 'row', 16 | }, 17 | vertical: { 18 | flexDirection: 'column', 19 | }, 20 | }, 21 | }, 22 | }); 23 | 24 | export type GroupVariants = RecipeVariants; 25 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Group/Group.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import {FlowComponent} from 'solid-js'; 3 | import {CustomComponentProps, styled} from '../../utils'; 4 | import * as styles from './Group.css'; 5 | import {GroupVariants} from './Group.css'; 6 | 7 | type GroupProps = CustomComponentProps<'div', GroupVariants>; 8 | 9 | export const Group: FlowComponent = props => { 10 | const classes = () => 11 | clsx( 12 | styles.group({ 13 | orientation: props.orientation, 14 | }), 15 | props.class, 16 | ); 17 | 18 | return ( 19 | 20 | {props.children} 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Group/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Group'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Icon/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SvgIcon'; 2 | export * from './RemoteSvgIcon'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/IconButton/IconButton.tsx: -------------------------------------------------------------------------------- 1 | import {ElementType} from '@solid-aria/types'; 2 | import clsx from 'clsx'; 3 | import {ParentProps} from 'solid-js'; 4 | import {omitProps} from 'solid-use/props'; 5 | import {Button, ButtonProps} from '../Button/Button'; 6 | import * as styles from './IconButton.css'; 7 | 8 | export function IconButton( 9 | props: ParentProps>, 10 | ) { 11 | const classes = () => 12 | clsx(styles.iconButton({size: props.size}), props.class); 13 | 14 | return ( 15 | // @ts-expect-error not valid type with TS>5.0 16 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/IconButton/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './IconButton'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Label/FieldLabel.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {themeVars} from '../../theme'; 3 | 4 | export const label = style({ 5 | color: themeVars.dynamicColors.input.labelTextColor, 6 | marginBottom: themeVars.margin['3'], 7 | }); 8 | 9 | export const labelHintWrapper = style({ 10 | display: 'inline-flex', 11 | alignItems: 'center', 12 | color: themeVars.dynamicColors.input.labelTextHintColor, 13 | }); 14 | 15 | export const labelHint = style({ 16 | color: themeVars.dynamicColors.input.labelTextHintColor, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Label/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FieldLabel'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Link/Link.css.ts: -------------------------------------------------------------------------------- 1 | import {recipe} from '@vanilla-extract/recipes'; 2 | 3 | export const link = recipe({ 4 | base: { 5 | textDecoration: 'none', 6 | 7 | ':link': { 8 | color: 'unset', 9 | }, 10 | 11 | ':visited': { 12 | color: 'unset', 13 | }, 14 | 15 | ':active': { 16 | color: 'unset', 17 | }, 18 | }, 19 | variants: { 20 | underline: { 21 | true: { 22 | textDecoration: 'underline', 23 | }, 24 | }, 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Link/Link.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import {JSX, splitProps} from 'solid-js'; 3 | import {Text, TextProps} from '../Text/Text'; 4 | import * as styles from './Link.css'; 5 | 6 | interface LinkProps extends TextProps<'a'> { 7 | underline?: boolean; 8 | } 9 | 10 | export function Link(props: LinkProps): JSX.Element { 11 | const [local, others] = splitProps(props, [ 12 | 'underline', 13 | 'class', 14 | 'children', 15 | 'as', 16 | ]); 17 | 18 | return ( 19 | 29 | {props.children} 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Link/index.ts: -------------------------------------------------------------------------------- 1 | export * as linkStyles from './Link.css'; 2 | export {Link} from './Link'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Loader/Loader.css.ts: -------------------------------------------------------------------------------- 1 | import {themeVars} from '../../theme'; 2 | import {style} from '@vanilla-extract/css'; 3 | 4 | export const loader = style({ 5 | selectors: { 6 | ['[data-theme-mode=dark] &']: { 7 | stroke: themeVars.backgroundColor.white, 8 | }, 9 | ['[data-theme-mode=light] &']: { 10 | stroke: themeVars.backgroundColor.black, 11 | }, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Loader/LoadingCircle.css.ts: -------------------------------------------------------------------------------- 1 | import {keyframes, style} from '@vanilla-extract/css'; 2 | 3 | export const spinner = keyframes({ 4 | to: { 5 | transform: 'rotate(1turn)', 6 | }, 7 | }); 8 | 9 | export const loadingIcon = style({ 10 | animation: `${spinner} 1s linear infinite`, 11 | }); 12 | 13 | export const circle = style({ 14 | opacity: '.25', 15 | }); 16 | 17 | export const ring = style({ 18 | opacity: '.75', 19 | }); 20 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Loader/LoadingOverlay.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | 3 | export const overlay = style({ 4 | position: 'fixed', 5 | width: '100%', 6 | left: 0, 7 | top: 0, 8 | height: '100%', 9 | backgroundColor: `rgba(0, 0, 0, .25)`, 10 | display: 'flex', 11 | alignItems: 'center', 12 | justifyContent: 'center', 13 | }); 14 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Loader/LoadingOverlay.tsx: -------------------------------------------------------------------------------- 1 | import {JSXElement, Show} from 'solid-js'; 2 | import {omitProps} from 'solid-use/props'; 3 | import {styled} from '../../utils'; 4 | import {LoaderProps, Loading} from './Loading'; 5 | import {overlay} from './LoadingOverlay.css'; 6 | 7 | interface LoadingOverlayProps extends LoaderProps { 8 | overlay: boolean; 9 | } 10 | 11 | export function LoadingOverlay(props: LoadingOverlayProps): JSXElement { 12 | const loadingProps = omitProps(props, ['overlay']); 13 | return ( 14 | }> 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Loader/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Loading'; 2 | export * from './LoadingCircle'; 3 | export * from './LoadingOverlay'; 4 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/PortalHost/PortalHost.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {themeVars} from '../../theme'; 3 | 4 | export const host = style({ 5 | width: '0px', 6 | height: '0px', 7 | zIndex: themeVars.zIndex['40'], 8 | }); 9 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/PortalHost/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PortalHost'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/RadioBlock/RadioBlock.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './RadioBlock.css'; 2 | import {RadioBlockVariants} from './RadioBlock.css'; 3 | import {JSXElement} from 'solid-js'; 4 | import {Box} from '../Box'; 5 | 6 | export type RadioBlockProps = RadioBlockVariants & { 7 | value: T; 8 | onSelect?: (value: T) => void; 9 | children?: JSXElement; 10 | }; 11 | 12 | export function RadioBlock(props: RadioBlockProps) { 13 | return ( 14 | props.onSelect?.(props.value)} 19 | > 20 | {props.children} 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/RadioBlock/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RadioBlock'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/RangeField/index.ts: -------------------------------------------------------------------------------- 1 | export * as rangeFieldStyles from './RangeField.css'; 2 | export * from './RangeField'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/SegmentedField/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SegmentedField'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Snackbar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Snackbar'; 2 | export * from './SnackbarHost'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Text/Text.css.ts: -------------------------------------------------------------------------------- 1 | import {style, styleVariants} from '@vanilla-extract/css'; 2 | import {mapToProperty} from '../../utils/mapToProperty'; 3 | import {themeVars} from '../../theme'; 4 | import * as variables from '../../theme/variables.css'; 5 | 6 | export const fontWeight = styleVariants( 7 | themeVars.fontWeight, 8 | mapToProperty('fontWeight'), 9 | ); 10 | 11 | export const fontSize = styleVariants( 12 | themeVars.fontSize, 13 | mapToProperty('fontSize'), 14 | ); 15 | 16 | export const baseText = style({ 17 | fontSize: variables.fontSize, 18 | }); 19 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Text/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Text'; 2 | export * from './useText'; 3 | export * as textStyles from './Text.css'; 4 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/TextField/index.ts: -------------------------------------------------------------------------------- 1 | export * from './TextField'; 2 | export * as textFieldStyles from './TextField.css'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Toggle/Toggle.tsx: -------------------------------------------------------------------------------- 1 | import * as styles from './Toggle.css'; 2 | import {ToggleProps as ShToggleProps} from 'solid-headless'; 3 | import {Toggle as ShToggle} from 'solid-headless'; 4 | import {Component} from 'solid-js'; 5 | 6 | type ToggleProps = ShToggleProps & styles.ToggleVariants; 7 | 8 | export const Toggle: Component = props => { 9 | return ( 10 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Toggle/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Toggle'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/primitives/Transition/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Transition'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/theme/base.css.ts: -------------------------------------------------------------------------------- 1 | import {style} from '@vanilla-extract/css'; 2 | import {dynamicFullHeight} from './variables.css'; 3 | 4 | export const adaptiveFullScreenHeight = style({ 5 | height: '100vh', 6 | '@media': { 7 | 'screen and (max-width: 768px)': { 8 | height: `calc(${dynamicFullHeight} * 100)`, 9 | 10 | '@supports': { 11 | // ios 15+ 12 | '(height: 100dvh)': { 13 | height: '100dvh', 14 | }, 15 | }, 16 | 17 | overflow: 'hidden', 18 | }, 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /packages/ui/src/lib/theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './colors'; 2 | export * from './spacing'; 3 | export * from './theme.css'; 4 | export * from './global2.css'; 5 | export * from './sprinkles.css'; 6 | export * from './variables.css'; 7 | export * from './base.css'; 8 | export * from './with-theme-mode'; 9 | -------------------------------------------------------------------------------- /packages/ui/src/lib/theme/spacing.ts: -------------------------------------------------------------------------------- 1 | export const spacing = { 2 | auto: 'auto', 3 | px: '1px', 4 | 0: '0', 5 | 1: '0.25rem', 6 | 2: '0.5rem', 7 | 3: '0.75rem', 8 | 4: '1rem', 9 | 5: '1.25rem', 10 | 6: '1.5rem', 11 | 8: '2rem', 12 | 10: '2.5rem', 13 | 12: '3rem', 14 | 16: '4rem', 15 | 20: '5rem', 16 | 24: '6rem', 17 | 32: '8rem', 18 | 40: '10rem', 19 | 48: '12rem', 20 | 56: '14rem', 21 | 64: '16rem', 22 | } as const; 23 | -------------------------------------------------------------------------------- /packages/ui/src/lib/theme/variables.css.ts: -------------------------------------------------------------------------------- 1 | import {createVar} from '@vanilla-extract/css'; 2 | 3 | export const colorVar = createVar(); 4 | export const fontSize = createVar(); 5 | export const backgroundColorVar = createVar(); 6 | export const dynamicFullHeight = createVar(); 7 | -------------------------------------------------------------------------------- /packages/ui/src/lib/tokens/createCodeImageTheme.ts: -------------------------------------------------------------------------------- 1 | import {createGlobalTheme, createTheme} from '@vanilla-extract/css'; 2 | import {MapLeafNodes} from '@vanilla-extract/private'; 3 | import {themeColors} from '../theme/theme.css'; 4 | 5 | export function createGlobalCodeImageTheme( 6 | theme: string, 7 | tokens: MapLeafNodes, 8 | ) { 9 | createGlobalTheme(`[data-codeimage-theme=${theme}]`, themeColors, tokens); 10 | } 11 | 12 | export function createCodeImageTheme( 13 | theme: string, 14 | tokens: MapLeafNodes, 15 | ): string { 16 | return createTheme(themeColors, tokens); 17 | } 18 | -------------------------------------------------------------------------------- /packages/ui/src/lib/tokens/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tokens'; 2 | -------------------------------------------------------------------------------- /packages/ui/src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './factory'; 2 | export * from './mapToProperty'; 3 | -------------------------------------------------------------------------------- /packages/ui/src/lib/utils/mapToProperty.ts: -------------------------------------------------------------------------------- 1 | import type {Properties} from 'csstype'; 2 | 3 | export const mapToProperty = 4 | >(property: Property) => 5 | (value: string | number) => { 6 | const styleRule = {[property]: value}; 7 | return styleRule; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/ui/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.dts.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": false, 6 | "emitDeclarationOnly": true, 7 | "outDir": "./dist/types" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "noUnusedLocals": true, 5 | "sourceMap": true, 6 | "jsx": "preserve", 7 | "resolveJsonModule": true, 8 | "jsxImportSource": "solid-js", 9 | "preserveSymlinks": true, 10 | "types": [ 11 | "@types/node" 12 | ] 13 | }, 14 | "include": [ 15 | "./src", 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.source.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 7 | "moduleResolution": "node", 8 | "allowSyntheticDefaultImports": true, 9 | "resolveJsonModule": true, 10 | "esModuleInterop": true, 11 | "jsx": "preserve", 12 | "jsxImportSource": "solid-js", 13 | "noEmit": true, 14 | "isolatedModules": true, 15 | "skipLibCheck": true, 16 | "types": [], 17 | "baseUrl": "." 18 | }, 19 | "include": ["src"], 20 | "exclude": ["node_modules", "dist"] 21 | } 22 | -------------------------------------------------------------------------------- /packages/vanilla-extract/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /packages/vanilla-extract/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /packages/vanilla-extract/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx,js,jsx,json}": [ 3 | "pnpm lint", 4 | "pnpm pre-commit-prettier", 5 | "pnpm pre-commit-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/vanilla-extract/src/esbuild/vanillaCssTsFilesLoader.ts: -------------------------------------------------------------------------------- 1 | import {Plugin} from 'esbuild'; 2 | import * as fs from 'node:fs'; 3 | import * as path from 'node:path'; 4 | 5 | export function vanillaCssTsFilesLoader(): Plugin { 6 | return { 7 | name: 'esbuild-vanilla-extract-css-ts-loader', 8 | setup(build) { 9 | build.onLoad({filter: /.css.ts.vanilla.css$/}, async ({path: path$1}) => { 10 | const css = await fs.promises.readFile(path$1, 'utf-8'); 11 | return { 12 | contents: css, 13 | loader: 'text', 14 | resolveDir: path.dirname(path$1), 15 | }; 16 | }); 17 | }, 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/vanilla-extract/src/index.ts: -------------------------------------------------------------------------------- 1 | export {vanillaExtractPlugin} from './vite-plugin'; 2 | 3 | export {vanillaCssTsFilesLoader} from './esbuild/vanillaCssTsFilesLoader'; 4 | -------------------------------------------------------------------------------- /packages/vanilla-extract/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "preserveSymlinks": true 6 | }, 7 | "include": [ 8 | "./src" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /patches/csstype@3.1.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/package.json b/package.json 2 | index c1ae23398955bb1a3d85a44fcf68a4a103262b71..e497de9875426296275f0fef2ba97a3e41ab2e4c 100644 3 | --- a/package.json 4 | +++ b/package.json 5 | @@ -7,6 +7,11 @@ 6 | "repository": "https://github.com/frenic/csstype", 7 | "author": "Fredrik Nicol ", 8 | "license": "MIT", 9 | + "exports": { 10 | + ".": { 11 | + "types": "./index.d.ts" 12 | + } 13 | + }, 14 | "devDependencies": { 15 | "@types/chokidar": "^2.1.3", 16 | "@types/css-tree": "^1.0.7", -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'apps/**' 3 | - 'packages/**' 4 | - 'tools/**' 5 | - '!**/test/**' 6 | -------------------------------------------------------------------------------- /scripts/env-utils.ts: -------------------------------------------------------------------------------- 1 | export function makeEnvFile( 2 | obj: Record, 3 | ): string { 4 | return Object.entries(obj).reduce( 5 | (acc, [key, value]) => (key ? acc + `${key}=${String(value)}\n` : acc), 6 | '', 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "declaration": true, 12 | "sourceMap": true, 13 | "importHelpers": true, 14 | "resolveJsonModule": true, 15 | "importsNotUsedAsValues": "remove", 16 | "forceConsistentCasingInFileNames": true, 17 | "skipLibCheck": true, 18 | "types": [ 19 | "vite/client" 20 | ], 21 | "lib": [ 22 | "dom", 23 | "ESNext" 24 | ] 25 | }, 26 | "include": [ 27 | "@types", 28 | "packages", 29 | "scripts" 30 | ], 31 | "exclude": ["**/node_modules"] 32 | } 33 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": { 3 | "enabled": false 4 | } 5 | } 6 | --------------------------------------------------------------------------------