Skip to content

[Web Import] Add Tabler Icons web import#958

Merged
t-regbs merged 1 commit intomainfrom
feature/tabler
Apr 27, 2026
Merged

[Web Import] Add Tabler Icons web import#958
t-regbs merged 1 commit intomainfrom
feature/tabler

Conversation

@t-regbs
Copy link
Copy Markdown
Collaborator

@t-regbs t-regbs commented Apr 19, 2026

Screen.Recording.2026-04-20.at.00.19.25.mov

📝 Changelog

If this PR introduces user-facing changes, please update the relevant Unreleased section in changelogs:

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 19, 2026

Walkthrough

This pull request integrates Tabler icons support into a Compose icon library and associated IDEA plugin. It adds a new TablerLogo icon asset to the SDK, establishes a complete web import workflow including a TablerRepository for font/codepoint handling, a TablerCodepointParser for CSS parsing, and a TablerUseCase implementing the standard icon provider interface. The IDEA plugin UI is extended with TablerImportScreen, settings persistence for Tabler icon size, navigation flow updates, and localized UI strings. A new toGlyphString() utility converts Unicode codepoints to glyph strings. Comprehensive unit tests validate codepoint parsing, SVG URL resolution, and icon configuration building.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description includes only a video asset link and a changelog checklist with the IntelliJ Plugin item checked, but lacks substantive details about the changes, motivation, or implementation approach. Add a descriptive summary explaining what was added, why, and how the feature works (e.g., new icon provider integration, UI changes, dependency injection setup). The video asset alone is insufficient context for code review.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title '[Web Import] Add Tabler Icons web import' directly and clearly summarizes the main change—adding Tabler Icons as a web import source to the IDE plugin.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/tabler

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParserTest.kt (1)

8-26: Good coverage for the happy path; consider adding a negative/edge case.

The test validates BMP (3-hex) and supplementary-plane (5-hex) codepoints plus hyphenated class names — good. One optional addition: a case with surrounding non-matching CSS (e.g., @font-face { ... } or unrelated rules) and a rule with a trailing ; to lock in the ;? branch of the regex.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParserTest.kt`
around lines 8 - 26, Add an extra negative/edge-case scenario to
TablerCodepointParserTest: when building the css string passed to
TablerCodepointParser().parse, include some unrelated CSS like an `@font-face`
block and at least one icon rule that ends with a trailing semicolon (to
exercise the regex branch that allows an optional ';'); then assert that parse
still returns only the expected keys/values for "accessible", "aerial-lift", and
"arrow-autofit-down" (and no entries from the unrelated block) to ensure the
parser ignores non-matching rules and handles the ';' case.
tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParser.kt (1)

5-8: Regex assumes content is the sole declaration in the rule block.

The pattern requires { directly followed by content: and } closing right after the value (with optional ;). This matches the current tabler-icons.css layout, but any additional declarations inside a .ti-*:before block (e.g., a future font-family) would silently drop that icon from the parsed map. Consider making the body tolerant to extra declarations, e.g.:

♻️ Suggested relaxed regex
-        Regex("""\.ti-([a-z0-9-]+):before\s*\{\s*content:\s*"\\([A-Fa-f0-9]+)"\s*;?\s*}"""),
+        Regex("""\.ti-([a-z0-9-]+):before\s*\{[^}]*?content:\s*"\\([A-Fa-f0-9]+)"[^}]*}"""),

Not blocking — the current CSS shape works with the existing regex.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParser.kt`
around lines 5 - 8, The current TablerCodepointParser (subclassing
RegexCssCodepointParser) uses a regex that requires the rule block to contain
only the content declaration, so any extra declarations will prevent matches;
update the Regex supplied to TablerCodepointParser to allow arbitrary
declarations inside the braces and find the content value anywhere in the block
(for example by matching
".ti-([a-z0-9-]+)\s*:\s*before\s*\{\s*[^}]*?content:\s*\"\\([A-Fa-f0-9]+)\"[^}]*\}"
style logic) so the parser tolerates additional properties while still capturing
the icon name and hex code.
tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerRepository.kt (1)

38-40: Consider surfacing HTTP failures with context for SVG/CSS downloads.

loadAndDecodeWoff2 helpfully includes the source URL in its failure message (line 50), but downloadSvg and loadCodepoints call bodyAsText() directly. Any Ktor exception (timeout, non-2xx if a response validator is configured, etc.) will propagate without the offending URL, which makes production triage harder. Consider wrapping these calls so failures include the URL, consistent with the WOFF2 path. Non-blocking — deferable if the project already handles this centrally in the shared HttpClient.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerRepository.kt`
around lines 38 - 40, downloadSvg and loadCodepoints call
httpClient.get(...).bodyAsText() directly so Ktor exceptions lack the source
URL; wrap their network calls in a try/catch (same pattern used by
loadAndDecodeWoff2) to catch any Throwable and rethrow or throw a new
IOException/RuntimeException that includes the resolved URL
(resolveTablerSvgUrl(iconName, style) for downloadSvg and
resolveTablerCodepointsUrl() for loadCodepoints) plus the original exception as
the cause so error logs include the offending URL for easier triage.
tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/domain/TablerIconConfigBuilderTest.kt (1)

31-32: Reuse the domain style constants instead of redefining them.

TABLER_OUTLINE_STYLE and TABLER_FILLED_STYLE are already declared as internal in the same package (...tabler.domain) in TablerUseCase.kt. Redefining local OUTLINE_STYLE/FILLED_STYLE duplicates the definition and risks silent drift if the production constants change (e.g., id/name). The test would still pass via IconStyle data-class equality while no longer validating the real values emitted by buildTablerIcons.

♻️ Proposed fix
-        assertThat(icons.map { it.style }).containsExactly(OUTLINE_STYLE, FILLED_STYLE, OUTLINE_STYLE)
+        assertThat(icons.map { it.style }).containsExactly(TABLER_OUTLINE_STYLE, TABLER_FILLED_STYLE, TABLER_OUTLINE_STYLE)
@@
-private val OUTLINE_STYLE = IconStyle(id = "outline", name = "Outline")
-private val FILLED_STYLE = IconStyle(id = "filled", name = "Filled")

(The IconStyle import can then be dropped.)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/domain/TablerIconConfigBuilderTest.kt`
around lines 31 - 32, Replace the local test constants OUTLINE_STYLE and
FILLED_STYLE in TablerIconConfigBuilderTest with the existing domain constants
TABLER_OUTLINE_STYLE and TABLER_FILLED_STYLE (declared internal in
TablerUseCase.kt) so the test validates the actual production values emitted by
buildTablerIcons; update references in the test to use TABLER_OUTLINE_STYLE /
TABLER_FILLED_STYLE and remove the now-unnecessary IconStyle import.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParser.kt`:
- Around line 5-8: The current TablerCodepointParser (subclassing
RegexCssCodepointParser) uses a regex that requires the rule block to contain
only the content declaration, so any extra declarations will prevent matches;
update the Regex supplied to TablerCodepointParser to allow arbitrary
declarations inside the braces and find the content value anywhere in the block
(for example by matching
".ti-([a-z0-9-]+)\s*:\s*before\s*\{\s*[^}]*?content:\s*\"\\([A-Fa-f0-9]+)\"[^}]*\}"
style logic) so the parser tolerates additional properties while still capturing
the icon name and hex code.

In
`@tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerRepository.kt`:
- Around line 38-40: downloadSvg and loadCodepoints call
httpClient.get(...).bodyAsText() directly so Ktor exceptions lack the source
URL; wrap their network calls in a try/catch (same pattern used by
loadAndDecodeWoff2) to catch any Throwable and rethrow or throw a new
IOException/RuntimeException that includes the resolved URL
(resolveTablerSvgUrl(iconName, style) for downloadSvg and
resolveTablerCodepointsUrl() for loadCodepoints) plus the original exception as
the cause so error logs include the offending URL for easier triage.

In
`@tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParserTest.kt`:
- Around line 8-26: Add an extra negative/edge-case scenario to
TablerCodepointParserTest: when building the css string passed to
TablerCodepointParser().parse, include some unrelated CSS like an `@font-face`
block and at least one icon rule that ends with a trailing semicolon (to
exercise the regex branch that allows an optional ';'); then assert that parse
still returns only the expected keys/values for "accessible", "aerial-lift", and
"arrow-autofit-down" (and no entries from the unrelated block) to ensure the
parser ignores non-matching rules and handles the ';' case.

In
`@tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/domain/TablerIconConfigBuilderTest.kt`:
- Around line 31-32: Replace the local test constants OUTLINE_STYLE and
FILLED_STYLE in TablerIconConfigBuilderTest with the existing domain constants
TABLER_OUTLINE_STYLE and TABLER_FILLED_STYLE (declared internal in
TablerUseCase.kt) so the test validates the actual production values emitted by
buildTablerIcons; update references in the test to use TABLER_OUTLINE_STYLE /
TABLER_FILLED_STYLE and remove the now-unnecessary IconStyle import.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cb951a43-5b6f-4720-85c9-e2b4c502faa8

📥 Commits

Reviewing files that changed from the base of the PR and between 817bbd3 and 55eb2a9.

📒 Files selected for processing (20)
  • sdk/compose/icons/api/icons.api
  • sdk/compose/icons/api/icons.klib.api
  • sdk/compose/icons/src/commonMain/kotlin/io/github/composegears/valkyrie/sdk/compose/icons/colored/TablerLogo.kt
  • tools/idea-plugin/CHANGELOG.md
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/service/PersistentSettings.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/settings/InMemorySettings.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/WebImportFlow.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/WebImportSelectorScreen.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/common/StandardImportScreenUI.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/common/domain/CodepointGlyph.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/TablerImportScreen.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParser.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerRepository.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/di/TablerModule.kt
  • tools/idea-plugin/src/main/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/domain/TablerUseCase.kt
  • tools/idea-plugin/src/main/resources/messages/Valkyrie.properties
  • tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/common/domain/CodepointGlyphTest.kt
  • tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerCodepointParserTest.kt
  • tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/data/TablerSvgPathResolverTest.kt
  • tools/idea-plugin/src/test/kotlin/io/github/composegears/valkyrie/ui/screen/webimport/standard/tabler/domain/TablerIconConfigBuilderTest.kt

@t-regbs t-regbs merged commit 5f6c0a6 into main Apr 27, 2026
5 checks passed
@t-regbs t-regbs deleted the feature/tabler branch April 27, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants