From a4b53943c80bb2e1e964f0de016abc364e828b38 Mon Sep 17 00:00:00 2001 From: Daniel Bertoldi Date: Mon, 29 Jun 2026 16:59:27 -0300 Subject: [PATCH] [JEWEL-1346] Force Auto Correct + Enable Documentation Rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picked from e2b25d41cd35c on master. 268 files; 254 applied cleanly and 14 conflicted where the 0.41 cycle had since rewritten the same declarations. The commit is almost entirely additive KDoc, so most resolutions keep both sides; the exceptions are where this branch is already ahead. Taken from this branch, because the incoming text describes superseded code: * `MacPlatformServices`, `Popup`, `PathImageResourceLocation` — `[JEWEL-1388]`, `[JEWEL-1396]` and `[JEWEL-1370]` rewrote these. The incoming doc for `MacPlatformServicesDefaultImpl` still refers to `[UnsafeAccessing]`, which `[JEWEL-1388]` deleted, so importing it would leave a dangling KDoc link. * `FocusableComponentState` — the incoming doc describes the old state priority; `[JEWEL-1193]` changed hover to take precedence over focus, and this branch's doc already matches that behaviour. * `ThemeColorPalette` — `isIslands` is a constructor `val`, and every sibling entry in that block uses `@property`, so the incoming `@param` would be both wrong and inconsistent. * `MarkdownTestTheme`, `ShowcaseIcons`, `JewelTheme` — signatures and declarations this branch gained from `[JEWEL-1322]`, `[JEWEL-1345]` and `[JEWEL-1150]`. Kept from both sides, with ordering decided per hunk rather than per file, since a KDoc has to sit immediately above what it documents: * `MenuStyling` (4 hunks) and one hunk of `Menu` — the incoming KDoc and this branch's `@Deprecated` / `@Suppress` annotate the same following declaration, so the doc goes first. * `Menu` (other hunk), `SimpleListItem`, `TooltipStyling`, `Typography`, `MarkdownStyling` — this branch's side is a complete deprecated declaration, several of them restored by the `[JEWEL-1323]` revert, and the incoming KDoc belongs to the declaration that follows it, so the declaration goes first. Verified applicable to this branch rather than assumed: enabling the documentation rules is only safe if the existing code already satisfies them. `.editorconfig` and `jewel-linting.gradle.kts` are now identical to master, and both gates pass here — `detekt detektMain detektTest` and `lintKotlin` are green, and Bazel still compiles. This also lands `scripts/annotate-detekt.main.kts` and the workflow's detekt split, which the `checks` job needs: `check -x detekt` leaves detekt to its own step so a failure there still reaches the annotation step, which turns detekt's checkstyle reports into inline findings on a PR's "Files changed" tab. (cherry picked from commit 513866356b5904906dcf33830192bce225d7a413) IJ-MR-220560 GitOrigin-RevId: 417028f8877d77b5d6aa61585081077a45f2a686 --- .github/workflows/jewel-checks.yml | 18 +- platform/jewel/.editorconfig | 1 + .../src/main/kotlin/jewel-linting.gradle.kts | 5 +- .../intui/window/DecoratedWindowIconKeys.kt | 8 + .../jewel/intui/window/IntUiTheme.kt | 9 + .../styling/IntUiDecoratedWindowStyling.kt | 29 +++ .../window/styling/IntUiTitleBarStyling.kt | 40 ++++ .../jetbrains/jewel/window/DecoratedWindow.kt | 65 +++++- .../org/jetbrains/jewel/window/Theme.kt | 2 + .../jetbrains/jewel/window/TitleBar.MacOS.kt | 7 + .../org/jetbrains/jewel/window/TitleBar.kt | 19 ++ .../window/styling/DecoratedWindowStyling.kt | 27 ++- .../jewel/window/styling/TitleBarStyling.kt | 49 ++++- .../jewel/window/utils/DesktopPlatform.kt | 10 + .../jewel/detekt/JewelRuleSetProvider.kt | 22 ++ .../jewel/detekt/rules/EqualityMembersRule.kt | 48 ++++- .../jewel/detekt/rules/JewelBaseRule.kt | 33 +++ .../rules/MissingApiStatusAnnotationRule.kt | 27 ++- .../jewel/detekt/EqualityMembersRuleSpec.kt | 28 ++- .../MissingApiStatusAnnotationRuleSpec.kt | 58 +++--- .../org/jetbrains/jewel/detekt/TestUtil.kt | 3 +- .../org/jetbrains/jewel/detekt/UtilsTest.kt | 20 +- platform/jewel/detekt.yml | 52 ++++- .../foundation/DisabledAppearanceValues.kt | 2 + .../jewel/foundation/GlobalColors.kt | 4 + .../jewel/foundation/GlobalMetrics.kt | 10 +- .../org/jetbrains/jewel/foundation/Stroke.kt | 37 ++++ .../actionSystem/DataProviderContext.kt | 3 + .../actionSystem/DataProviderNode.kt | 7 +- .../jewel/foundation/code/MimeType.kt | 10 + .../code/highlighting/CodeHighlighter.kt | 5 + .../code/highlighting/NoOpCodeHighlighter.kt | 1 + .../jewel/foundation/lazy/Keybindings.kt | 12 ++ .../lazy/SelectableColumnOnKeyEvent.kt | 18 ++ .../lazy/SelectableLazyListScope.kt | 26 +++ .../lazy/SelectableLazyListState.kt | 60 ++++++ .../foundation/lazy/tree/BasicLazyTree.kt | 35 +++- .../jewel/foundation/lazy/tree/BuildTree.kt | 50 ++++- .../lazy/tree/DefaultTreeViewKeybindings.kt | 8 + .../lazy/tree/DefaultTreeViewOnKeyEvent.kt | 1 + .../jewel/foundation/lazy/tree/KeyActions.kt | 80 +++++++ .../jewel/foundation/lazy/tree/Tree.kt | 44 ++++ .../jewel/foundation/lazy/tree/TreeState.kt | 21 ++ .../lazy/tree/TreeViewOnKeyEvent.kt | 1 + .../jewel/foundation/modifier/Activation.kt | 1 + .../foundation/modifier/PointerModifiers.kt | 11 + .../foundation/search/SpeedSearchMatcher.kt | 9 +- .../foundation/state/CommonStateBitMask.kt | 15 ++ .../state/FocusableComponentState.kt | 5 + .../state/InteractiveComponentState.kt | 8 + .../state/SelectableComponentState.kt | 2 + .../state/ToggleableComponentState.kt | 6 + .../jewel/foundation/theme/JewelTheme.kt | 31 +++ .../foundation/theme/ThemeColorPalette.kt | 1 + .../jewel/foundation/theme/ThemeDefinition.kt | 15 ++ .../jewel/foundation/theme/ThemeDescriptor.kt | 8 + .../jewel/foundation/theme/ThemeIconData.kt | 10 + .../jewel/foundation/util/JewelLogger.kt | 19 ++ .../jetbrains/jewel/bridge/BridgeIconData.kt | 1 + .../bridge/BridgePainterHintsProvider.kt | 7 + .../jewel/bridge/ComposeSemanticsTreeUtils.kt | 12 ++ .../jewel/bridge/JewelBridgeException.kt | 3 + .../jewel/bridge/ToolWindowExtensions.kt | 4 +- .../actionSystem/RootDataProviderNode.kt | 4 + .../highlighting/CodeHighlighterFactory.kt | 7 + .../jewel/bridge/icon/IntelliJIconKey.kt | 7 + .../jewel/bridge/theme/BridgeGlobalMetrics.kt | 1 + .../bridge/theme/BridgeThemeColorPalette.kt | 4 + .../bridge/theme/IntUiBridgeScrollbar.kt | 6 + .../jewel/bridge/theme/IntUiBridgeSlider.kt | 3 + .../bridge/theme/IntUiBridgeSplitButton.kt | 2 + .../jewel/bridge/theme/IntUiBridgeText.kt | 1 + .../jewel/bridge/theme/SwingBridgeTheme.kt | 7 + .../jewel/intui/standalone/InterFont.kt | 1 + .../intui/standalone/JetBrainsMonoFont.kt | 1 + .../StandalonePainterHintsProvider.kt | 1 + .../standalone/StandaloneScrollbarHelper.kt | 1 + .../intui/standalone/bundle/DynamicBundle.kt | 3 + .../StandaloneShortcutProvider.kt | 4 + .../standalone/styling/IntUIBannerStyling.kt | 78 +++++-- .../standalone/styling/IntUiBadgeStyling.kt | 51 +++++ .../standalone/styling/IntUiButtonStyling.kt | 32 +++ .../styling/IntUiCheckboxStyling.kt | 7 + .../standalone/styling/IntUiChipStyling.kt | 6 + .../styling/IntUiCircularProgressStyling.kt | 2 + .../styling/IntUiComboBoxStyling.kt | 21 ++ .../standalone/styling/IntUiDividerStyle.kt | 2 + .../styling/IntUiDropdownStyling.kt | 19 ++ .../styling/IntUiGroupHeaderStyling.kt | 5 + .../IntUiHorizontalProgressBarStyling.kt | 5 + .../styling/IntUiIconButtonStyling.kt | 9 + .../styling/IntUiLazyTreeStyling.kt | 7 + .../standalone/styling/IntUiLinkStyling.kt | 6 + .../standalone/styling/IntUiMenuStyling.kt | 10 + .../standalone/styling/IntUiPopupAdStyling.kt | 6 + .../styling/IntUiPopupContainerStyling.kt | 5 + .../styling/IntUiRadioButtonStyling.kt | 7 + .../styling/IntUiSearchMatchStyling.kt | 5 + .../IntUiSegmentedControlButtonStyling.kt | 5 + .../styling/IntUiSegmentedControlStyling.kt | 5 + .../IntUiSelectableLazyColumnStyling.kt | 2 + .../styling/IntUiSimpleListItemStyling.kt | 13 ++ .../standalone/styling/IntUiSliderStyling.kt | 5 + .../styling/IntUiSpeedSearchStyling.kt | 6 + .../styling/IntUiSplitButtonStyling.kt | 8 + .../styling/IntUiTabStripScrollbarStyling.kt | 6 + .../standalone/styling/IntUiTabStyling.kt | 20 ++ .../styling/IntUiTextAreaStyling.kt | 5 + .../styling/IntUiTextFieldStyling.kt | 5 + .../standalone/styling/IntUiTooltipStyling.kt | 4 + .../standalone/theme/IntUiGlobalMetrics.kt | 1 + .../intui/standalone/theme/IntUiTheme.kt | 8 + .../intui/standalone/theme/TextStyles.kt | 1 + .../intui/standalone/window/JnaLoader.kt | 7 + .../jewel/intui/standalone/window/macos/ID.kt | 3 + .../jewel/markdown/InlineMarkdown.kt | 11 + .../jetbrains/jewel/markdown/MarkdownBlock.kt | 23 ++ .../jetbrains/jewel/markdown/MarkdownMode.kt | 7 + .../jetbrains/jewel/markdown/MarkdownText.kt | 6 +- .../jewel/markdown/WithChildBlocks.kt | 1 + .../jewel/markdown/extensions/Markdown.kt | 8 + .../markdown/processing/MarkdownProcessor.kt | 4 - .../processing/html/MarkdownHtmlNode.kt | 1 + .../rendering/DefaultMarkdownBlockRenderer.kt | 5 + .../markdown/rendering/ImageSourceResolver.kt | 1 + .../rendering/MarkdownBlockRenderer.kt | 39 ++-- .../markdown/rendering/MarkdownStyling.kt | 197 +++++++++++++++++- .../scrolling/ScrollingSynchronizer.kt | 7 + .../github/alerts/GitHubAlertIcons.kt | 10 + .../alerts/GitHubAlertRendererExtension.kt | 6 + .../github/alerts/GitHubAlertStyling.kt | 33 ++- .../strikethrough/GitHubStrikethroughNode.kt | 9 +- .../github/tables/GitHubTableStyling.kt | 18 ++ .../images/Coil3ImageRendererExtension.kt | 1 + .../BridgeMarkdownBlockRendererExtensions.kt | 4 + .../bridge/styling/BridgeMarkdownStyling.kt | 31 ++- .../github/alerts/BridgeGitHubAlertStyling.kt | 9 + .../github/tables/BridgeGitHubTableStyling.kt | 3 + .../IntUiMarkdownBlockRendererExtensions.kt | 2 + .../styling/IntUiMarkdownStyling.kt | 55 ++++- .../github/alerts/IntUiGitHubAlertStyling.kt | 12 ++ .../github/tables/IntUiGitHubTableStyling.kt | 5 + .../markdown/testing/MarkdownTestTheme.kt | 4 + .../jewel/samples/showcase/ShowcaseIcons.kt | 67 ++++++ .../samples/showcase/components/Badges.kt | 1 + .../samples/showcase/components/Banners.kt | 1 + .../samples/showcase/components/Borders.kt | 1 + .../samples/showcase/components/Buttons.kt | 1 + .../samples/showcase/components/Checkboxes.kt | 1 + .../showcase/components/ChipsAndTree.kt | 4 + .../samples/showcase/components/ComboBoxes.kt | 1 + .../samples/showcase/components/Icons.kt | 1 + .../samples/showcase/components/Links.kt | 1 + .../samples/showcase/components/Menus.kt | 1 + .../showcase/components/ProgressBar.kt | 1 + .../showcase/components/RadioButtons.kt | 1 + .../samples/showcase/components/Scrollbars.kt | 1 + .../showcase/components/SegmentedControls.kt | 1 + .../samples/showcase/components/Slider.kt | 1 + .../showcase/components/SplitLayouts.kt | 1 + .../jewel/samples/showcase/components/Tabs.kt | 1 + .../samples/showcase/components/TextAreas.kt | 1 + .../samples/showcase/components/TextFields.kt | 1 + .../samples/showcase/components/Tooltips.kt | 1 + .../samples/showcase/components/Typography.kt | 1 + .../samples/showcase/views/ComponentsView.kt | 8 + .../showcase/views/ComponentsViewModel.kt | 4 + .../jewel/samples/showcase/views/ViewInfo.kt | 15 ++ .../jewel/samples/standalone/IntUiThemes.kt | 12 ++ .../jewel/samples/standalone/Main.kt | 1 + .../standalone/viewmodel/MainViewModel.kt | 9 + .../jewel/scripts/annotate-detekt.main.kts | 94 +++++++++ .../jetbrains/jewel/ui/ComponentStyling.kt | 13 ++ .../jewel/ui/DefaultComponentStyling.kt | 40 ++++ .../jewel/ui/MenuItemShortcutHintProvider.kt | 2 + .../jewel/ui/MenuItemShortcutProvider.kt | 1 + .../kotlin/org/jetbrains/jewel/ui/Outline.kt | 3 +- .../org/jetbrains/jewel/ui/Typography.kt | 2 + .../jewel/ui/component/ActionButton.kt | 5 + .../org/jetbrains/jewel/ui/component/Badge.kt | 3 + .../jetbrains/jewel/ui/component/Button.kt | 13 +- .../jetbrains/jewel/ui/component/Checkbox.kt | 7 + .../org/jetbrains/jewel/ui/component/Chip.kt | 9 +- .../ui/component/CircularProgressIndicator.kt | 8 + .../jetbrains/jewel/ui/component/ComboBox.kt | 1 + .../jetbrains/jewel/ui/component/Divider.kt | 4 + .../jetbrains/jewel/ui/component/Dropdown.kt | 8 +- .../jewel/ui/component/EditableComboBox.kt | 26 ++- .../jewel/ui/component/GroupHeader.kt | 1 + .../org/jetbrains/jewel/ui/component/Icon.kt | 16 +- .../jewel/ui/component/IconActionButton.kt | 28 +++ .../jewel/ui/component/IconButton.kt | 47 ++++- .../jewel/ui/component/InlineBanner.kt | 2 - .../jewel/ui/component/InputField.kt | 11 +- .../jetbrains/jewel/ui/component/LazyTree.kt | 29 +++ .../org/jetbrains/jewel/ui/component/Link.kt | 16 +- .../jewel/ui/component/ListComboBox.kt | 3 + .../org/jetbrains/jewel/ui/component/Menu.kt | 37 +++- .../jewel/ui/component/MenuController.kt | 49 +++++ .../jewel/ui/component/PopupContainer.kt | 11 + .../jewel/ui/component/PopupManager.kt | 2 +- .../jewel/ui/component/RadioButton.kt | 9 +- .../jewel/ui/component/ScrollableContainer.kt | 3 + .../jewel/ui/component/SegmentedControl.kt | 21 +- .../ui/component/SegmentedControlButton.kt | 10 +- .../component/SelectableIconActionButton.kt | 16 ++ .../jewel/ui/component/SimpleListItem.kt | 12 +- .../jetbrains/jewel/ui/component/Slider.kt | 11 +- .../jewel/ui/component/SpeedSearchArea.kt | 14 ++ .../jewel/ui/component/SplitLayout.kt | 4 +- .../jetbrains/jewel/ui/component/TabStrip.kt | 18 +- .../org/jetbrains/jewel/ui/component/Tabs.kt | 18 +- .../component/ToggleableIconActionButton.kt | 26 +++ .../jewel/ui/component/Typography.kt | 2 + .../jewel/ui/component/search/Highlight.kt | 14 ++ .../search/SpeedSearchableComboBox.kt | 1 + .../search/SpeedSearchableLazyColumn.kt | 36 ++++ .../component/search/SpeedSearchableTree.kt | 1 + .../ui/component/styling/BadgeStyling.kt | 5 + .../ui/component/styling/BannerStyling.kt | 47 ++++- .../ui/component/styling/ButtonStyling.kt | 40 ++++ .../ui/component/styling/CheckboxStyling.kt | 45 +++- .../jewel/ui/component/styling/ChipStyling.kt | 67 +++++- .../styling/CircularProgressStyle.kt | 10 +- .../ui/component/styling/ComboBoxStyling.kt | 56 ++++- .../ui/component/styling/DividerStyling.kt | 20 +- .../ui/component/styling/DropdownStyling.kt | 48 ++++- .../component/styling/GroupHeaderStyling.kt | 26 ++- .../styling/HorizontalProgressBarStyling.kt | 23 ++ .../ui/component/styling/IconButtonStyling.kt | 62 +++++- .../ui/component/styling/InputFieldStyling.kt | 53 +++++ .../ui/component/styling/LazyTreeStyling.kt | 20 ++ .../jewel/ui/component/styling/LinkStyling.kt | 40 +++- .../jewel/ui/component/styling/MenuStyling.kt | 81 ++++++- .../ui/component/styling/PopupAdStyle.kt | 26 ++- .../component/styling/PopupContainerStyle.kt | 28 ++- .../component/styling/RadioButtonStyling.kt | 31 ++- .../ui/component/styling/ScrollbarStyling.kt | 10 + .../ui/component/styling/SearchMatchStyle.kt | 24 ++- .../styling/SegmentedControlButtonStyling.kt | 43 ++++ .../styling/SegmentedControlStyling.kt | 22 +- .../styling/SelectableLazyColumnStyle.kt | 13 +- .../component/styling/SimpleListItemStyle.kt | 38 +++- .../ui/component/styling/SliderStyling.kt | 41 ++++ .../ui/component/styling/SpeedSearchStyle.kt | 26 ++- .../component/styling/SplitButtonStyling.kt | 21 +- .../jewel/ui/component/styling/TabStyling.kt | 79 ++++++- .../ui/component/styling/TextAreaStyling.kt | 14 ++ .../ui/component/styling/TextFieldStyling.kt | 41 ++++ .../ui/component/styling/TooltipStyling.kt | 41 ++++ .../ui/icon/ComposeImageResourceProvider.kt | 1 + .../ui/icon/ComposeLayerPaintingContext.kt | 13 ++ .../org/jetbrains/jewel/ui/icon/IconKey.kt | 15 ++ .../org/jetbrains/jewel/ui/icon/IconUtils.kt | 35 ++++ .../jetbrains/jewel/ui/icon/NewUiChecker.kt | 4 + .../jetbrains/jewel/ui/painter/PainterHint.kt | 5 + .../jewel/ui/painter/PainterHintsProvider.kt | 1 + .../jewel/ui/painter/PainterProviderScope.kt | 6 + .../ui/painter/ResourcePainterProvider.kt | 13 ++ .../jewel/ui/painter/badge/DotBadgeShape.kt | 6 + .../EmbeddedToInlineCssStyleSvgPatchHint.kt | 1 + .../jewel/ui/painter/hints/Selected.kt | 1 + .../ui/platform/PlatformCursorController.kt | 1 + .../jetbrains/jewel/ui/theme/JewelTheme.kt | 48 +++++ .../jewel/ui/util/MessageResourceResolver.kt | 1 + 265 files changed, 4050 insertions(+), 224 deletions(-) create mode 100644 platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/JewelBaseRule.kt create mode 100644 platform/jewel/scripts/annotate-detekt.main.kts diff --git a/.github/workflows/jewel-checks.yml b/.github/workflows/jewel-checks.yml index bafad1e34de5..45865dc7fb8a 100644 --- a/.github/workflows/jewel-checks.yml +++ b/.github/workflows/jewel-checks.yml @@ -43,7 +43,7 @@ jobs: - name: Run :check task # Run checks for all modules except the IDE plugin sample, as that is bound to have missing APIs issues - run: ./gradlew check --continue --no-daemon + run: ./gradlew check -x detekt --continue --no-daemon - name: Annotate JUnit test failures uses: mikepenz/action-junit-report@v6 @@ -61,9 +61,25 @@ jobs: retention-days: 7 - name: Run detekt tasks + id: detekt + if: ${{ !cancelled() }} # Run detekt checks for all modules except the IDE plugin sample, as that is bound to have missing APIs issues run: ./gradlew detekt detektMain detektTest --continue --no-daemon + - name: Set up Kotlin ${{ env.KOTLIN_VERSION }} + id: kotlin + if: ${{ !cancelled() && steps.detekt.outcome != 'skipped' }} + uses: ./.github/actions/setup-kotlin + with: + version: ${{ env.KOTLIN_VERSION }} + + - name: Annotate detekt findings + if: ${{ !cancelled() && steps.detekt.outcome != 'skipped' }} + # Turn detekt's checkstyle reports (main.xml from detektMain, test.xml from detektTest) into inline + # GitHub annotations on the PR's "Files changed" tab, plus a run summary. The failing detekt task is + # the gate; this is visibility. Works for fork PRs too (annotations, not API-driven comments). + run: ${{ steps.kotlin.outputs.bin-dir }}/kotlin ./scripts/annotate-detekt.main.kts + check_paths: name: Check changed files runs-on: ubuntu-latest diff --git a/platform/jewel/.editorconfig b/platform/jewel/.editorconfig index 5dda86ceba44..cec88ddfc71f 100644 --- a/platform/jewel/.editorconfig +++ b/platform/jewel/.editorconfig @@ -49,6 +49,7 @@ ktlint_standard_try-catch-finally-spacing = disabled ktlint_standard_blank-line-between-when-conditions = disabled ktlint_standard_when-entry-bracing = disabled ktlint_standard_wrapping = disabled +ktlint_standard_spacing-between-declarations-with-comments=disabled trim_trailing_whitespace = false [gradlew.bat] diff --git a/platform/jewel/buildSrc/src/main/kotlin/jewel-linting.gradle.kts b/platform/jewel/buildSrc/src/main/kotlin/jewel-linting.gradle.kts index 4456b55ed2b4..6fc8cca18eeb 100644 --- a/platform/jewel/buildSrc/src/main/kotlin/jewel-linting.gradle.kts +++ b/platform/jewel/buildSrc/src/main/kotlin/jewel-linting.gradle.kts @@ -8,10 +8,11 @@ plugins { detekt { // TODO: JEWEL-1329 standalone analysis API initialises PSI documents as read-only, Detekt tries to open in writing mode. - // enable it once it has been fixed. - autoCorrect = false + // We are able to circumvent this using JewelBaseRule and JewelRuleSet for now. + autoCorrect = System.getenv("CI") == null config.from(files(rootProject.file("detekt.yml"))) buildUponDefaultConfig = true + debug = providers.gradleProperty("detekt.debug").map { it.toBoolean() }.getOrElse(false) } dependencies { diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/DecoratedWindowIconKeys.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/DecoratedWindowIconKeys.kt index 55f3d523b607..8d34313497c6 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/DecoratedWindowIconKeys.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/DecoratedWindowIconKeys.kt @@ -3,9 +3,17 @@ package org.jetbrains.jewel.intui.window import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icon.PathIconKey +/** Icon keys for the decorated window control buttons (minimize, maximize, restore, close). */ public object DecoratedWindowIconKeys { + /** The icon key for the minimize button. */ public val minimize: IconKey = PathIconKey("window/minimize.svg", this::class.java) + + /** The icon key for the maximize button. */ public val maximize: IconKey = PathIconKey("window/maximize.svg", this::class.java) + + /** The icon key for the restore button. */ public val restore: IconKey = PathIconKey("window/restore.svg", this::class.java) + + /** The icon key for the close button. */ public val close: IconKey = PathIconKey("window/close.svg", this::class.java) } diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/IntUiTheme.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/IntUiTheme.kt index 5ca966e8fae6..8e2e54342e99 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/IntUiTheme.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/IntUiTheme.kt @@ -9,6 +9,15 @@ import org.jetbrains.jewel.window.styling.LocalDecoratedWindowStyle import org.jetbrains.jewel.window.styling.LocalTitleBarStyle import org.jetbrains.jewel.window.styling.TitleBarStyle +/** + * Provides [DecoratedWindowStyle] and [TitleBarStyle] into this [ComponentStyling], defaulting to the Int UI light or + * dark variants based on [JewelTheme.isDark]. + * + * @param windowStyle The [DecoratedWindowStyle] to use. Defaults to [DecoratedWindowStyle.dark] or + * [DecoratedWindowStyle.light] based on the current theme. + * @param titleBarStyle The [TitleBarStyle] to use. Defaults to [TitleBarStyle.dark] or [TitleBarStyle.light] based on + * the current theme. + */ public fun ComponentStyling.decoratedWindow( windowStyle: DecoratedWindowStyle? = null, titleBarStyle: TitleBarStyle? = null, diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiDecoratedWindowStyling.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiDecoratedWindowStyling.kt index 8909315790bb..71d881772942 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiDecoratedWindowStyling.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiDecoratedWindowStyling.kt @@ -7,27 +7,56 @@ import org.jetbrains.jewel.window.styling.DecoratedWindowColors import org.jetbrains.jewel.window.styling.DecoratedWindowMetrics import org.jetbrains.jewel.window.styling.DecoratedWindowStyle +/** + * Creates an Int UI light [DecoratedWindowStyle]. + * + * @param colors The [DecoratedWindowColors] to use. Defaults to [DecoratedWindowColors.light]. + * @param metrics The [DecoratedWindowMetrics] to use. Defaults to [DecoratedWindowMetrics.defaults]. + */ public fun DecoratedWindowStyle.Companion.light( colors: DecoratedWindowColors = DecoratedWindowColors.light(), metrics: DecoratedWindowMetrics = DecoratedWindowMetrics.defaults(), ): DecoratedWindowStyle = DecoratedWindowStyle(colors, metrics) +/** + * Creates an Int UI dark [DecoratedWindowStyle]. + * + * @param colors The [DecoratedWindowColors] to use. Defaults to [DecoratedWindowColors.dark]. + * @param metrics The [DecoratedWindowMetrics] to use. Defaults to [DecoratedWindowMetrics.defaults]. + */ public fun DecoratedWindowStyle.Companion.dark( colors: DecoratedWindowColors = DecoratedWindowColors.dark(), metrics: DecoratedWindowMetrics = DecoratedWindowMetrics.defaults(), ): DecoratedWindowStyle = DecoratedWindowStyle(colors, metrics) +/** + * Creates Int UI light [DecoratedWindowColors] using the standard undecorated window border color. + * + * @param borderColor The active window border color. Defaults to `#5A5D6B`. + * @param inactiveBorderColor The inactive window border color. Defaults to [borderColor]. + */ public fun DecoratedWindowColors.Companion.light( // from Window.undecorated.border borderColor: Color = Color(0xFF5A5D6B), inactiveBorderColor: Color = borderColor, ): DecoratedWindowColors = DecoratedWindowColors(borderColor, inactiveBorderColor) +/** + * Creates Int UI dark [DecoratedWindowColors] using the standard undecorated window border color. + * + * @param borderColor The active window border color. Defaults to `#5A5D63`. + * @param inactiveBorderColor The inactive window border color. Defaults to [borderColor]. + */ public fun DecoratedWindowColors.Companion.dark( // from Window.undecorated.border borderColor: Color = Color(0xFF5A5D63), inactiveBorderColor: Color = borderColor, ): DecoratedWindowColors = DecoratedWindowColors(borderColor, inactiveBorderColor) +/** + * Creates default [DecoratedWindowMetrics] with a 1dp border width. + * + * @param borderWidth The width of the border drawn around the undecorated window on Linux. + */ public fun DecoratedWindowMetrics.Companion.defaults(borderWidth: Dp = 1.dp): DecoratedWindowMetrics = DecoratedWindowMetrics(borderWidth) diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiTitleBarStyling.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiTitleBarStyling.kt index 399aacb84c61..8dd6f94b8d4e 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiTitleBarStyling.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/intui/window/styling/IntUiTitleBarStyling.kt @@ -27,6 +27,13 @@ import org.jetbrains.jewel.window.styling.TitleBarIcons import org.jetbrains.jewel.window.styling.TitleBarMetrics import org.jetbrains.jewel.window.styling.TitleBarStyle +/** + * Creates an Int UI light [TitleBarStyle] with the standard IntelliJ dark-header appearance. + * + * @param colors The [TitleBarColors] to use. Defaults to [TitleBarColors.light]. + * @param metrics The [TitleBarMetrics] to use. Defaults to [TitleBarMetrics.defaults]. + * @param icons The [TitleBarIcons] to use. Defaults to [TitleBarIcons.defaults]. + */ @Composable public fun TitleBarStyle.Companion.light( colors: TitleBarColors = TitleBarColors.light(), @@ -78,6 +85,13 @@ public fun TitleBarStyle.Companion.light( ), ) +/** + * Creates an Int UI [TitleBarStyle] with a light-colored header, matching the "New UI" appearance. + * + * @param colors The [TitleBarColors] to use. Defaults to [TitleBarColors.lightWithLightHeader]. + * @param metrics The [TitleBarMetrics] to use. Defaults to [TitleBarMetrics.defaults]. + * @param icons The [TitleBarIcons] to use. Defaults to [TitleBarIcons.defaults]. + */ @Composable public fun TitleBarStyle.Companion.lightWithLightHeader( colors: TitleBarColors = TitleBarColors.lightWithLightHeader(), @@ -128,6 +142,13 @@ public fun TitleBarStyle.Companion.lightWithLightHeader( ), ) +/** + * Creates an Int UI dark [TitleBarStyle]. + * + * @param colors The [TitleBarColors] to use. Defaults to [TitleBarColors.dark]. + * @param metrics The [TitleBarMetrics] to use. Defaults to [TitleBarMetrics.defaults]. + * @param icons The [TitleBarIcons] to use. Defaults to [TitleBarIcons.defaults]. + */ @Composable public fun TitleBarStyle.Companion.dark( colors: TitleBarColors = TitleBarColors.dark(), @@ -200,6 +221,7 @@ private fun titleBarIconButtonStyle(hoveredBackground: Color, pressedBackground: metrics, ) +/** Creates Int UI light [TitleBarColors] for the standard IntelliJ dark-header title bar. */ @Composable public fun TitleBarColors.Companion.light( backgroundColor: Color = IntUiLightTheme.colors.gray(2), @@ -247,6 +269,7 @@ public fun TitleBarColors.Companion.light( dropdownPressedBackground = dropdownPressedBackground, ) +/** Creates Int UI [TitleBarColors] for a light-colored title bar header, as used in the New UI. */ @Composable public fun TitleBarColors.Companion.lightWithLightHeader( backgroundColor: Color = IntUiLightTheme.colors.gray(13), @@ -279,6 +302,7 @@ public fun TitleBarColors.Companion.lightWithLightHeader( dropdownPressedBackground = dropdownPressedBackground, ) +/** Creates Int UI dark [TitleBarColors]. */ @Composable public fun TitleBarColors.Companion.dark( backgroundColor: Color = IntUiDarkTheme.colors.gray(2), @@ -311,6 +335,14 @@ public fun TitleBarColors.Companion.dark( dropdownPressedBackground = dropdownPressedBackground, ) +/** + * Creates default [TitleBarMetrics] with standard Int UI values. + * + * @param height The title bar height. Defaults to `40.dp`. + * @param gradientStartX The horizontal start position of the background gradient. Defaults to `-100.dp`. + * @param gradientEndX The horizontal end position of the background gradient. Defaults to `400.dp`. + * @param titlePaneButtonSize The size of window control buttons (minimize, maximize, close). Defaults to `40x40.dp`. + */ public fun TitleBarMetrics.Companion.defaults( height: Dp = 40.dp, gradientStartX: Dp = (-100).dp, @@ -318,6 +350,14 @@ public fun TitleBarMetrics.Companion.defaults( titlePaneButtonSize: DpSize = DpSize(40.dp, 40.dp), ): TitleBarMetrics = TitleBarMetrics(height, gradientStartX, gradientEndX, titlePaneButtonSize) +/** + * Creates default [TitleBarIcons] using the standard [DecoratedWindowIconKeys] for window controls. + * + * @param minimizeButton The icon key for the minimize button. + * @param maximizeButton The icon key for the maximize button. + * @param restoreButton The icon key for the restore button. + * @param closeButton The icon key for the close button. + */ public fun TitleBarIcons.Companion.defaults( minimizeButton: IconKey = DecoratedWindowIconKeys.minimize, maximizeButton: IconKey = DecoratedWindowIconKeys.maximize, diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/DecoratedWindow.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/DecoratedWindow.kt index 1d7a9005a14b..d47a7e753b2f 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/DecoratedWindow.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/DecoratedWindow.kt @@ -48,6 +48,28 @@ import org.jetbrains.jewel.intui.standalone.window.Window import org.jetbrains.jewel.window.styling.DecoratedWindowStyle import org.jetbrains.jewel.window.utils.DesktopPlatform +/** + * A Compose window with custom JetBrains Runtime (JBR) window decorations, including support for a custom [TitleBar]. + * Requires the application to run on JetBrains Runtime; an error is thrown at runtime if JBR is not available. + * + * On Linux, the window is rendered undecorated with a 1dp border drawn by Compose to simulate a native frame. + * + * @param onCloseRequest Callback invoked when the user requests to close the window. + * @param state The [WindowState] controlling the window's size and placement. + * @param visible Whether the window is visible. + * @param title The title shown in the OS window frame and taskbar. + * @param icon The icon shown in the OS window frame and taskbar. + * @param resizable Whether the user can resize the window. + * @param enabled Whether the window is enabled for user interaction. + * @param focusable Whether the window can receive focus. + * @param alwaysOnTop Whether the window is always displayed on top of other windows. + * @param onPreviewKeyEvent Callback invoked for key events before they are dispatched to children. Return `true` to + * consume the event. + * @param onKeyEvent Callback invoked for key events after they are dispatched to children. Return `true` to consume the + * event. + * @param style The [DecoratedWindowStyle] controlling the window frame's visual appearance. + * @param content The composable content displayed inside the window, scoped to a [DecoratedWindowScope]. + */ @Suppress("ModifierMissing") @Composable public fun DecoratedWindow( @@ -184,10 +206,13 @@ public fun DecoratedWindow( } } +/** Scope provided to content composables inside a [DecoratedWindow], exposing the [window] and its [state]. */ @Stable public interface DecoratedWindowScope : FrameWindowScope { + /** The [ComposeWindow] backing this decorated window. */ override val window: ComposeWindow + /** The current visual state of the decorated window. */ public val state: DecoratedWindowState } @@ -230,21 +255,37 @@ private object DecoratedWindowMeasurePolicy : MeasurePolicy { } } +/** Encodes the visual state of a decorated window (active, fullscreen, minimized, maximized) as a bit mask. */ @Immutable @JvmInline -public value class DecoratedWindowState(public val state: ULong) { +public value class DecoratedWindowState( + /** The raw bit mask encoding the current window state flags. */ + public val state: ULong +) { + /** Whether the window is currently active (focused). */ public val isActive: Boolean get() = state and Active != 0UL + /** Whether the window is in fullscreen mode. */ public val isFullscreen: Boolean get() = state and Fullscreen != 0UL + /** Whether the window is minimized. */ public val isMinimized: Boolean get() = state and Minimize != 0UL + /** Whether the window is maximized. */ public val isMaximized: Boolean get() = state and Maximize != 0UL + /** + * Returns a copy of this [DecoratedWindowState] with the given fields replaced by their new values. + * + * @param fullscreen Whether the window is in fullscreen mode. + * @param minimized Whether the window is minimized. + * @param maximized Whether the window is maximized. + * @param active Whether the window is active (focused). + */ public fun copy( fullscreen: Boolean = isFullscreen, minimized: Boolean = isMinimized, @@ -254,12 +295,28 @@ public value class DecoratedWindowState(public val state: ULong) { override fun toString(): String = "${javaClass.simpleName}(isFullscreen=$isFullscreen, isActive=$isActive)" + /** State bit constants and the [of] factory for constructing [DecoratedWindowState] values. */ public companion object { + /** Bit flag for the active (focused) state. */ public val Active: ULong = 1UL shl 0 + + /** Bit flag for the fullscreen state. */ public val Fullscreen: ULong = 1UL shl 1 + + /** Bit flag for the minimized state. */ public val Minimize: ULong = 1UL shl 2 + + /** Bit flag for the maximized state. */ public val Maximize: ULong = 1UL shl 3 + /** + * Constructs a [DecoratedWindowState] from individual boolean flags. + * + * @param fullscreen Whether the window is in fullscreen mode. + * @param minimized Whether the window is minimized. + * @param maximized Whether the window is maximized. + * @param active Whether the window is active (focused). + */ public fun of( fullscreen: Boolean = false, minimized: Boolean = false, @@ -273,6 +330,12 @@ public value class DecoratedWindowState(public val state: ULong) { (if (active) Active else 0UL) ) + /** + * Constructs a [DecoratedWindowState] by reading the current placement and activation state of the given + * [ComposeWindow]. + * + * @param window The [ComposeWindow] to read state from. + */ public fun of(window: ComposeWindow): DecoratedWindowState = of( fullscreen = window.placement == WindowPlacement.Fullscreen, diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/Theme.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/Theme.kt index cc0dd7db7c1f..1a411e2b5eab 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/Theme.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/Theme.kt @@ -8,8 +8,10 @@ import org.jetbrains.jewel.window.styling.LocalDecoratedWindowStyle import org.jetbrains.jewel.window.styling.LocalTitleBarStyle import org.jetbrains.jewel.window.styling.TitleBarStyle +/** The default title bar style provided by the current theme. */ public val JewelTheme.Companion.defaultTitleBarStyle: TitleBarStyle @Composable @ReadOnlyComposable get() = LocalTitleBarStyle.current +/** The default decorated window style provided by the current theme. */ public val JewelTheme.Companion.defaultDecoratedWindowStyle: DecoratedWindowStyle @Composable @ReadOnlyComposable get() = LocalDecoratedWindowStyle.current diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt index 3ec9175dfa7c..f4c02fbb432f 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt @@ -15,6 +15,13 @@ import org.jetbrains.jewel.intui.standalone.window.macos.LocalMacPlatformService import org.jetbrains.jewel.window.styling.TitleBarStyle import org.jetbrains.jewel.window.utils.WindowMouseEventEffect +/** + * Enables or disables the macOS "new fullscreen controls" (the three colored circles displayed in the upper-left corner + * of a window in fullscreen mode). When enabled, the background color of the controls is taken from + * [TitleBarColors.fullscreenControlButtonsBackground]. + * + * @param newControls Whether to use the new fullscreen controls. Defaults to `true`. + */ public fun Modifier.newFullscreenControls(newControls: Boolean = true): Modifier = this then NewFullscreenControlsElement( diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt index 56366e9b645f..536052428372 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt @@ -60,6 +60,18 @@ internal const val TITLE_BAR_LAYOUT_ID = "__TITLE_BAR_CONTENT__" internal const val TITLE_BAR_BORDER_LAYOUT_ID = "__TITLE_BAR_BORDER__" +/** + * Renders the title bar for a [DecoratedWindow], routing to the platform-specific implementation for macOS, Windows, + * and Linux. Content is laid out using [TitleBarScope.align] to position children at the start, center, or end of the + * bar. + * + * @param modifier The [Modifier] to apply to the title bar container. + * @param gradientStartColor An optional color used as the center point of a horizontal gradient blended with the + * background. Use [Color.Unspecified] for a solid background. + * @param style The [TitleBarStyle] controlling the bar's visual appearance. + * @param content The composable content rendered inside the title bar, provided with the current + * [DecoratedWindowState]. + */ @Composable public fun DecoratedWindowScope.TitleBar( modifier: Modifier = Modifier, @@ -243,11 +255,18 @@ internal fun rememberTitleBarMeasurePolicy( applyTitleBar: (Dp, DecoratedWindowState) -> PaddingValues, ): MeasurePolicy = remember(window, state, applyTitleBar) { TitleBarMeasurePolicy(window, state, applyTitleBar) } +/** Scope provided to content composables inside a title bar, exposing the window [title], [icon], and alignment. */ public interface TitleBarScope { public val title: String public val icon: Painter? + /** + * Aligns this title bar child element horizontally to [Start][Alignment.Start], [End][Alignment.End], or + * [CenterHorizontally][Alignment.CenterHorizontally]. + * + * @param alignment The horizontal alignment to apply to this element. + */ @Stable public fun Modifier.align(alignment: Alignment.Horizontal): Modifier } diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/DecoratedWindowStyling.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/DecoratedWindowStyling.kt index 82f935e4ac57..eeba4c00ad83 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/DecoratedWindowStyling.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/DecoratedWindowStyling.kt @@ -11,10 +11,13 @@ import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.window.DecoratedWindowState +/** Defines the overall visual style of a decorated window, combining its colors and metrics. */ @Immutable @GenerateDataFunctions public class DecoratedWindowStyle( + /** The colors used for the decorated window frame. */ public val colors: DecoratedWindowColors, + /** The layout metrics for the decorated window frame. */ public val metrics: DecoratedWindowMetrics, ) { override fun equals(other: Any?): Boolean { @@ -37,12 +40,25 @@ public class DecoratedWindowStyle( override fun toString(): String = "DecoratedWindowStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [DecoratedWindowStyle]. */ public companion object } +/** Holds the border colors used for the decorated window frame in active and inactive states. */ @Immutable @GenerateDataFunctions -public class DecoratedWindowColors(public val border: Color, public val borderInactive: Color) { +public class DecoratedWindowColors( + /** The border color when the window is active. */ + public val border: Color, + /** The border color when the window is inactive. */ + public val borderInactive: Color, +) { + /** + * Returns a [State] holding the border color appropriate for the given [state]: the inactive border color when the + * window is not active, or the active border color otherwise. + * + * @param state The current [DecoratedWindowState] of the window. + */ @Composable public fun borderFor(state: DecoratedWindowState): State = rememberUpdatedState( @@ -72,12 +88,17 @@ public class DecoratedWindowColors(public val border: Color, public val borderIn override fun toString(): String = "DecoratedWindowColors(border=$border, borderInactive=$borderInactive)" + /** Companion object for [DecoratedWindowColors]. */ public companion object } +/** Holds the layout metrics for the decorated window frame, such as border width. */ @Immutable @GenerateDataFunctions -public class DecoratedWindowMetrics(public val borderWidth: Dp) { +public class DecoratedWindowMetrics( + /** The width of the decorated window border. */ + public val borderWidth: Dp +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -91,9 +112,11 @@ public class DecoratedWindowMetrics(public val borderWidth: Dp) { override fun toString(): String = "DecoratedWindowMetrics(borderWidth=$borderWidth)" + /** Companion object for [DecoratedWindowMetrics]. */ public companion object } +/** CompositionLocal providing the current [DecoratedWindowStyle]. */ public val LocalDecoratedWindowStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DecoratedWindowStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/TitleBarStyling.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/TitleBarStyling.kt index 8d26a00654da..c09adeaae646 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/TitleBarStyling.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/styling/TitleBarStyling.kt @@ -16,15 +16,23 @@ import org.jetbrains.jewel.ui.component.styling.IconButtonStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.window.DecoratedWindowState +/** Defines the overall visual style of the title bar, combining its colors, metrics, icons, and button styles. */ @Stable @GenerateDataFunctions public class TitleBarStyle( + /** The color tokens used by the title bar. */ public val colors: TitleBarColors, + /** The layout metrics for the title bar. */ public val metrics: TitleBarMetrics, + /** The icon keys for the title bar's window control buttons. */ public val icons: TitleBarIcons, + /** The style applied to dropdowns rendered inside the title bar. */ public val dropdownStyle: DropdownStyle, + /** The style applied to icon buttons rendered inside the title bar. */ public val iconButtonStyle: IconButtonStyle, + /** The style applied to window control pane buttons (minimize, maximize, restore). */ public val paneButtonStyle: IconButtonStyle, + /** The style applied to the window close pane button. */ public val paneCloseButtonStyle: IconButtonStyle, ) { override fun equals(other: Any?): Boolean { @@ -67,32 +75,47 @@ public class TitleBarStyle( ")" } + /** Companion object for [TitleBarStyle]. */ public companion object } +/** Holds all color tokens used by the title bar in its various interactive and focus states. */ @Immutable @GenerateDataFunctions public class TitleBarColors( + /** The background color when the window is active. */ public val background: Color, + /** The background color when the window is inactive. */ public val inactiveBackground: Color, + /** The foreground/content color of the title bar. */ public val content: Color, + /** The border color of the title bar. */ public val border: Color, - // The background color for newControlButtons(three circles in left top corner) in MacOS - // fullscreen mode + /** The background color for the macOS fullscreen control buttons (the three circles in the top-left corner). */ public val fullscreenControlButtonsBackground: Color, - // The hover and press background color for window control buttons(minimize, maximize) in Linux + /** The background color for window control buttons (minimize, maximize) on Linux when hovered. */ public val titlePaneButtonHoveredBackground: Color, + /** The background color for window control buttons (minimize, maximize) on Linux when pressed. */ public val titlePaneButtonPressedBackground: Color, - // The hover and press background color for window close button in Linux + /** The background color for the window close button on Linux when hovered. */ public val titlePaneCloseButtonHoveredBackground: Color, + /** The background color for the window close button on Linux when pressed. */ public val titlePaneCloseButtonPressedBackground: Color, - // The hover and press background color for IconButtons in title bar content + /** The background color for icon buttons in the title bar content area when hovered. */ public val iconButtonHoveredBackground: Color, + /** The background color for icon buttons in the title bar content area when pressed. */ public val iconButtonPressedBackground: Color, - // The hover and press background color for Dropdown in title bar content + /** The background color for dropdowns in the title bar content area when pressed. */ public val dropdownPressedBackground: Color, + /** The background color for dropdowns in the title bar content area when hovered. */ public val dropdownHoveredBackground: Color, ) { + /** + * Returns a [State] holding the background color appropriate for the given [state]: the inactive background when + * the window is not active, or the active background otherwise. + * + * @param state The current [DecoratedWindowState] of the window. + */ @Composable public fun backgroundFor(state: DecoratedWindowState): State = rememberUpdatedState( @@ -160,15 +183,21 @@ public class TitleBarColors( ")" } + /** Companion object for [TitleBarColors]. */ public companion object } +/** Holds the layout metrics for the title bar: height, gradient positions, and control button size. */ @Immutable @GenerateDataFunctions public class TitleBarMetrics( + /** The height of the title bar. */ public val height: Dp, + /** The horizontal start position of the title bar gradient. */ public val gradientStartX: Dp, + /** The horizontal end position of the title bar gradient. */ public val gradientEndX: Dp, + /** The size of the window control pane buttons (minimize, maximize, restore, close). */ public val titlePaneButtonSize: DpSize, ) { override fun equals(other: Any?): Boolean { @@ -202,15 +231,21 @@ public class TitleBarMetrics( ")" } + /** Companion object for [TitleBarMetrics]. */ public companion object } +/** Holds the icon keys for the title bar's window control buttons (minimize, maximize, restore, close). */ @Immutable @GenerateDataFunctions public class TitleBarIcons( + /** The icon key for the minimize window control button. */ public val minimizeButton: IconKey, + /** The icon key for the maximize window control button. */ public val maximizeButton: IconKey, + /** The icon key for the restore window control button. */ public val restoreButton: IconKey, + /** The icon key for the close window control button. */ public val closeButton: IconKey, ) { override fun equals(other: Any?): Boolean { @@ -244,9 +279,11 @@ public class TitleBarIcons( ")" } + /** Companion object for [TitleBarIcons]. */ public companion object } +/** CompositionLocal that provides the current [TitleBarStyle]. Must be provided by the active theme. */ public val LocalTitleBarStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No TitleBarStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/utils/DesktopPlatform.kt b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/utils/DesktopPlatform.kt index d135294db1fa..dc43be75bade 100644 --- a/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/utils/DesktopPlatform.kt +++ b/platform/jewel/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/utils/DesktopPlatform.kt @@ -1,12 +1,22 @@ package org.jetbrains.jewel.window.utils +/** Identifies the desktop operating system the application is currently running on. */ public enum class DesktopPlatform { + /** The Linux operating system. */ Linux, + + /** The Windows operating system. */ Windows, + + /** The macOS operating system. */ MacOS, + + /** An unrecognized or unsupported operating system. */ Unknown; + /** Provides the [Current] platform detected from system properties. */ public companion object { + /** The [DesktopPlatform] detected from the `os.name` system property at runtime. */ public val Current: DesktopPlatform by lazy { val name = System.getProperty("os.name") when { diff --git a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/JewelRuleSetProvider.kt b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/JewelRuleSetProvider.kt index 28db3a7c0619..6a506ad63bc6 100644 --- a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/JewelRuleSetProvider.kt +++ b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/JewelRuleSetProvider.kt @@ -2,15 +2,37 @@ // Apache 2.0 license. package org.jetbrains.jewel.detekt +import com.intellij.core.CoreApplicationEnvironment +import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.impl.source.tree.TreeCopyHandler import dev.detekt.api.RuleSet import dev.detekt.api.RuleSetId import dev.detekt.api.RuleSetProvider import org.jetbrains.jewel.detekt.rules.EqualityMembersRule import org.jetbrains.jewel.detekt.rules.MissingApiStatusAnnotationRule +/** Registers Jewel's custom Detekt rules under the `jewel` rule set ID. */ class JewelRuleSetProvider : RuleSetProvider { override val ruleSetId: RuleSetId = RuleSetId("jewel") + init { + // Detekt's standalone Analysis API does not register treeCopyHandler (it was intentionally removed in + // https://github.com/detekt/detekt/commit/ba593207d90e97c96c890740a8a3cf3d0978aee2 as KtLint was phasing + // it out). However, our autocorrect rules use high-level PSI manipulation APIs (e.g. addDeclaration) that + // require cross-tree node copies, which internally look up this extension point. We register it here at the + // earliest point in the Detekt plugin lifecycle so that it is available before any analysis begins. + // The registration must happen here rather than in individual rules, as the RuleSetProvider is loaded via + // ServiceLoader before the Analysis API session is created. + val extensionArea = ApplicationManager.getApplication().extensionArea + if (!extensionArea.hasExtensionPoint(TreeCopyHandler.EP_NAME)) { + CoreApplicationEnvironment.registerExtensionPoint( + extensionArea, + TreeCopyHandler.EP_NAME, + TreeCopyHandler::class.java, + ) + } + } + override fun instance(): RuleSet = RuleSet(ruleSetId, rules = listOf(::EqualityMembersRule, ::MissingApiStatusAnnotationRule)) } diff --git a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/EqualityMembersRule.kt b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/EqualityMembersRule.kt index 2ac54d5edd3f..7dad37ab4d72 100644 --- a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/EqualityMembersRule.kt +++ b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/EqualityMembersRule.kt @@ -5,9 +5,9 @@ package org.jetbrains.jewel.detekt.rules import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.impl.source.tree.LeafPsiElement import dev.detekt.api.Config +import dev.detekt.api.Configuration import dev.detekt.api.Entity import dev.detekt.api.Finding -import dev.detekt.api.Rule import dev.detekt.api.config import dev.detekt.api.internal.AutoCorrectable import org.jetbrains.kotlin.lexer.KtTokens @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType @@ -31,9 +32,11 @@ private const val RULE_DESCRIPTION = "This rule detects missing or incomplete eq * correctly implemented based on the class's properties. Formatting of the auto-corrected code is left to the IDE's * formatter/ktfmt. */ -@AutoCorrectable(since = "0.38.0") -class EqualityMembersRule(config: Config) : Rule(config, RULE_DESCRIPTION) { +@AutoCorrectable(since = "0.40.0") +class EqualityMembersRule(config: Config) : JewelBaseRule(config, RULE_DESCRIPTION) { private val functionsToCheck: List by config(defaultValue = listOf("equals", "hashCode", "toString")) + + @Configuration("Only check classes annotated with these annotations") private val annotated: List by config(defaultValue = listOf("GenerateDataFunctions")) override fun visitClass(klass: KtClass) { @@ -147,7 +150,17 @@ class EqualityMembersRule(config: Config) : Rule(config, RULE_DESCRIPTION) { // Clean up class code after the fixes val factory = KtPsiFactory(klass.project) val body = checkNotNull(klass.body) - if (body.lastChild is LeafPsiElement && (body.lastChild as LeafPsiElement).elementType == KtTokens.RBRACE) { + val companionObject = + klass.declarations.filterIsInstance().firstOrNull { it.isCompanion() } + + if (companionObject != null) { + // Ensure a blank line separates the last generated function from the companion object + if (companionObject.prevSibling is KtFunction) { + body.addBefore(factory.createWhiteSpace("\n\n"), companionObject) + } + } else if ( + body.lastChild is LeafPsiElement && (body.lastChild as LeafPsiElement).elementType == KtTokens.RBRACE + ) { when (val prevSibling = body.lastChild.prevSibling) { is KtFunction -> { // Missing newline before rbrace @@ -212,9 +225,17 @@ class EqualityMembersRule(config: Config) : Rule(config, RULE_DESCRIPTION) { private fun generateToStringFunction(klass: KtClass, props: Set) { generateFunction(klass) { appendLine("override fun toString(): String {") - append(" return \"${klass.name}(") - append(props.joinToString(", ") { "$it=$$it" }) - appendLine(")\"") + appendLine(" return \"${klass.name}(\" +") + val propsList = props.toList() + for ((index, prop) in propsList.withIndex()) { + val isLast = index == propsList.lastIndex + if (isLast) { + appendLine(" \"$prop=$$prop\" +") + } else { + appendLine(" \"$prop=$$prop, \" +") + } + } + appendLine(" \")\"") appendLine("}") } } @@ -223,10 +244,17 @@ class EqualityMembersRule(config: Config) : Rule(config, RULE_DESCRIPTION) { val factory = KtPsiFactory(klass.project) val newFunction = factory.createFunction(buildString(builder)) - // 1. Add the function itself to the class body - val addedElement = klass.addDeclaration(newFunction) + // Insert before the companion object if present, otherwise append (addDeclaration creates + // the body block if the class currently has none). + val companionObject = + klass.declarations.filterIsInstance().firstOrNull { it.isCompanion() } + val addedElement: KtNamedFunction = + if (companionObject != null) { + checkNotNull(klass.body).addBefore(newFunction, companionObject) as KtNamedFunction + } else { + klass.addDeclaration(newFunction) + } - // 2. Add two newlines before the function we just added for nice formatting. checkNotNull(klass.body).addBefore(factory.createWhiteSpace("\n\n"), addedElement) } } diff --git a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/JewelBaseRule.kt b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/JewelBaseRule.kt new file mode 100644 index 000000000000..bbdd7e115d87 --- /dev/null +++ b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/JewelBaseRule.kt @@ -0,0 +1,33 @@ +package org.jetbrains.jewel.detekt.rules + +import dev.detekt.api.Config +import dev.detekt.api.Rule +import dev.detekt.api.modifiedText +import java.net.URI +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory + +/** + * Base class for Jewel Detekt rules. Handles working-file isolation for autocorrect: changes are applied to a writable + * copy of the PSI file, then written back to the original only if modifications were made. + */ +@Suppress("AbstractClassCanBeConcreteClass") +abstract class JewelBaseRule(config: Config, description: String, url: URI? = null) : Rule(config, description, url) { + private lateinit var workingFile: KtFile + + override fun visit(root: KtFile) { + val startingText = root.modifiedText ?: root.text + workingFile = + if (autoCorrect) { + KtPsiFactory(root.project).createPhysicalFile(fileName = root.name, text = startingText) + } else { + root + } + + super.visit(workingFile) + + if (autoCorrect && workingFile.text != startingText) { + root.modifiedText = workingFile.text + } + } +} diff --git a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/MissingApiStatusAnnotationRule.kt b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/MissingApiStatusAnnotationRule.kt index 0cccb5d875bb..9639ffedbf85 100644 --- a/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/MissingApiStatusAnnotationRule.kt +++ b/platform/jewel/detekt-plugin/src/main/kotlin/org/jetbrains/jewel/detekt/rules/MissingApiStatusAnnotationRule.kt @@ -4,9 +4,9 @@ package org.jetbrains.jewel.detekt.rules import dev.detekt.api.Config import dev.detekt.api.Entity import dev.detekt.api.Finding -import dev.detekt.api.Rule import dev.detekt.api.internal.AutoCorrectable import org.jetbrains.kotlin.psi.KtAnnotated +import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtClassInitializer import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration @@ -32,7 +32,7 @@ private const val RULE_DESCRIPTION = * Auto-correction will add the missing annotation, but formatting is left to the IDE's formatter/ktfmt. */ @AutoCorrectable(since = "0.38.0") -class MissingApiStatusAnnotationRule(config: Config) : Rule(config, RULE_DESCRIPTION) { +class MissingApiStatusAnnotationRule(config: Config) : JewelBaseRule(config, RULE_DESCRIPTION) { private val annotationsMap = mapOf("InternalJewelApi" to "ApiStatus.Internal", "ExperimentalJewelApi" to "ApiStatus.Experimental") @@ -140,8 +140,27 @@ class MissingApiStatusAnnotationRule(config: Config) : Rule(config, RULE_DESCRIP private fun KtDeclaration.addAnnotation(annotationName: String) { val factory = KtPsiFactory(project) val annotationEntry = factory.createAnnotationEntry("@$annotationName") - val added = addAnnotationEntry(annotationEntry) - modifierList?.addAfter(factory.createNewLine(1), added) + + // When inserting a Jewel annotation, find the paired ApiStatus one and insert after it. + val pairedApiStatus = annotationsMap[annotationName] + val anchorEntry = + if (pairedApiStatus != null) { + annotationEntries.firstOrNull { entry -> + val name = entry.shortName.toString() + name == pairedApiStatus || name == pairedApiStatus.removePrefix("ApiStatus.") + } + } else { + null + } + + if (anchorEntry != null) { + val modList = checkNotNull(modifierList) + val added = modList.addAfter(annotationEntry, anchorEntry) as KtAnnotationEntry + modList.addBefore(factory.createNewLine(1), added) + } else { + val added = addAnnotationEntry(annotationEntry) + modifierList?.addAfter(factory.createNewLine(1), added) + } } private fun KtFile.addImportIfNeeded(fqName: String) { diff --git a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/EqualityMembersRuleSpec.kt b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/EqualityMembersRuleSpec.kt index fac28c300a8f..35c95a645be3 100644 --- a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/EqualityMembersRuleSpec.kt +++ b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/EqualityMembersRuleSpec.kt @@ -90,7 +90,9 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a)" + | return "DataFuncTest(" + + | "a=$a" + + | ")" |} |} """ @@ -139,7 +141,9 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a)" + | return "DataFuncTest(" + + | "a=$a" + + | ")" |} |} """ @@ -327,7 +331,10 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a, b=$b)" + | return "DataFuncTest(" + + | "a=$a, " + + | "b=$b" + + | ")" |} |} """ @@ -388,7 +395,10 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a, b=$b)" + | return "DataFuncTest(" + + | "a=$a, " + + | "b=$b" + + | ")" |} |} """ @@ -450,7 +460,10 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a, b=$b)" + | return "DataFuncTest(" + + | "a=$a, " + + | "b=$b" + + | ")" |} |} """ @@ -520,7 +533,10 @@ class EqualityMembersRuleSpec { |} | |override fun toString(): String { - | return "DataFuncTest(a=$a, b=$b)" + | return "DataFuncTest(" + + | "a=$a, " + + | "b=$b" + + | ")" |} |} """ diff --git a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/MissingApiStatusAnnotationRuleSpec.kt b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/MissingApiStatusAnnotationRuleSpec.kt index 005ef4f694ef..36e4aac0b6ef 100644 --- a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/MissingApiStatusAnnotationRuleSpec.kt +++ b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/MissingApiStatusAnnotationRuleSpec.kt @@ -638,8 +638,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |class MyClass """ .trimMargin() @@ -668,8 +668,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |class MyClass """ .trimMargin() @@ -698,8 +698,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |fun myFunction() {} """ .trimMargin() @@ -728,8 +728,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |fun myFunction() {} """ .trimMargin() @@ -758,8 +758,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |val myVal = 0 """ .trimMargin() @@ -788,8 +788,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |val myVal = 0 """ .trimMargin() @@ -818,8 +818,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |typealias MyAlias = String """ .trimMargin() @@ -848,8 +848,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |typealias MyAlias = String """ .trimMargin() @@ -878,8 +878,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |object MyObject """ .trimMargin() @@ -907,8 +907,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |class MyClass @ExperimentalJewelApi - |@ApiStatus.Experimental constructor() + |class MyClass @ApiStatus.Experimental + |@ExperimentalJewelApi constructor() """ .trimMargin() ) @@ -939,8 +939,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi |class MyClass { - | @InternalJewelApi - |@ApiStatus.Internal + | @ApiStatus.Internal + |@InternalJewelApi | constructor() |} """ @@ -973,8 +973,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi |class MyClass { - | @ExperimentalJewelApi - |@ApiStatus.Experimental + | @ApiStatus.Experimental + |@ExperimentalJewelApi | init {} |} """ @@ -1009,8 +1009,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.jewel.foundation.InternalJewelApi |class MyClass { | val myVal: Int - | @InternalJewelApi - |@ApiStatus.Internal + | @ApiStatus.Internal + |@InternalJewelApi | get() = 1 |} """ @@ -1045,8 +1045,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.jewel.foundation.ExperimentalJewelApi |class MyClass { | var myVal: Int = 1 - | @ExperimentalJewelApi - |@ApiStatus.Experimental + | @ApiStatus.Experimental + |@ExperimentalJewelApi | set(value) {} |} """ @@ -1075,8 +1075,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |fun myFunction(@InternalJewelApi - |@ApiStatus.Internal param: Int) {} + |fun myFunction(@ApiStatus.Internal + |@InternalJewelApi param: Int) {} """ .trimMargin() ) @@ -1104,8 +1104,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi - |@InternalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |interface MyInterface """ .trimMargin() @@ -1134,8 +1134,8 @@ internal class MissingApiStatusAnnotationRuleSpec { """ |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |enum class MyEnum """ .trimMargin() @@ -1167,8 +1167,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi |class MyClass { - | @InternalJewelApi - |@ApiStatus.Internal + | @ApiStatus.Internal + |@InternalJewelApi | companion object |} """ @@ -1201,8 +1201,8 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.ExperimentalJewelApi |class MyClass( - | @ExperimentalJewelApi - |@ApiStatus.Experimental + | @ApiStatus.Experimental + |@ExperimentalJewelApi | val myVal: Int |) """ @@ -1239,10 +1239,10 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.annotations.ApiStatus |import org.jetbrains.jewel.foundation.InternalJewelApi |import org.jetbrains.jewel.foundation.ExperimentalJewelApi - |@ExperimentalJewelApi |@ApiStatus.Internal |@InternalJewelApi |@ApiStatus.Experimental + |@ExperimentalJewelApi |class MismatchedAnnotation """ .trimMargin() @@ -1278,9 +1278,9 @@ internal class MissingApiStatusAnnotationRuleSpec { |import org.jetbrains.jewel.foundation.ExperimentalJewelApi |import org.jetbrains.jewel.foundation.InternalJewelApi |@ApiStatus.Experimental - |@InternalJewelApi |@ExperimentalJewelApi |@ApiStatus.Internal + |@InternalJewelApi |class MismatchedAnnotation """ .trimMargin() diff --git a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/TestUtil.kt b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/TestUtil.kt index 1be30e6be414..434367cd7669 100644 --- a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/TestUtil.kt +++ b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/TestUtil.kt @@ -6,6 +6,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.psi.impl.source.tree.TreeCopyHandler import dev.detekt.api.Finding import dev.detekt.api.Rule +import dev.detekt.api.modifiedText import dev.detekt.test.FakeLanguageVersionSettings import dev.detekt.test.utils.compileContentForTest import org.assertj.core.api.Assertions.assertThat @@ -28,7 +29,7 @@ internal fun Rule.lintAndFix(@Language("kotlin") code: String): Pair.hasMessage(message: String) = diff --git a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/UtilsTest.kt b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/UtilsTest.kt index 3d68ec12241f..13f3bdaae1fe 100644 --- a/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/UtilsTest.kt +++ b/platform/jewel/detekt-plugin/src/test/kotlin/org/jetbrains/jewel/detekt/UtilsTest.kt @@ -1,7 +1,7 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jewel.detekt -import dev.detekt.test.TestConfig +import dev.detekt.api.Config import dev.detekt.test.lint import org.assertj.core.api.Assertions.assertThat import org.jetbrains.jewel.detekt.rules.EqualityMembersRule @@ -13,7 +13,7 @@ import org.junit.jupiter.api.Test class UtilsTest { @Test fun `isJewelSymbol should return true for exact org_jetbrains_jewel package`() { - val rule = EqualityMembersRule(TestConfig()) + val rule = EqualityMembersRule(Config.empty) val code = """ |package org.jetbrains.jewel @@ -32,7 +32,7 @@ class UtilsTest { @Test fun `isJewelSymbol should return true for org_jetbrains_jewel subpackages`() { - val rule = EqualityMembersRule(TestConfig()) + val rule = EqualityMembersRule(Config.empty) val code = """ |package org.jetbrains.jewel.foundation @@ -51,7 +51,7 @@ class UtilsTest { @Test fun `isJewelSymbol should return true for deeply nested org_jetbrains_jewel subpackages`() { - val rule = EqualityMembersRule(TestConfig()) + val rule = EqualityMembersRule(Config.empty) val code = """ |package org.jetbrains.jewel.ui.component @@ -70,7 +70,7 @@ class UtilsTest { @Test fun `isJewelSymbol should return true for no package declaration`() { - val rule = EqualityMembersRule(TestConfig()) + val rule = EqualityMembersRule(Config.empty) val code = """ |annotation class GenerateDataFunctions @@ -87,7 +87,7 @@ class UtilsTest { @Test fun `isJewelSymbol should return false for non-jewel packages`() { - val rule = EqualityMembersRule(TestConfig()) + val rule = EqualityMembersRule(Config.empty) val code = """ |package com.example.other @@ -106,7 +106,7 @@ class UtilsTest { @Test fun `MissingApiStatusAnnotationRule should work with exact org_jetbrains_jewel package`() { - val rule = MissingApiStatusAnnotationRule(TestConfig()) + val rule = MissingApiStatusAnnotationRule(Config.empty) val code = """ |package org.jetbrains.jewel @@ -125,7 +125,7 @@ class UtilsTest { @Test fun `MissingApiStatusAnnotationRule should work with Jewel subpackages`() { - val rule = MissingApiStatusAnnotationRule(TestConfig()) + val rule = MissingApiStatusAnnotationRule(Config.empty) val code = """ |package org.jetbrains.jewel.foundation @@ -144,7 +144,7 @@ class UtilsTest { @Test fun `MissingApiStatusAnnotationRule should work with root package`() { - val rule = MissingApiStatusAnnotationRule(TestConfig()) + val rule = MissingApiStatusAnnotationRule(Config.empty) val code = """ |import org.jetbrains.jewel.foundation.InternalJewelApi @@ -161,7 +161,7 @@ class UtilsTest { @Test fun `MissingApiStatusAnnotationRule should not run for non-jewel packages`() { - val rule = MissingApiStatusAnnotationRule(TestConfig()) + val rule = MissingApiStatusAnnotationRule(Config.empty) val code = """ |package com.example.other diff --git a/platform/jewel/detekt.yml b/platform/jewel/detekt.yml index de3b03158598..398d5c18ab38 100644 --- a/platform/jewel/detekt.yml +++ b/platform/jewel/detekt.yml @@ -1,7 +1,8 @@ config: validation: true + warningsAsErrors: false # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' - excludes: [] + excludes: [ 'jewel>.*>.*' ] processors: active: true @@ -23,7 +24,48 @@ console-reports: - 'FileBasedFindingsReport' comments: - active: false + active: true +# AbsentOrWrongFileLicense: +# active: false +# licenseTemplateFile: 'license.template' +# licenseTemplateIsRegex: false +# CommentOverPrivateFunction: +# active: false +# CommentOverPrivateProperty: +# active: false +# DeprecatedBlockTag: +# active: false +# EndOfSentenceFormat: +# active: false +# endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' +# KDocReferencesNonPublicProperty: +# active: false +# excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**' ] + OutdatedDocumentation: + active: true + matchTypeParameters: true + matchDeclarationsOrder: true + allowParamOnConstructorProperties: true + UndocumentedPublicClass: + active: true + excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/generated/**' ] + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + searchInProtectedClass: false + ignoreDefaultCompanionObject: false + ignoreAnnotated: [ 'Deprecated', 'InternalJewelApi' ] + UndocumentedPublicFunction: + active: true + excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/generated/**' ] + searchProtectedFunction: false + ignoreAnnotated: [ 'Deprecated', 'InternalJewelApi' ] + UndocumentedPublicProperty: + active: true + excludes: [ '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/generated/**' ] + searchProtectedProperty: false + ignoreAnnotated: [ 'Deprecated', 'InternalJewelApi' ] complexity: active: true @@ -93,7 +135,6 @@ style: active: true ExpressionBodySyntax: active: true - autoCorrect: true includeLineWrapping: false ForbiddenComment: active: true @@ -175,10 +216,15 @@ naming: active: false ignoreAnnotated: - Composable + jewel: EqualityMembersRule: + active: true + autoCorrect: true annotated: - GenerateDataFunctions + MissingApiStatusAnnotationRule: + active: true autoCorrect: true Compose: diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/DisabledAppearanceValues.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/DisabledAppearanceValues.kt index 22d6244a1a74..de43801e17fd 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/DisabledAppearanceValues.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/DisabledAppearanceValues.kt @@ -52,9 +52,11 @@ public class DisabledAppearanceValues(public val brightness: Int, public val con override fun toString(): String = "GrayFilterValues(brightness=$brightness, contrast=$contrast, alpha=$alpha)" + /** Companion object for [DisabledAppearanceValues]. */ public companion object } +/** The composition local that provides [DisabledAppearanceValues] to the composition tree. */ public val LocalDisabledAppearanceValues: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DisabledAppearanceValues provided. Have you forgotten the theme?") diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalColors.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalColors.kt index 26ddc01082e7..f890cc9585a5 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalColors.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalColors.kt @@ -69,6 +69,7 @@ public class GlobalColors( "toolwindowBackground=$toolwindowBackground" + ")" + /** Companion object for [GlobalColors]. */ public companion object } @@ -138,6 +139,7 @@ public class TextColors( "TextColors(normal=$normal, selected=$selected, disabled=$disabled, disabledSelected=$disabledSelected, " + "info=$info, error=$error, warning=$warning)" + /** Companion object for [TextColors]. */ public companion object } @@ -173,6 +175,7 @@ public class BorderColors(public val normal: Color, public val focused: Color, p override fun toString(): String = "BorderColors(normal=$normal, focused=$focused, disabled=$disabled)" + /** Companion object for [BorderColors]. */ public companion object } @@ -227,6 +230,7 @@ public class OutlineColors( "error=$error" + ")" + /** Companion object for [OutlineColors]. */ public companion object } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalMetrics.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalMetrics.kt index e09374bb9b1a..525b8681b931 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalMetrics.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/GlobalMetrics.kt @@ -5,9 +5,15 @@ import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.unit.Dp +/** Global layout metrics shared across all Jewel components, defining the default outline width and row height. */ @Immutable @GenerateDataFunctions -public class GlobalMetrics(public val outlineWidth: Dp, public val rowHeight: Dp) { +public class GlobalMetrics( + /** The width of the focus outline drawn around focusable components. */ + public val outlineWidth: Dp, + /** The default height of a single row in list-like components. */ + public val rowHeight: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -28,9 +34,11 @@ public class GlobalMetrics(public val outlineWidth: Dp, public val rowHeight: Dp override fun toString(): String = "GlobalMetrics(outlineWidth=$outlineWidth, rowHeight=$rowHeight)" + /** Companion object for [GlobalMetrics]. */ public companion object } +/** Composition local providing the current [GlobalMetrics] for the active theme. */ public val LocalGlobalMetrics: ProvidableCompositionLocal = staticCompositionLocalOf { error("No GlobalMetrics provided. Have you forgotten the theme?") } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/Stroke.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/Stroke.kt index e9d71ed99aa3..982597a43c71 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/Stroke.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/Stroke.kt @@ -7,20 +7,30 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.isUnspecified import androidx.compose.ui.unit.Dp +/** + * Describes how a component's stroke (border) is drawn. Use [Stroke.None] for no stroke, [Stroke.Solid] for a + * single-color stroke, or [Stroke.Brush] for a gradient stroke. + */ @Suppress("AbstractClassCanBeInterface") // Binary compatibility: sealed class cannot be changed to interface public sealed class Stroke { + /** No stroke; the component has no visible border. */ @Immutable public object None : Stroke() { override fun toString(): String = "None" } + /** A stroke drawn with a single solid [color]. */ @Immutable @GenerateDataFunctions public class Solid internal constructor( + /** The width of the stroke. */ public val width: Dp, + /** The solid color of the stroke. */ public val color: Color, + /** Where the stroke is drawn relative to the component bounds. */ public val alignment: Alignment, + /** The amount by which to expand the stroke beyond the component bounds. */ public val expand: Dp, ) : Stroke() { override fun equals(other: Any?): Boolean { @@ -48,13 +58,18 @@ public sealed class Stroke { override fun toString(): String = "Solid(width=$width, color=$color, alignment=$alignment, expand=$expand)" } + /** A stroke drawn with a [Brush][androidx.compose.ui.graphics.Brush], allowing gradient effects. */ @Immutable @GenerateDataFunctions public class Brush internal constructor( + /** The width of the stroke. */ public val width: Dp, + /** The brush used to paint the stroke. */ public val brush: androidx.compose.ui.graphics.Brush, + /** Where the stroke is drawn relative to the component bounds. */ public val alignment: Alignment, + /** The amount by which to expand the stroke beyond the component bounds. */ public val expand: Dp, ) : Stroke() { override fun equals(other: Any?): Boolean { @@ -82,13 +97,26 @@ public sealed class Stroke { override fun toString(): String = "Brush(width=$width, brush=$brush, alignment=$alignment, expand=$expand)" } + /** Controls where the stroke is drawn relative to the component's bounds. */ public enum class Alignment { + /** The stroke is drawn inside the component bounds. */ Inside, + /** The stroke is centered on the component bounds edge. */ Center, + /** The stroke is drawn outside the component bounds. */ Outside, } } +/** + * Creates a [Stroke] from a solid [color]. Returns [Stroke.None] if [width] is zero or [color] is + * [Color.Unspecified][androidx.compose.ui.graphics.Color.Unspecified]. + * + * @param width The width of the stroke. + * @param color The solid color of the stroke. + * @param alignment Where the stroke is drawn relative to the component bounds. + * @param expand Optional amount by which to expand the stroke beyond the component bounds. + */ public fun Stroke(width: Dp, color: Color, alignment: Stroke.Alignment, expand: Dp = Dp.Unspecified): Stroke { if (width.value == 0f) return Stroke.None if (color.isUnspecified) return Stroke.None @@ -96,6 +124,15 @@ public fun Stroke(width: Dp, color: Color, alignment: Stroke.Alignment, expand: return Stroke.Solid(width, color, alignment, expand) } +/** + * Creates a [Stroke] from a [Brush]. Returns [Stroke.None] if [width] is zero or the brush is a + * [SolidColor][androidx.compose.ui.graphics.SolidColor] with an unspecified color. + * + * @param width The width of the stroke. + * @param brush The brush used to paint the stroke. + * @param alignment Where the stroke is drawn relative to the component bounds. + * @param expand Optional amount by which to expand the stroke beyond the component bounds. + */ public fun Stroke(width: Dp, brush: Brush, alignment: Stroke.Alignment, expand: Dp = Dp.Unspecified): Stroke { if (width.value == 0f) return Stroke.None return when (brush) { diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderContext.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderContext.kt index 1f6428cfe21a..c6b39e017fe6 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderContext.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderContext.kt @@ -1,7 +1,10 @@ package org.jetbrains.jewel.foundation.actionSystem +/** A context used to supply data entries to the IntelliJ Platform action system from within a Compose component. */ public interface DataProviderContext { + /** Registers an eager data [value] for the given [key] in the action system context. */ public fun set(key: String, value: TValue?) + /** Registers a lazily-initialized value for the given [key]; [initializer] is invoked on first access. */ public fun lazy(key: String, initializer: () -> TValue?) } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderNode.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderNode.kt index dd5daffa7ff4..64b360b031ec 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderNode.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/actionSystem/DataProviderNode.kt @@ -7,9 +7,13 @@ import androidx.compose.ui.node.TraversableNode import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.InternalJewelApi +/** + * A [Modifier.Node] that tracks focus and exposes data to the IntelliJ Platform action system via a + * [DataProviderContext] lambda. + */ @InternalJewelApi @ApiStatus.Internal -public class DataProviderNode(@Suppress("DEPRECATION") public var dataProvider: DataProviderContext.() -> Unit) : +public class DataProviderNode(public var dataProvider: DataProviderContext.() -> Unit) : Modifier.Node(), FocusEventModifierNode, TraversableNode { public var hasFocus: Boolean = false @@ -19,5 +23,6 @@ public class DataProviderNode(@Suppress("DEPRECATION") public var dataProvider: override val traverseKey: TraverseKey = TraverseKey + /** The traversal key used to locate [DataProviderNode] instances in the Modifier node tree. */ public companion object TraverseKey } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/MimeType.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/MimeType.kt index 31231fe0cdb7..db932a6a8ae6 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/MimeType.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/MimeType.kt @@ -99,6 +99,11 @@ private val ALREADY_NORMALIZED_BUILTIN_TYPES = ) @JvmInline public value class MimeType(private val mimeType: String) { + /** + * Returns a human-readable display name for this MIME type (e.g., `"Kotlin"`, `"Java"`, `"XML"`). + * + * @see Known + */ @Deprecated( message = "The MimeType class is deprecated in favor of using the code block info strings (e.g., \"kt\", " + @@ -247,6 +252,11 @@ public value class MimeType(private val mimeType: String) { const val VALUE_MANIFEST = "manifest" } + /** + * Predefined [MimeType] constants for well-known programming languages and content types. + * + * @see MimeType + */ @Deprecated( message = "The MimeType class is deprecated in favor of using the code block info strings (e.g., \"kt\", " + diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/CodeHighlighter.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/CodeHighlighter.kt index 0263e85a5df7..f60bd7203ac3 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/CodeHighlighter.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/CodeHighlighter.kt @@ -8,6 +8,10 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.foundation.code.MimeType +/** + * A functional interface for applying syntax highlighting to source code. Returns a [kotlinx.coroutines.flow.Flow] of + * styled [androidx.compose.ui.text.AnnotatedString]s that can update in response to theme or color scheme changes. + */ @ApiStatus.Experimental @ExperimentalJewelApi public interface CodeHighlighter { @@ -55,6 +59,7 @@ public interface CodeHighlighter { public fun highlight(code: String, language: String = ""): Flow } +/** The composition local that provides the current [CodeHighlighter] instance. */ @ExperimentalJewelApi @get:ApiStatus.Experimental public val LocalCodeHighlighter: ProvidableCompositionLocal = staticCompositionLocalOf { diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/NoOpCodeHighlighter.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/NoOpCodeHighlighter.kt index 204c931b75ed..4081fe49276b 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/NoOpCodeHighlighter.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/code/highlighting/NoOpCodeHighlighter.kt @@ -7,6 +7,7 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.foundation.code.MimeType +/** A [CodeHighlighter] that applies no syntax highlighting, returning the code as a plain unstyled string. */ @ApiStatus.Experimental @ExperimentalJewelApi public object NoOpCodeHighlighter : CodeHighlighter { diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/Keybindings.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/Keybindings.kt index 27d08750b196..f279219219da 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/Keybindings.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/Keybindings.kt @@ -11,13 +11,18 @@ import androidx.compose.ui.input.pointer.isCtrlPressed import androidx.compose.ui.input.pointer.isMetaPressed import androidx.compose.ui.input.pointer.isShiftPressed +/** Defines the key bindings for navigating and selecting items in a selectable lazy column. */ public interface SelectableColumnKeybindings { + /** Whether the contiguous selection modifier key (e.g., Shift) is pressed in a key event. */ public val KeyEvent.isContiguousSelectionKeyPressed: Boolean + /** Whether the contiguous selection modifier key (e.g., Shift) is pressed in a pointer event. */ public val PointerKeyboardModifiers.isContiguousSelectionKeyPressed: Boolean + /** Whether the multi-selection modifier key (e.g., Ctrl or Meta) is pressed in a key event. */ public val KeyEvent.isMultiSelectionKeyPressed: Boolean + /** Whether the multi-selection modifier key (e.g., Ctrl or Meta) is pressed in a pointer event. */ public val PointerKeyboardModifiers.isMultiSelectionKeyPressed: Boolean /** Select First Node. */ @@ -63,7 +68,9 @@ public interface SelectableColumnKeybindings { public val KeyEvent.isSelectAll: Boolean } +/** Default [SelectableColumnKeybindings] for macOS, using `Meta` (⌘) as the multi-selection modifier. */ public open class DefaultMacOsSelectableColumnKeybindings : DefaultSelectableColumnKeybindings() { + /** The default singleton instance for macOS. */ public companion object : DefaultMacOsSelectableColumnKeybindings() override val KeyEvent.isMultiSelectionKeyPressed: Boolean @@ -73,7 +80,12 @@ public open class DefaultMacOsSelectableColumnKeybindings : DefaultSelectableCol get() = isMetaPressed } +/** + * Default [SelectableColumnKeybindings] for Windows/Linux, using `Ctrl` for multi-selection and standard arrow/page + * keys. + */ public open class DefaultSelectableColumnKeybindings : SelectableColumnKeybindings { + /** The default singleton instance. */ public companion object : DefaultSelectableColumnKeybindings() override val KeyEvent.isContiguousSelectionKeyPressed: Boolean diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableColumnOnKeyEvent.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableColumnOnKeyEvent.kt index 102a500a5b62..f1c45058ce76 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableColumnOnKeyEvent.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableColumnOnKeyEvent.kt @@ -6,7 +6,9 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.InternalJewelApi import org.jetbrains.jewel.foundation.lazy.SelectableLazyListKey.Selectable +/** Defines the keyboard navigation actions for a selectable lazy column. */ public interface SelectableColumnOnKeyEvent { + /** The keybindings that define keyboard navigation actions for the selectable column. */ public val keybindings: SelectableColumnKeybindings /** Select First Node. */ @@ -72,6 +74,13 @@ public interface SelectableColumnOnKeyEvent { onSelectPreviousItem(keys, state, initialIndex - 1 downTo 0) } + /** + * Selects the previous selectable item found among [possibleIndexes], updating [state] accordingly. + * + * @param keys All keys in the list. + * @param state The current selection state to update. + * @param possibleIndexes The candidate indices to search through, in the order they should be checked. + */ @InternalJewelApi @ApiStatus.Internal public fun onSelectPreviousItem( @@ -109,6 +118,13 @@ public interface SelectableColumnOnKeyEvent { onSelectNextItem(keys, state, initialIndex + 1..keys.lastIndex) } + /** + * Selects the next selectable item found among [possibleIndexes], updating [state] accordingly. + * + * @param keys All keys in the list. + * @param state The current selection state to update. + * @param possibleIndexes The candidate indices to search through, in the order they should be checked. + */ @InternalJewelApi @ApiStatus.Internal public fun onSelectNextItem( @@ -194,7 +210,9 @@ public interface SelectableColumnOnKeyEvent { } } +/** Default [SelectableColumnOnKeyEvent] implementation backed by a configurable [SelectableColumnKeybindings]. */ public open class DefaultSelectableOnKeyEvent(override val keybindings: SelectableColumnKeybindings) : SelectableColumnOnKeyEvent { + /** The default singleton instance using [DefaultSelectableColumnKeybindings]. */ public companion object : DefaultSelectableOnKeyEvent(DefaultSelectableColumnKeybindings) } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListScope.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListScope.kt index 30d22550a863..154c947372be 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListScope.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListScope.kt @@ -152,6 +152,16 @@ internal class SelectableLazyListScopeContainer : SelectableLazyListScope { } } +/** + * Convenience extension that adds all elements of [items] to this [SelectableLazyListScope]. + * + * @param T The type of items in the list. + * @param items The list of items to add. + * @param key A function producing a stable unique key for each item. Defaults to the item itself. + * @param contentType A function returning the content type of each item, used for composition reuse. + * @param selectable A function returning whether each item is selectable. Defaults to `true`. + * @param itemContent The composable content for each item. + */ public fun SelectableLazyListScope.items( items: List, key: (item: T) -> Any = { it }, @@ -168,6 +178,16 @@ public fun SelectableLazyListScope.items( ) } +/** + * Convenience extension that adds all elements of [items] with their indices to this [SelectableLazyListScope]. + * + * @param T The type of items in the list. + * @param items The list of items to add. + * @param key A function producing a stable unique key for each item by index and value. + * @param contentType A function returning the content type of each item by index and value. + * @param selectable A function returning whether each item is selectable by index and value. + * @param itemContent The composable content for each item, receiving both the index and the item. + */ public fun SelectableLazyListScope.itemsIndexed( items: List, key: (index: Int, item: T) -> Any = { _, item -> item }, @@ -184,6 +204,12 @@ public fun SelectableLazyListScope.itemsIndexed( ) } +/** + * Creates a [SelectableLazyItemScope] for this [LazyItemScope], decorating it with selection and focus state. + * + * @param isSelected Whether this item is currently selected. + * @param isActive Whether this item's parent list is currently focused. + */ @Composable public fun LazyItemScope.SelectableLazyItemScope( isSelected: Boolean = false, diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListState.kt index a0ac00c6009f..eb896553522c 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyListState.kt @@ -15,14 +15,18 @@ import org.jetbrains.jewel.foundation.util.JewelLogger private val logger = JewelLogger.getInstance(SelectableLazyListState::class.java) +/** The index range of currently visible items in this [LazyListState]. */ @Suppress("unused") public val LazyListState.visibleItemsRange: IntRange get() = firstVisibleItemIndex until firstVisibleItemIndex + layoutInfo.visibleItemsInfo.size +/** The index range of currently visible items in this [SelectableLazyListState]. */ public val SelectableLazyListState.visibleItemsRange: IntRange get() = firstVisibleItemIndex until firstVisibleItemIndex + layoutInfo.visibleItemsInfo.size +/** Exposes mutable [selectedKeys] to composables and state holders managing a selectable list. */ public interface SelectableScope { + /** The set of keys currently selected in the list. */ public var selectedKeys: Set } @@ -63,8 +67,10 @@ public constructor( /** Flag indicating whether the user is currently navigating via keyboard */ public var isKeyboardNavigating: Boolean by mutableStateOf(false) + /** The set of keys currently selected in the list. */ override var selectedKeys: Set by mutableStateOf(initialSelectedKeys) + /** The index of the last item that was made active, or null if no item has been activated yet. */ public var lastActiveItemIndex: Int? = null /** @@ -90,6 +96,7 @@ public constructor( lastActiveItemIndex = itemIndex } + /** Layout information about the currently visible items and overall list state. */ public val layoutInfo: LazyListLayoutInfo get() = lazyListState.layoutInfo @@ -113,6 +120,10 @@ public constructor( get() = lazyListState.interactionSource } +/** + * Type-safe state holder for single-selection lazy lists, enforcing [SelectionMode.Single] semantics. Delegates scroll + * and layout to an underlying [SelectableLazyListState]. + */ public class SingleSelectionLazyListState internal constructor(internal val delegate: SelectableLazyListState) : ScrollableState by delegate, SelectableScope { /** @@ -138,12 +149,15 @@ public class SingleSelectionLazyListState internal constructor(internal val dele ) ) + /** The underlying [LazyListState] used for scroll and layout. */ public val lazyListState: LazyListState get() = delegate.lazyListState + /** The selection mode, always [SelectionMode.Single] for this state. */ public val selectionMode: SelectionMode get() = SelectionMode.Single + /** The set of keys currently selected; enforces at most one key. */ override var selectedKeys: Set get() = delegate.selectedKeys set(value) { @@ -156,36 +170,56 @@ public class SingleSelectionLazyListState internal constructor(internal val dele delegate.selectedKeys = if (value.isEmpty()) emptySet() else setOf(value.first()) } + /** Whether the user is currently navigating via keyboard. */ public var isKeyboardNavigating: Boolean get() = delegate.isKeyboardNavigating set(value) { delegate.isKeyboardNavigating = value } + /** The index of the last item that was made active, or null if no item has been activated yet. */ public var lastActiveItemIndex: Int? get() = delegate.lastActiveItemIndex set(value) { delegate.lastActiveItemIndex = value } + /** + * Scrolls to the item at [itemIndex], optionally animating and applying a [scrollOffset]. + * + * @param itemIndex The index of the item to scroll to. + * @param animateScroll Whether to animate the scroll. Defaults to `false`. + * @param scrollOffset Offset from the start of the item. Defaults to `0`. + */ public suspend fun scrollToItem(itemIndex: Int, animateScroll: Boolean = false, scrollOffset: Int = 0) { delegate.scrollToItem(itemIndex, animateScroll, scrollOffset) } + /** Layout information about the currently visible items and overall list state. */ public val layoutInfo: LazyListLayoutInfo get() = delegate.layoutInfo + /** The index of the first item that is visible. */ public val firstVisibleItemIndex: Int get() = delegate.firstVisibleItemIndex + /** The scroll offset of the first visible item. */ @Suppress("unused") public val firstVisibleItemScrollOffset: Int get() = delegate.firstVisibleItemScrollOffset + /** + * [InteractionSource] that will be used to dispatch drag events when this list is being dragged. If you want to + * know whether the fling (or animated scroll) is in progress, use [isScrollInProgress]. + */ public val interactionSource: InteractionSource get() = delegate.interactionSource } +/** + * Type-safe state holder for multi-selection lazy lists, enforcing [SelectionMode.Multiple] semantics. Delegates scroll + * and layout to an underlying [SelectableLazyListState]. + */ public class MultiSelectionLazyListState internal constructor(internal val delegate: SelectableLazyListState) : ScrollableState by delegate, SelectableScope { /** @@ -211,44 +245,63 @@ public class MultiSelectionLazyListState internal constructor(internal val deleg ) ) + /** The underlying [LazyListState] used for scroll and layout. */ public val lazyListState: LazyListState get() = delegate.lazyListState + /** The selection mode, always [SelectionMode.Multiple] for this state. */ public val selectionMode: SelectionMode get() = SelectionMode.Multiple + /** The set of keys currently selected in the list. */ override var selectedKeys: Set get() = delegate.selectedKeys set(value) { delegate.selectedKeys = value } + /** Whether the user is currently navigating via keyboard. */ public var isKeyboardNavigating: Boolean get() = delegate.isKeyboardNavigating set(value) { delegate.isKeyboardNavigating = value } + /** The index of the last item that was made active, or null if no item has been activated yet. */ public var lastActiveItemIndex: Int? get() = delegate.lastActiveItemIndex set(value) { delegate.lastActiveItemIndex = value } + /** + * Scrolls to the item at [itemIndex], optionally animating and applying a [scrollOffset]. + * + * @param itemIndex The index of the item to scroll to. + * @param animateScroll Whether to animate the scroll. Defaults to `false`. + * @param scrollOffset Offset from the start of the item. Defaults to `0`. + */ public suspend fun scrollToItem(itemIndex: Int, animateScroll: Boolean = false, scrollOffset: Int = 0) { delegate.scrollToItem(itemIndex, animateScroll, scrollOffset) } + /** Layout information about the currently visible items and overall list state. */ public val layoutInfo: LazyListLayoutInfo get() = delegate.layoutInfo + /** The index of the first item that is visible. */ public val firstVisibleItemIndex: Int get() = delegate.firstVisibleItemIndex + /** The scroll offset of the first visible item. */ @Suppress("unused") public val firstVisibleItemScrollOffset: Int get() = delegate.firstVisibleItemScrollOffset + /** + * [InteractionSource] that will be used to dispatch drag events when this list is being dragged. If you want to + * know whether the fling (or animated scroll) is in progress, use [isScrollInProgress]. + */ public val interactionSource: InteractionSource get() = delegate.interactionSource } @@ -292,8 +345,15 @@ public sealed class SelectableLazyListKey { override fun hashCode(): Int = key.hashCode() } +/** Extends [LazyItemScope] with [isSelected] and [isActive] flags for items inside a selectable lazy column. */ public interface SelectableLazyItemScope : LazyItemScope { + /** Whether this item is currently selected. */ public val isSelected: Boolean + + /** + * Whether this item's parent list is currently focused. This reflects the list-wide focus state and is the same for + * every item in the list. + */ public val isActive: Boolean } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BasicLazyTree.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BasicLazyTree.kt index 9be1392c1bd5..5aab31878556 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BasicLazyTree.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BasicLazyTree.kt @@ -49,6 +49,7 @@ import org.jetbrains.jewel.foundation.state.SelectableComponentState /** * Renders a lazy tree view based on the provided tree data structure. * + * @param T the type of data held by each tree element. * @param tree The tree structure to be rendered. * @param selectionMode The selection mode for the tree nodes. * @param onElementClick Callback function triggered when a tree node is clicked. @@ -127,6 +128,7 @@ public fun BasicLazyTree( /** * Renders a lazy tree view based on the provided tree data structure. * + * @param T the type of data held by each tree element. * @param tree The tree structure to be rendered. * @param elementBackgroundFocused The background color of a tree node when focused. * @param elementBackgroundSelectedFocused The background color of a selected tree node when focused. @@ -333,9 +335,16 @@ private fun Modifier.elementBackground( shape = backgroundShape, ) +/** + * Encodes the visual state of a tree element as a bit mask, including enabled, focused, expanded, pressed, hovered, + * active, and selected flags. + */ @Immutable @JvmInline -public value class TreeElementState(public val state: ULong) : FocusableComponentState, SelectableComponentState { +public value class TreeElementState( + /** The raw bit mask encoding all state flags for this tree element. */ + public val state: ULong +) : FocusableComponentState, SelectableComponentState { @Stable override val isActive: Boolean get() = state and Active != 0UL @@ -360,6 +369,7 @@ public value class TreeElementState(public val state: ULong) : FocusableComponen override val isSelected: Boolean get() = state and Selected != 0UL + /** Whether the node is expanded. */ @Stable public val isExpanded: Boolean get() = state and Expanded != 0UL @@ -368,6 +378,17 @@ public value class TreeElementState(public val state: ULong) : FocusableComponen "${javaClass.simpleName}(enabled=$isEnabled, focused=$isFocused, expanded=$isExpanded, " + "pressed=$isPressed, hovered=$isHovered, active=$isActive, selected=$isSelected)" + /** + * Returns a copy of this [TreeElementState] with the given fields replaced by their new values. + * + * @param enabled Whether the element is enabled. + * @param focused Whether the element is focused. + * @param expanded Whether the element is expanded. + * @param pressed Whether the element is pressed. + * @param hovered Whether the element is hovered. + * @param active Whether the element's parent list is active (focused). + * @param selected Whether the element is selected. + */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -387,11 +408,23 @@ public value class TreeElementState(public val state: ULong) : FocusableComponen selected = selected, ) + /** State bit constants and the [of] factory for constructing [TreeElementState] values. */ public companion object { private const val EXPANDED_BIT_OFFSET = CommonStateBitMask.FIRST_AVAILABLE_OFFSET private val Expanded = 1UL shl EXPANDED_BIT_OFFSET + /** + * Constructs a [TreeElementState] from individual boolean flags. + * + * @param enabled Whether the element is enabled. + * @param focused Whether the element is focused. + * @param expanded Whether the node is expanded. + * @param hovered Whether the element is hovered. + * @param pressed Whether the element is pressed. + * @param active Whether the element's parent list is active (focused). + * @param selected Whether the element is selected. + */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BuildTree.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BuildTree.kt index 2eca6bf23888..8cd4698dc746 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BuildTree.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/BuildTree.kt @@ -4,15 +4,29 @@ import java.io.File import java.nio.file.Path import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** + * Builds a [Tree] using a [TreeBuilder] DSL, then constructs and returns the resulting tree. + * + * @param T The type of data held by each tree element. + * @param builder A lambda with receiver [TreeBuilder] where root entries are declared. + */ public fun buildTree(builder: TreeBuilder.() -> Unit): Tree = TreeBuilder().apply(builder).build() +/** A DSL builder for constructing a [Tree], used via [buildTree]. */ public class TreeBuilder : TreeGeneratorScope { + /** A sealed class representing either a [Leaf] or [Node] entry added to a [TreeBuilder]. */ @Suppress("AbstractClassCanBeInterface") // Binary compatibility: sealed class cannot be changed to interface public sealed class Element { + /** The stable identifier for this element, or null if none was provided. */ public abstract val id: Any? + /** A leaf entry in a [TreeBuilder], holding [data] with no children. */ @GenerateDataFunctions - public class Leaf(public val data: T, override val id: Any?) : Element() { + public class Leaf( + /** The data held by this leaf. */ + public val data: T, + override val id: Any?, + ) : Element() { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -34,10 +48,13 @@ public class TreeBuilder : TreeGeneratorScope { override fun toString(): String = "Leaf(data=$data, id=$id)" } + /** A node entry in a [TreeBuilder], holding [data] and a lambda that generates its children. */ @GenerateDataFunctions public class Node( + /** The data held by this node. */ public val data: T, override val id: Any?, + /** The lambda invoked to populate this node's children when the node is expanded. */ public val childrenGenerator: ChildrenGeneratorScope.() -> Unit, ) : Element() { override fun equals(other: Any?): Boolean { @@ -78,6 +95,7 @@ public class TreeBuilder : TreeGeneratorScope { heads.add(element) } + /** Constructs and returns the [Tree] from all root entries added to this builder. */ public fun build(): Tree { val elements = mutableListOf>() for (index in heads.indices) { @@ -167,17 +185,30 @@ private fun evaluatePrevious(element: Tree.Element): Tree.Element = } } +/** A DSL scope for adding [TreeBuilder.Element.Leaf] and [TreeBuilder.Element.Node] entries to a tree or subtree. */ public interface TreeGeneratorScope { + /** Adds a node with [data], an optional stable [id], and a [childrenGenerator] that populates its subtree. */ public fun addNode(data: T, id: Any? = null, childrenGenerator: ChildrenGeneratorScope.() -> Unit = {}) + /** Adds a leaf entry with [data] and an optional stable [id]. */ public fun addLeaf(data: T, id: Any? = null) + /** Adds a pre-built [element] (either a [TreeBuilder.Element.Leaf] or [TreeBuilder.Element.Node]) directly. */ public fun add(element: TreeBuilder.Element) } +/** A [TreeGeneratorScope] used inside a node's children generator lambda, providing access to [parent] info. */ public class ChildrenGeneratorScope(private val parentElement: Tree.Element.Node) : TreeGeneratorScope { + /** Holds identifying information about a node's parent: its data, depth in the tree, and child index. */ @GenerateDataFunctions - public class ParentInfo(public val data: T, public val depth: Int, public val index: Int) { + public class ParentInfo( + /** The data held by the parent node. */ + public val data: T, + /** The depth of the parent node in the tree (0 = root level). */ + public val depth: Int, + /** The child index of the parent node within its own parent's children. */ + public val index: Int, + ) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -201,6 +232,7 @@ public class ChildrenGeneratorScope(private val parentElement: Tree.Element.N override fun toString(): String = "ParentInfo(data=$data, depth=$depth, index=$index)" } + /** Information about the parent node of the current scope. */ public val parent: ParentInfo by lazy { ParentInfo(parentElement.data, parentElement.depth, parentElement.childIndex) } @@ -220,8 +252,22 @@ public class ChildrenGeneratorScope(private val parentElement: Tree.Element.N } } +/** + * Converts this [Path] into a [Tree] of [File] nodes, recursively expanding directories. + * + * @param isOpen A predicate whose boolean result is used as the id of the root file/directory node. Note: it does not + * control the node's initial expansion state; nodes are always created collapsed and expanded lazily via + * [Tree.Element.Node.open]. + */ public fun Path.asTree(isOpen: (File) -> Boolean = { false }): Tree = toFile().asTree(isOpen) +/** + * Converts this [File] into a [Tree] of [File] nodes, recursively expanding directories. + * + * @param isOpen A predicate whose boolean result is used as the id of the root file/directory node. Note: it does not + * control the node's initial expansion state; nodes are always created collapsed and expanded lazily via + * [Tree.Element.Node.open]. + */ public fun File.asTree(isOpen: (File) -> Boolean = { false }): Tree = buildTree { addNode(this@asTree, isOpen(this@asTree)) { generateFileNodes(isOpen) } } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewKeybindings.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewKeybindings.kt index b1a8a8f80821..d198da1322a8 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewKeybindings.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewKeybindings.kt @@ -11,7 +11,9 @@ import org.jetbrains.jewel.foundation.lazy.DefaultSelectableColumnKeybindings import org.jetbrains.jewel.foundation.lazy.SelectableColumnKeybindings import org.jetbrains.skiko.hostOs +/** Default [TreeViewKeybindings]: left/right arrows collapse/expand nodes; F2 edits. */ public open class DefaultTreeViewKeybindings : DefaultSelectableColumnKeybindings(), TreeViewKeybindings { + /** The default singleton instance. */ public companion object : DefaultTreeViewKeybindings() override val KeyEvent.isSelectParent: Boolean @@ -32,10 +34,12 @@ public open class DefaultTreeViewKeybindings : DefaultSelectableColumnKeybinding override val KeyEvent.isSelectPreviousSibling: Boolean get() = false + /** Whether the event triggers an inline edit action (F2). */ override val KeyEvent.isEdit: Boolean get() = key == Key.F2 && !isContiguousSelectionKeyPressed } +/** Extends [SelectableColumnKeybindings] with tree-specific navigation: expand/collapse and sibling traversal. */ public interface TreeViewKeybindings : SelectableColumnKeybindings { /** Select Parent Node. */ public val KeyEvent.isSelectParent: Boolean @@ -56,6 +60,7 @@ public interface TreeViewKeybindings : SelectableColumnKeybindings { public val KeyEvent.isSelectPreviousSibling: Boolean } +/** Default click modifier handler that uses Ctrl on Windows/Linux and Meta (⌘) on macOS. */ @Suppress("unused") public val DefaultWindowsTreeViewClickModifierHandler: TreeViewClickModifierHandler get() = { @@ -66,9 +71,12 @@ public val DefaultWindowsTreeViewClickModifierHandler: TreeViewClickModifierHand } } +/** Function type for determining whether a pointer event's modifier keys constitute a multi-selection click. */ public typealias TreeViewClickModifierHandler = PointerKeyboardModifiers.() -> Boolean +/** [DefaultTreeViewKeybindings] for macOS, overriding the multi-selection modifier to `Meta` (⌘). */ public open class DefaultMacOsTreeColumnKeybindings : DefaultTreeViewKeybindings() { + /** The default singleton instance for macOS. */ public companion object : DefaultMacOsTreeColumnKeybindings() override val KeyEvent.isMultiSelectionKeyPressed: Boolean diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewOnKeyEvent.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewOnKeyEvent.kt index e926266b2aee..b617e4ecb84e 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewOnKeyEvent.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/DefaultTreeViewOnKeyEvent.kt @@ -3,6 +3,7 @@ package org.jetbrains.jewel.foundation.lazy.tree import org.jetbrains.jewel.foundation.lazy.SelectableLazyListKey import org.jetbrains.jewel.foundation.lazy.SelectableLazyListState +/** Default [TreeViewOnKeyEvent] that handles tree navigation: collapsing/expanding nodes and moving to parent/child. */ public open class DefaultTreeViewOnKeyEvent( override val keybindings: TreeViewKeybindings, private val treeState: TreeState, diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/KeyActions.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/KeyActions.kt index 830bd5751fa9..a024d3c74ceb 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/KeyActions.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/KeyActions.kt @@ -22,10 +22,23 @@ import org.jetbrains.jewel.foundation.lazy.SelectableLazyListState import org.jetbrains.jewel.foundation.lazy.SelectionMode import org.jetbrains.skiko.hostOs +/** Combines keybindings and on-key-event actions for a selectable list or tree, dispatching keyboard events. */ public interface KeyActions { + /** The keybindings that define which key combinations trigger selection actions. */ public val keybindings: SelectableColumnKeybindings + + /** The handler that performs selection actions in response to key events. */ public val actions: SelectableColumnOnKeyEvent + /** + * Returns a handler lambda for [event] that, when invoked on the [KeyEvent], applies the appropriate selection + * action and returns `true` if the event was consumed, or `false` to let it propagate. + * + * @param event The incoming key event. + * @param keys All selectable keys in the current list. + * @param state The mutable selection and scroll state. + * @param selectionMode The active selection mode. + */ public fun handleOnKeyEvent( event: KeyEvent, keys: List, @@ -34,7 +47,21 @@ public interface KeyActions { ): KeyEvent.() -> Boolean } +/** + * Handles pointer (mouse) events for a selectable list or tree, including click-based selection and range extension. + */ public interface PointerEventActions { + /** + * Handles a pointer press event, updating selection in [selectableLazyListState] for [key] based on modifier keys + * and [selectionMode]. + * + * @param pointerEvent The raw pointer event containing modifier key state. + * @param keybindings The keybindings defining which modifier keys trigger multi/range select. + * @param selectableLazyListState The mutable selection state to update. + * @param selectionMode The active selection mode. + * @param allKeys All selectable keys in the list. + * @param key The key of the item that was pressed. + */ public fun handlePointerEventPress( pointerEvent: PointerEvent, keybindings: SelectableColumnKeybindings, @@ -44,6 +71,14 @@ public interface PointerEventActions { key: Any, ) + /** + * Toggles the selection state of [key] in [selectableLazyListState], respecting [selectionMode]. + * + * @param key The key to toggle. + * @param allKeys All selectable keys in the list. + * @param selectableLazyListState The mutable selection state to update. + * @param selectionMode The active selection mode. + */ public fun toggleKeySelection( key: Any, allKeys: List, @@ -51,6 +86,14 @@ public interface PointerEventActions { selectionMode: SelectionMode, ) + /** + * Extends the current selection from the active item to [key], adding all items in between. + * + * @param key The target key to extend selection to. + * @param allKeys All selectable keys in the list. + * @param state The mutable selection state to update. + * @param selectionMode The active selection mode. + */ public fun onExtendSelectionToKey( key: Any, allKeys: List, @@ -59,6 +102,7 @@ public interface PointerEventActions { ) } +/** Default [PointerEventActions] for selectable lazy columns, handling click, multi-select, and range-select. */ public open class DefaultSelectableLazyColumnEventAction : PointerEventActions { override fun handlePointerEventPress( pointerEvent: PointerEvent, @@ -147,6 +191,7 @@ public open class DefaultSelectableLazyColumnEventAction : PointerEventActions { } } +/** [DefaultSelectableLazyColumnEventAction] for tree views, adding single/double-click detection for node expansion. */ public open class DefaultTreeViewPointerEventAction(private val treeState: TreeState) : DefaultSelectableLazyColumnEventAction() { override fun handlePointerEventPress( @@ -188,6 +233,18 @@ public open class DefaultTreeViewPointerEventAction(private val treeState: TreeS // for item click that lose focus and fail to match if a operation is a double-click private var elementClickedTmpHolder: Any? = null + /** + * Detects whether [item] was single-clicked or double-clicked within [doubleClickTimeDelayMillis] and invokes the + * appropriate callback. For double-clicks on a [Tree.Element.Node], the node is also toggled. + * + * @param T The type of data in the tree. + * @param item The tree element that was clicked. + * @param scope The coroutine scope used to launch the double-click timeout. + * @param doubleClickTimeDelayMillis The window in milliseconds within which a second click counts as a + * double-click. + * @param onElementClick Callback invoked on a single click. + * @param onElementDoubleClick Callback invoked on a double click. + */ @ApiStatus.Internal @InternalJewelApi public fun notifyItemClicked( @@ -216,6 +273,11 @@ public open class DefaultTreeViewPointerEventAction(private val treeState: TreeS } } +/** + * Creates a [DefaultTreeViewKeyActions] with platform-appropriate keybindings (macOS or Windows/Linux). + * + * @param treeState The [TreeState] used by key actions to expand/collapse nodes. + */ public fun DefaultTreeViewKeyActions(treeState: TreeState): DefaultTreeViewKeyActions { val keybindings = when { @@ -225,8 +287,13 @@ public fun DefaultTreeViewKeyActions(treeState: TreeState): DefaultTreeViewKeyAc return DefaultTreeViewKeyActions(keybindings, DefaultTreeViewOnKeyEvent(keybindings, treeState)) } +/** + * [KeyActions] for tree views, adding expand/collapse key handling on top of [DefaultSelectableLazyColumnKeyActions]. + */ public class DefaultTreeViewKeyActions( + /** The tree-view-specific keybindings, including expand and collapse key mappings. */ override val keybindings: TreeViewKeybindings, + /** The handler that performs tree-view actions (expand, collapse, selection) in response to key events. */ override val actions: DefaultTreeViewOnKeyEvent, ) : DefaultSelectableLazyColumnKeyActions(keybindings, actions) { override fun handleOnKeyEvent( @@ -259,10 +326,17 @@ public class DefaultTreeViewKeyActions( } } +/** + * Default [KeyActions] for selectable lazy columns, dispatching key events via configurable [keybindings] and + * [actions]. + */ public open class DefaultSelectableLazyColumnKeyActions( + /** The keybindings that define which key combinations trigger selection actions. */ override val keybindings: SelectableColumnKeybindings, + /** The handler that performs selection actions in response to key events. */ override val actions: SelectableColumnOnKeyEvent = DefaultSelectableOnKeyEvent(keybindings), ) : KeyActions { + /** The default singleton instance using platform-appropriate keybindings (macOS or Windows/Linux). */ public companion object : DefaultSelectableLazyColumnKeyActions( when { @@ -359,12 +433,18 @@ public open class DefaultSelectableLazyColumnKeyActions( } } +/** + * A no-op [KeyActions] whose [handleOnKeyEvent] always returns a handler that consumes nothing (false), so no key event + * is ever handled. For internal use when keyboard input handling must be disabled. + */ @ApiStatus.Internal @InternalJewelApi public object NoopListKeyActions : KeyActions { + /** The keybindings used by this no-op implementation (default column keybindings). */ override val keybindings: SelectableColumnKeybindings get() = DefaultSelectableColumnKeybindings + /** The on-key-event handler used by this no-op implementation. */ override val actions: SelectableColumnOnKeyEvent = DefaultSelectableOnKeyEvent(keybindings) override fun handleOnKeyEvent( diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/Tree.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/Tree.kt index 7325c20dab66..749af051b666 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/Tree.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/Tree.kt @@ -2,13 +2,20 @@ package org.jetbrains.jewel.foundation.lazy.tree import org.jetbrains.jewel.foundation.lazy.tree.Tree.Element.Node +/** Returns a shared empty [Tree] instance with no root elements. */ @Suppress("UNCHECKED_CAST") public fun emptyTree(): Tree = Tree.EMPTY as Tree +/** + * A lazy tree data structure whose top-level entries are stored as a flat list of [roots]. Child nodes are generated on + * demand when a [Element.Node] is opened. + */ public class Tree internal constructor(public val roots: List>) { + /** Provides the [EMPTY] singleton for an empty tree with no root elements. */ public companion object { internal val EMPTY = Tree(roots = emptyList>()) } + /** Returns `true` if this tree has no root elements. */ public fun isEmpty(): Boolean = roots.isEmpty() private fun walk(breathFirst: Boolean) = sequence { @@ -27,19 +34,39 @@ public class Tree internal constructor(public val roots: List>) { } } + /** Returns a [Sequence] that traverses the tree in breadth-first order, opening nodes as it visits them. */ public fun walkBreadthFirst(): Sequence> = walk(true) + /** Returns a [Sequence] that traverses the tree in depth-first order, opening nodes as it visits them. */ public fun walkDepthFirst(): Sequence> = walk(false) + /** + * An element in the tree, holding [data] plus [depth], [childIndex], a [parent] pointer, and [next]/[previous] + * pointers into the tree's flattened linked list. + */ public sealed interface Element { + /** The data payload held by this element. */ public val data: T + + /** The nesting depth of this element, where 0 means a root element. */ public val depth: Int + + /** The parent element of this element, or `null` if it is a root element. */ public val parent: Element? + + /** The zero-based index of this element among its siblings. */ public val childIndex: Int + + /** The next element in the flattened linked list, or `null` if this is the last element. */ public var next: Element? + + /** The previous element in the flattened linked list, or `null` if this is the first element. */ public var previous: Element? + + /** A stable identifier for this element, used to distinguish it from other elements in the tree. */ public val id: Any + /** Returns the ordered path from the root of the tree down to this element (inclusive). */ public fun path(): List> = buildList { var next: Element? = this@Element @@ -50,12 +77,15 @@ public class Tree internal constructor(public val roots: List>) { } .reversed() + /** Returns an [Iterable] over elements preceding this one in the flattened linked list, in reverse order. */ public fun previousElementsIterable(): Iterable> = Iterable { elementIterator(previous) { it.previous } } + /** Returns an [Iterable] over elements following this one in the flattened linked list, in forward order. */ public fun nextElementsIterable(): Iterable> = Iterable { elementIterator(next) { it.next } } + /** A terminal element in the tree that holds [data] and has no children. */ public class Leaf( override val data: T, override val depth: Int, @@ -66,6 +96,9 @@ public class Tree internal constructor(public val roots: List>) { override val id: Any, ) : Element + /** + * A branching element in the tree that holds [data] and can lazily generate [children] when [open] is called. + */ public class Node( override val data: T, override val depth: Int, @@ -76,6 +109,7 @@ public class Tree internal constructor(public val roots: List>) { override var previous: Element?, override val id: Any, ) : Element { + /** The lazily evaluated children of this node, or `null` if [open] has not been called yet. */ public var children: List>? = null private set @@ -103,11 +137,21 @@ public class Tree internal constructor(public val roots: List>) { } } + /** + * Evaluates and links this node's children into the flat element linked list. If [reloadChildren] is + * `true`, the children generator is invoked again even if children were already evaluated. + * + * @param reloadChildren Whether to force re-evaluation of the children generator. + */ public fun open(reloadChildren: Boolean = false) { if (reloadChildren || children == null) evaluateChildren() connectChildren() } + /** + * Detaches this node's children from the flat element linked list and recursively closes all descendant + * nodes. + */ public fun close() { detachChildren() children?.asSequence()?.filterIsInstance>()?.forEach { it.closeRecursively() } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeState.kt index 3a4314113e56..337fc5356ab2 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeState.kt @@ -13,19 +13,35 @@ import org.jetbrains.jewel.foundation.InternalJewelApi import org.jetbrains.jewel.foundation.lazy.SelectableLazyListState import org.jetbrains.jewel.foundation.lazy.SelectableScope +/** + * Creates and remembers a [TreeState] backed by [selectableLazyListState]. + * + * @param lazyListState The [LazyListState] used for scroll and layout. Defaults to a new instance. + * @param selectableLazyListState The selectable list state backing the tree. Defaults to a new instance wrapping + * [lazyListState]. + */ @Composable public fun rememberTreeState( lazyListState: LazyListState = LazyListState(), selectableLazyListState: SelectableLazyListState = SelectableLazyListState(lazyListState), ): TreeState = remember { TreeState(selectableLazyListState) } +/** Holds the runtime state of a tree view: the set of open node IDs and the underlying selectable list state. */ public class TreeState(delegate: SelectableLazyListState) : SelectableScope by delegate, ScrollableState by delegate { internal val allNodes = mutableStateListOf>() + /** The underlying selectable lazy list state backing the tree. */ @InternalJewelApi @ApiStatus.Internal public val lazyListState: SelectableLazyListState = delegate + /** The set of node IDs that are currently expanded (open) in the tree. */ public var openNodes: Set by mutableStateOf>(emptySet()) + /** + * Toggles the open/closed state of the node with [nodeId]: removes it from [openNodes] if present, or adds it + * otherwise. + * + * @param nodeId The unique identifier of the node to toggle. + */ public fun toggleNode(nodeId: Any) { if (nodeId in openNodes) { openNodes -= nodeId @@ -34,6 +50,11 @@ public class TreeState(delegate: SelectableLazyListState) : SelectableScope by d } } + /** + * Adds all [nodes] to [openNodes], expanding them all at once. + * + * @param nodes The list of node IDs to open. + */ public fun openNodes(nodes: List) { openNodes += nodes } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeViewOnKeyEvent.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeViewOnKeyEvent.kt index 264a462ba007..ccb1704837ce 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeViewOnKeyEvent.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/tree/TreeViewOnKeyEvent.kt @@ -4,6 +4,7 @@ import org.jetbrains.jewel.foundation.lazy.SelectableColumnOnKeyEvent import org.jetbrains.jewel.foundation.lazy.SelectableLazyListKey import org.jetbrains.jewel.foundation.lazy.SelectableLazyListState +/** Extends [SelectableColumnOnKeyEvent] with tree-specific handlers for navigating to parent and child nodes. */ public interface TreeViewOnKeyEvent : SelectableColumnOnKeyEvent { /** Select Parent Node. */ public fun onSelectParent(keys: List, state: SelectableLazyListState) diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/Activation.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/Activation.kt index a32a873e6391..c44c0d380d21 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/Activation.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/Activation.kt @@ -254,4 +254,5 @@ private class ActivateChangedNode(var onChanged: (Boolean) -> Unit) : } } +/** The modifier local that provides the current activation state to child modifiers. */ public val ModifierLocalActivated: ProvidableModifierLocal = modifierLocalOf { false } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/PointerModifiers.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/PointerModifiers.kt index 65fbf11e6c2a..269ebddb1156 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/PointerModifiers.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/modifier/PointerModifiers.kt @@ -6,6 +6,11 @@ import androidx.compose.ui.input.pointer.PointerEventType import androidx.compose.ui.input.pointer.pointerInput import java.awt.event.MouseEvent +/** + * Invokes [onHover] with `true` when the pointer enters this composable and `false` when it exits. + * + * @param onHover Callback receiving `true` on enter and `false` on exit. + */ public fun Modifier.onHover(onHover: (Boolean) -> Unit): Modifier = pointerInput(onHover) { awaitPointerEventScope { @@ -19,6 +24,12 @@ public fun Modifier.onHover(onHover: (Boolean) -> Unit): Modifier = } } +/** + * Invokes [onMove] with the underlying [MouseEvent] (or `null` if unavailable) whenever the pointer moves over this + * composable. + * + * @param onMove Callback receiving the AWT [MouseEvent] on each pointer move event. + */ public fun Modifier.onMove(onMove: (MouseEvent?) -> Unit): Modifier = pointerInput(onMove) { awaitPointerEventScope { diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/search/SpeedSearchMatcher.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/search/SpeedSearchMatcher.kt index 92994adced20..43a95682608e 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/search/SpeedSearchMatcher.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/search/SpeedSearchMatcher.kt @@ -9,6 +9,7 @@ import org.jetbrains.jewel.foundation.search.SpeedSearchMatcher.MatchResult import org.jetbrains.jewel.foundation.search.impl.ExactSubstringSpeedSearchMatcher import org.jetbrains.jewel.foundation.search.impl.PatternSpeedSearchMatcher +/** A functional interface for matching text against a search pattern, returning matched character ranges. */ public fun interface SpeedSearchMatcher { /** * Returns a [MatchResult.Match] with a list of ranges from the where the pattern matches, or [MatchResult.NoMatch] @@ -22,6 +23,7 @@ public fun interface SpeedSearchMatcher { */ public fun matches(text: CharSequence?): MatchResult = matches(text?.toString()) + /** Factory methods for creating [SpeedSearchMatcher] instances: [exactSubstringMatcher] and [patternMatcher]. */ public companion object { /** * Returns a [SpeedSearchMatcher] that searches for the given [pattern] in the text. @@ -85,9 +87,12 @@ public fun interface SpeedSearchMatcher { ) } + /** The result of a [SpeedSearchMatcher.matches] call: either [NoMatch] or a [Match] with matched ranges. */ public sealed interface MatchResult { + /** Indicates that the text did not match the search pattern. */ public object NoMatch : MatchResult + /** Indicates a successful match, containing the list of matched [ranges] within the text. */ @GenerateDataFunctions public class Match(public val ranges: List) : MatchResult { override fun equals(other: Any?): Boolean { @@ -104,6 +109,7 @@ public fun interface SpeedSearchMatcher { override fun toString(): String = "Match(ranges=$ranges)" } + /** Companion object for [MatchResult]. */ public companion object { internal fun from(ranges: List?): MatchResult = if (ranges.isNullOrEmpty()) NoMatch else Match(ranges) @@ -196,7 +202,7 @@ public object EmptySpeedSearchMatcher : SpeedSearchMatcher { * matcher.doesMatch("baz") // false * ``` * - * @param text The text to check for matches. If null, returns false. + * @param matcher The [SpeedSearchMatcher] to use for matching. * @return `true` if the text matches the pattern, `false` otherwise. * @see SpeedSearchMatcher.matches for the underlying match result with ranges */ @@ -255,6 +261,7 @@ public fun Iterable.filter( * // Returns: ["React"] * ``` * + * @param T the type of items in the collection, constrained to [CharSequence]. * @param matcher The [SpeedSearchMatcher] to use for filtering. * @return A list containing only the strings that match the search pattern. * @see filter for filtering collections of other types diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/CommonStateBitMask.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/CommonStateBitMask.kt index 2d1227e0559b..c15a6552c821 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/CommonStateBitMask.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/CommonStateBitMask.kt @@ -1,13 +1,28 @@ package org.jetbrains.jewel.foundation.state +/** Bit mask constants for the common interactive component states shared across all Jewel components. */ public object CommonStateBitMask { + /** Bit flag for the enabled state. */ public val Enabled: ULong = 1UL shl 0 + + /** Bit flag for the focused state. */ public val Focused: ULong = 1UL shl 1 + + /** Bit flag for the hovered state. */ public val Hovered: ULong = 1UL shl 2 + + /** Bit flag for the pressed state. */ public val Pressed: ULong = 1UL shl 3 + + /** Bit flag for the active state. */ public val Active: ULong = 1UL shl 4 + + /** Bit flag for the selected state. */ public val Selected: ULong = 1UL shl 5 + + /** Bit flag for the indeterminate state. */ public val Indeterminate: ULong = 1UL shl 6 + /** The first bit offset available for component-specific state flags. */ public const val FIRST_AVAILABLE_OFFSET: Int = 7 } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/FocusableComponentState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/FocusableComponentState.kt index c6de616c2f2e..2e07acae073d 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/FocusableComponentState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/FocusableComponentState.kt @@ -3,7 +3,12 @@ package org.jetbrains.jewel.foundation.state import androidx.compose.runtime.Composable import org.jetbrains.jewel.foundation.theme.JewelTheme +/** + * An [InteractiveComponentState] that also tracks focus. Provides a composable `chooseValue` helper that resolves a + * state-dependent value based on the current enabled, pressed, hovered, focused, and active flags. + */ public interface FocusableComponentState : InteractiveComponentState { + /** Whether the component currently has keyboard focus. */ public val isFocused: Boolean /** diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/InteractiveComponentState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/InteractiveComponentState.kt index 58e9dfee6bd4..78ef8f9f0846 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/InteractiveComponentState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/InteractiveComponentState.kt @@ -1,11 +1,19 @@ package org.jetbrains.jewel.foundation.state +/** + * Base interface for interactive component states, tracking whether a component is active, enabled, hovered, or + * pressed. + */ public interface InteractiveComponentState { + /** Whether the component is active (e.g., its parent window has focus). */ public val isActive: Boolean + /** Whether the component is enabled and can receive user interaction. */ public val isEnabled: Boolean + /** Whether the pointer is currently hovering over the component. */ public val isHovered: Boolean + /** Whether the component is currently being pressed. */ public val isPressed: Boolean } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/SelectableComponentState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/SelectableComponentState.kt index 860e00455bf7..36aed68c83c9 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/SelectableComponentState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/SelectableComponentState.kt @@ -1,5 +1,7 @@ package org.jetbrains.jewel.foundation.state +/** An [InteractiveComponentState] that also tracks whether the component is selected. */ public interface SelectableComponentState : InteractiveComponentState { + /** Whether the component is currently selected. */ public val isSelected: Boolean } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt index 16206eb7a43f..1c242104f9f2 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/state/ToggleableComponentState.kt @@ -4,16 +4,22 @@ import androidx.compose.ui.state.ToggleableState import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Indeterminate import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Selected +/** A component state that tracks a [ToggleableState] value (on, off, or indeterminate). */ public interface ToggleableComponentState { + /** The current toggleable state of the component (on, off, or indeterminate). */ public val toggleableState: ToggleableState + /** Whether the component is in the [ToggleableState.On] state. */ public val isSelected: Boolean get() = toggleableState == ToggleableState.On + /** Whether the component is in either the [ToggleableState.On] or [ToggleableState.Indeterminate] state. */ public val isSelectedOrIndeterminate: Boolean get() = toggleableState != ToggleableState.Off + /** Provides the [readToggleableState] helper for decoding a [ToggleableState] from a [ULong] bit mask. */ public companion object { + /** Decodes the [ToggleableState] from this [ULong] bit mask using the [Selected] and [Indeterminate] bits. */ public fun ULong.readToggleableState(): ToggleableState { val selected = this and Selected != 0UL val indeterminate = this and Indeterminate != 0UL diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt index 30dfa8953d88..f3966bb2ad2e 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/JewelTheme.kt @@ -15,8 +15,11 @@ import org.jetbrains.jewel.foundation.LocalDisabledAppearanceValues import org.jetbrains.jewel.foundation.LocalGlobalColors import org.jetbrains.jewel.foundation.LocalGlobalMetrics +/** Entry point for accessing the current Jewel theme values from any composable via composition locals. */ public interface JewelTheme { + /** Provides composable-accessible properties for the current theme's colors, metrics, text styles, and flags. */ public companion object { + /** The name of the current theme. */ public val name: String @Composable @ReadOnlyComposable get() = LocalThemeName.current @@ -24,37 +27,58 @@ public interface JewelTheme { public val instanceUuid: UUID @Composable @ReadOnlyComposable get() = LocalThemeInstanceUuid.current + /** The global colors for the current theme. */ public val globalColors: GlobalColors @Composable @ReadOnlyComposable get() = LocalGlobalColors.current + /** The global metrics for the current theme. */ public val globalMetrics: GlobalMetrics @Composable @ReadOnlyComposable get() = LocalGlobalMetrics.current + /** The default text style for the current theme. */ public val defaultTextStyle: TextStyle @Composable @ReadOnlyComposable get() = LocalTextStyle.current + /** The text style used in editor components. */ public val editorTextStyle: TextStyle @Composable @ReadOnlyComposable get() = LocalEditorTextStyle.current + /** The text style used in console/terminal components. */ public val consoleTextStyle: TextStyle @Composable @ReadOnlyComposable get() = LocalConsoleTextStyle.current + /** The default content (foreground) color for the current theme. */ public val contentColor: Color @Composable @ReadOnlyComposable get() = LocalContentColor.current + /** Whether the current theme is a dark theme. */ public val isDark: Boolean @Composable @ReadOnlyComposable get() = LocalIsDarkTheme.current + /** Whether Swing compatibility mode is enabled, which disables hover and press state changes. */ public val isSwingCompatMode: Boolean @Composable @ReadOnlyComposable get() = LocalSwingCompatMode.current } } +/** + * Applies the given [theme] and [swingCompatMode] flag to the [content] composition tree. + * + * @param theme The [ThemeDefinition] describing colors, metrics, and text styles. + * @param swingCompatMode Whether to enable Swing compatibility mode (disables hover/press state changes). + * @param content The composable content to render under this theme. + */ @Composable public fun JewelTheme(theme: ThemeDefinition, swingCompatMode: Boolean, content: @Composable () -> Unit) { CompositionLocalProvider(LocalSwingCompatMode provides swingCompatMode) { JewelTheme(theme, content) } } +/** + * Applies the given [theme] to the [content] composition tree, providing all theme composition locals. + * + * @param theme The [ThemeDefinition] describing colors, metrics, and text styles. + * @param content The composable content to render under this theme. + */ @Composable public fun JewelTheme(theme: ThemeDefinition, content: @Composable () -> Unit) { CompositionLocalProvider( @@ -72,6 +96,7 @@ public fun JewelTheme(theme: ThemeDefinition, content: @Composable () -> Unit) { ) } +/** Composition local providing the name of the current theme. */ public val LocalThemeName: ProvidableCompositionLocal = staticCompositionLocalOf { error("No ThemeName provided") } @@ -89,6 +114,7 @@ public val LocalThemeInstanceUuid: ProvidableCompositionLocal = staticComp error("No ThemeInstanceUuid provided. Have you forgotten the theme?") } +/** Composition local providing the default content (foreground) color for the current theme. */ public val LocalContentColor: ProvidableCompositionLocal = staticCompositionLocalOf { error("No ContentColor provided. Have you forgotten the theme?") } @@ -102,20 +128,25 @@ internal val LocalSwingCompatMode: ProvidableCompositionLocal = staticC false } +/** Composition local providing the color palette for the current theme. */ public val LocalColorPalette: ProvidableCompositionLocal = staticCompositionLocalOf { ThemeColorPalette.Empty } +/** Composition local providing icon data (mappings and overrides) for the current theme. */ public val LocalIconData: ProvidableCompositionLocal = staticCompositionLocalOf { ThemeIconData.Empty } +/** Composition local providing the default text style for the current theme. */ public val LocalTextStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No TextStyle provided. Have you forgotten the theme?") } +/** Composition local providing the text style used in editor components. */ public val LocalEditorTextStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No EditorTextStyle provided. Have you forgotten the theme?") } +/** Composition local providing the text style used in console/terminal components. */ public val LocalConsoleTextStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No ConsoleTextStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeColorPalette.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeColorPalette.kt index 5ddff8165bc2..bbbc813fce50 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeColorPalette.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeColorPalette.kt @@ -418,6 +418,7 @@ public class ThemeColorPalette( ")" } + /** Provides the [Empty] instance representing a palette with no color entries. */ public companion object { public val Empty: ThemeColorPalette = ThemeColorPalette( diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt index d6369dc5a7a6..08867566f8e3 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDefinition.kt @@ -8,19 +8,34 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.foundation.GlobalColors import org.jetbrains.jewel.foundation.GlobalMetrics +/** + * Defines all visual properties of a Jewel theme: its name, dark/light mode, global colors and metrics, text styles, + * content color, color palette, icon data, and disabled appearance values. + */ @Immutable @GenerateDataFunctions public class ThemeDefinition( + /** The unique name identifying this theme. */ public val name: String, + /** Whether this theme is a dark theme. */ public val isDark: Boolean, + /** The global colors shared across all components in this theme. */ public val globalColors: GlobalColors, + /** The global metrics (sizes, spacings) shared across all components in this theme. */ public val globalMetrics: GlobalMetrics, + /** The default text style used for body content. */ public val defaultTextStyle: TextStyle, + /** The text style used for editor content. */ public val editorTextStyle: TextStyle, + /** The text style used for console/terminal content. */ public val consoleTextStyle: TextStyle, + /** The default foreground color for content rendered with this theme. */ public val contentColor: Color, + /** The color palette providing semantic and raw color mappings for this theme. */ public val colorPalette: ThemeColorPalette, + /** The icon data providing icon overrides and mappings for this theme. */ public val iconData: ThemeIconData, + /** The values controlling the appearance of disabled components. */ public val disabledAppearanceValues: DisabledAppearanceValues, ) { @Deprecated("Use the primary constructor and provide DisabledAppearanceValues.") diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDescriptor.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDescriptor.kt index 42198d5c3c82..c52520d18a91 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDescriptor.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeDescriptor.kt @@ -2,10 +2,18 @@ package org.jetbrains.jewel.foundation.theme import androidx.compose.runtime.Immutable +/** Describes the identity and palette of a Jewel theme: its name, dark/light flag, color palette, and icon data. */ @Immutable public interface ThemeDescriptor { + /** The unique name identifying this theme. */ public val name: String + + /** Whether this theme uses a dark color scheme. */ public val isDark: Boolean + + /** The color palette associated with this theme. */ public val colors: ThemeColorPalette + + /** The icon data associated with this theme. */ public val iconData: ThemeIconData } diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeIconData.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeIconData.kt index f6532bb90730..0418b2f27432 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeIconData.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/theme/ThemeIconData.kt @@ -3,12 +3,21 @@ package org.jetbrains.jewel.foundation.theme import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color +/** Holds theme-specific icon path overrides and color palette mappings used to tint and remap SVG icons. */ @Immutable public class ThemeIconData( + /** Maps original icon paths to replacement icon paths for this theme. */ public val iconOverrides: Map, + /** Maps color hex strings to replacement color hex strings (or null to leave unchanged) for icon tinting. */ public val colorPalette: Map, + /** Maps color hex strings to replacement ARGB int values used for selected icon tinting. */ public val selectionColorPalette: Map, ) { + /** + * Converts [selectionColorPalette] into a typed [Map] from source [Color] (parsed from each hex-string key) to + * replacement [Color] (built from each ARGB int value). Entries whose key string cannot be parsed as a color are + * silently dropped. + */ public fun selectionColorMapping(): Map = selectionColorPalette .mapNotNull { (key, value) -> @@ -18,6 +27,7 @@ public class ThemeIconData( } .toMap() + /** Provides the [Empty] instance representing a theme with no icon customizations. */ public companion object { public val Empty: ThemeIconData = ThemeIconData(iconOverrides = emptyMap(), colorPalette = emptyMap(), selectionColorPalette = emptyMap()) diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/util/JewelLogger.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/util/JewelLogger.kt index 793c47861541..321c416936fd 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/util/JewelLogger.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/util/JewelLogger.kt @@ -6,6 +6,7 @@ import java.util.logging.Level import java.util.logging.Logger import org.jetbrains.annotations.ApiStatus +/** Creates a [JewelLogger] instance scoped to the calling class [T]. */ public inline fun T.myLogger(): JewelLogger = JewelLogger.getInstance(T::class.java) /** A wrapper which uses either IDE logging subsystem (if available) or java.util.logging. */ @@ -16,34 +17,49 @@ public abstract class JewelLogger { fun getInstance(category: String?): JewelLogger } + /** Logs [message] at TRACE level with no associated throwable. */ public fun trace(message: String?): Unit = trace(message, null) + /** Logs [t] at TRACE level, using the throwable's message as the log message. */ public fun trace(t: Throwable): Unit = trace(t.message, t) + /** Logs [message] at DEBUG level with no associated throwable. */ public fun debug(message: String?): Unit = debug(message, null) + /** Logs [t] at DEBUG level, using the throwable's message as the log message. */ public fun debug(t: Throwable): Unit = debug(t.message, t) + /** Logs [message] at INFO level with no associated throwable. */ public fun info(message: String?): Unit = info(message, null) + /** Logs [t] at INFO level, using the throwable's message as the log message. */ public fun info(t: Throwable): Unit = info(t.message, t) + /** Logs [message] at WARN level with no associated throwable. */ public fun warn(message: String?): Unit = warn(message, null) + /** Logs [t] at WARN level, using the throwable's message as the log message. */ public fun warn(t: Throwable): Unit = warn(t.message, t) + /** Logs [message] at ERROR level with no associated throwable. */ public fun error(message: String?): Unit = error(message, null) + /** Logs [t] at ERROR level, using the throwable's message as the log message. */ public fun error(t: Throwable): Unit = error(t.message, t) + /** Logs [message] with optional [t] at TRACE level. */ public abstract fun trace(message: String?, t: Throwable?) + /** Logs [message] with optional [t] at DEBUG level. */ public abstract fun debug(message: String?, t: Throwable?) + /** Logs [message] with optional [t] at INFO level. */ public abstract fun info(message: String?, t: Throwable?) + /** Logs [message] with optional [t] at WARN level. */ public abstract fun warn(message: String?, t: Throwable?) + /** Logs [message] with optional [t] at ERROR level. */ public abstract fun error(message: String?, t: Throwable?) private class JavaFactory : Factory { @@ -252,6 +268,7 @@ public abstract class JewelLogger { @Throws(Exception::class) override fun getLogger(category: String?): Any = myGetLogger.invoke(null, category) } + /** Provides [getInstance] factory methods for obtaining [JewelLogger] instances by category name or class. */ public companion object { @get:Synchronized private val factory: Factory = createFactory() @@ -267,8 +284,10 @@ public abstract class JewelLogger { } } + /** Returns a [JewelLogger] instance for the given [category] name. */ public fun getInstance(category: String): JewelLogger = factory.getInstance("#$category") + /** Returns a [JewelLogger] instance for the given [clazz], using the class name as the category. */ public fun getInstance(clazz: Class<*>): JewelLogger = getInstance("#${clazz.name}") } } diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeIconData.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeIconData.kt index 69d1b2c759d1..0f30e8b14ac9 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeIconData.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgeIconData.kt @@ -3,6 +3,7 @@ package org.jetbrains.jewel.bridge import com.intellij.ide.ui.UITheme import org.jetbrains.jewel.foundation.theme.ThemeIconData +/** Reads [ThemeIconData] from the currently active IntelliJ UI theme, including icon overrides and color palettes. */ @Suppress("UnstableApiUsage") public fun ThemeIconData.Companion.readFromLaF(): ThemeIconData { val uiTheme = currentUiThemeOrNull() diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgePainterHintsProvider.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgePainterHintsProvider.kt index dd4685538440..321a7a23c948 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgePainterHintsProvider.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/BridgePainterHintsProvider.kt @@ -102,9 +102,16 @@ private constructor( add(Dark(JewelTheme.isDark)) } + /** Provides the [invoke] factory that creates a [PalettePainterHintsProvider] from the current IDE UI theme. */ public companion object { private val logger = thisLogger() + /** + * Creates a [PalettePainterHintsProvider] from the current IDE UI theme. Falls back to a basic + * [BridgePainterHintsProvider] if no theme is active. + * + * @param isDark Whether the current theme is dark. + */ @Suppress("UnstableApiUsage") // We need to call @Internal APIs public operator fun invoke(isDark: Boolean): PalettePainterHintsProvider { val uiTheme = currentUiThemeOrNull() ?: return BridgePainterHintsProvider(isDark) diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ComposeSemanticsTreeUtils.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ComposeSemanticsTreeUtils.kt index 48a76a3387a3..1a79e3876208 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ComposeSemanticsTreeUtils.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ComposeSemanticsTreeUtils.kt @@ -12,6 +12,10 @@ import androidx.compose.ui.semantics.getOrNull import org.jetbrains.annotations.ApiStatus.Internal import org.jetbrains.jewel.foundation.InternalJewelApi +/** + * Internal utilities for inspecting the Compose semantics tree, such as finding the focused node or identifying text + * fields. + */ @Internal @InternalJewelApi public object ComposeSemanticsTreeUtils { @@ -39,6 +43,10 @@ public object ComposeSemanticsTreeUtils { null } + /** + * Returns `true` if this [SemanticsNode] represents an editable text field (has editable text or a set-text + * action). + */ public fun SemanticsNode.isEditableTextField(): Boolean { // Check if the node has editable text or supports setting text val editable = config.contains(SemanticsProperties.EditableText) @@ -46,6 +54,10 @@ public object ComposeSemanticsTreeUtils { return editable || hasSetTextAction } + /** + * Returns the [CustomAccessibilityAction] with the given [label] from this node's semantics, or `null` if not + * found. + */ public fun SemanticsNode.getCustomAction(label: String): CustomAccessibilityAction? = config.getOrNull(SemanticsActions.CustomActions)?.firstOrNull { it.label == label } } diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelBridgeException.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelBridgeException.kt index 93893436db59..9da2b71c0b89 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelBridgeException.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/JewelBridgeException.kt @@ -1,9 +1,12 @@ package org.jetbrains.jewel.bridge +/** A sealed exception hierarchy for errors that occur when a required key is not found in the Swing LaF. */ public sealed class JewelBridgeException(override val message: String?) : RuntimeException(message) { + /** Thrown when a single expected Swing LaF key is not found. */ public class KeyNotFoundException(key: String, type: String) : JewelBridgeException("Key '$key' not found in Swing LaF, was expecting a value of type $type") + /** Thrown when none of a set of expected Swing LaF keys are found. */ public class KeysNotFoundException(keys: List, type: String) : JewelBridgeException( "Keys ${keys.joinToString(", ") { "'$it'" }} not found in Swing LaF, " + diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt index 8d8903dd3e24..0d49914455ca 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/ToolWindowExtensions.kt @@ -8,11 +8,11 @@ import org.jetbrains.jewel.foundation.enableNewSwingCompositing /** * Adds a new tab to the tool window with Compose content. * - * @param focusOnClickInside If `true`, the underlying [ComposePanel] will request focus when a mouse click occurs - * inside it, even if it does not hit a "focusable" element. * @param tabDisplayName The title of the tab. * @param isLockable Whether the tab can be locked. * @param isCloseable Whether the tab can be closed. + * @param focusOnClickInside If `true`, the underlying [ComposePanel] will request focus when a mouse click occurs + * inside it, even if it does not hit a "focusable" element. * @param content The Composable content of the tab. */ public fun ToolWindow.addComposeTab( diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/actionSystem/RootDataProviderNode.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/actionSystem/RootDataProviderNode.kt index 017c6ea07bbb..fbda5e282dfa 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/actionSystem/RootDataProviderNode.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/actionSystem/RootDataProviderNode.kt @@ -11,6 +11,10 @@ import org.jetbrains.annotations.VisibleForTesting import org.jetbrains.jewel.foundation.InternalJewelApi import org.jetbrains.jewel.foundation.actionSystem.DataProviderNode +/** + * A [Modifier.Node] that collects data from all [DataProviderNode] descendants with focus and exposes it to the + * IntelliJ Platform via [UiDataProvider.uiDataSnapshot]. + */ @VisibleForTesting @ApiStatus.Internal @InternalJewelApi diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/code/highlighting/CodeHighlighterFactory.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/code/highlighting/CodeHighlighterFactory.kt index 37c1964ad461..42da895eb2d8 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/code/highlighting/CodeHighlighterFactory.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/code/highlighting/CodeHighlighterFactory.kt @@ -10,6 +10,10 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch import org.jetbrains.jewel.foundation.code.highlighting.CodeHighlighter +/** + * A project-level IDE service that creates [CodeHighlighter] instances backed by the IDE's editor color scheme, and + * triggers re-highlighting when the color scheme changes. + */ @Service(Service.Level.PROJECT) public class CodeHighlighterFactory(private val project: Project, private val coroutineScope: CoroutineScope) { private val reHighlightingRequests = MutableSharedFlow(replay = 0) @@ -23,9 +27,12 @@ public class CodeHighlighterFactory(private val project: Project, private val co ) } + /** Creates a new [CodeHighlighter] backed by the IDE's current editor color scheme for this project. */ public fun createHighlighter(): CodeHighlighter = IntelliJCodeHighlighter(project, reHighlightingRequests) + /** Provides the [getInstance] factory for obtaining the [CodeHighlighterFactory] service for a given project. */ public companion object { + /** Returns the [CodeHighlighterFactory] service instance for the given [project]. */ public fun getInstance(project: Project): CodeHighlighterFactory = project.service() } } diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/icon/IntelliJIconKey.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/icon/IntelliJIconKey.kt index fb90cd400da6..c2a82b73492e 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/icon/IntelliJIconKey.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/icon/IntelliJIconKey.kt @@ -4,6 +4,13 @@ import com.intellij.ui.icons.IconPathProvider import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icon.IntelliJIconKey +/** + * Creates an [IntelliJIconKey] from a Swing [icon] that implements [IconPathProvider], extracting the old-UI and New-UI + * resource paths. + * + * @param icon The Swing icon to convert. Must be an [IconPathProvider] (e.g., icons from `AllIcons`). + * @param iconClass The class whose [ClassLoader] will be used to locate the icon resource. + */ public fun IntelliJIconKey.Companion.fromPlatformIcon( icon: javax.swing.Icon, iconClass: Class<*> = icon::class.java, diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeGlobalMetrics.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeGlobalMetrics.kt index 6300663bd63a..a2dad4e2a520 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeGlobalMetrics.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeGlobalMetrics.kt @@ -7,6 +7,7 @@ import com.intellij.util.ui.JBUI import org.jetbrains.jewel.bridge.safeValue import org.jetbrains.jewel.foundation.GlobalMetrics +/** Reads [GlobalMetrics] from the current IntelliJ LaF, deriving outline width and row height from JBUI. */ public fun GlobalMetrics.Companion.readFromLaF(): GlobalMetrics = GlobalMetrics( outlineWidth = DarculaUIUtil.BW.unscaled.dp.safeValue(), diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeThemeColorPalette.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeThemeColorPalette.kt index a378270d423c..386061d8386c 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeThemeColorPalette.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/BridgeThemeColorPalette.kt @@ -10,9 +10,13 @@ import org.jetbrains.jewel.foundation.theme.ThemeColorPalette private val logger: Logger = Logger.getInstance("BridgeThemeColorPalette") +/** The border color used for Windows-style popups, or null if not defined in the current LaF. */ public val ThemeColorPalette.windowsPopupBorder: Color? get() = lookup("windowsPopupBorder") +/** + * Reads [ThemeColorPalette] from the current IntelliJ LaF by extracting named color-palette entries from UIDefaults. + */ public fun ThemeColorPalette.Companion.readFromLaF(): ThemeColorPalette { val isIslands = IslandsState.isEnabled() val gray = readPaletteColors("Gray", isIslands) diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeScrollbar.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeScrollbar.kt index f883882cf7f8..9419f5e99d5b 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeScrollbar.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeScrollbar.kt @@ -278,6 +278,7 @@ private fun readScrollbarVisibility() = ScrollbarVisibility.AlwaysVisible.windowsAndLinux() } +/** Creates the default [ScrollbarVisibility.WhenScrolling] for the current platform: macOS or Windows/Linux. */ public fun ScrollbarVisibility.WhenScrolling.Companion.default(): ScrollbarVisibility.WhenScrolling = if (hostOs.isMacOS) { ScrollbarVisibility.WhenScrolling.macOs() @@ -285,6 +286,7 @@ public fun ScrollbarVisibility.WhenScrolling.Companion.default(): ScrollbarVisib ScrollbarVisibility.WhenScrolling.windowsAndLinux() } +/** Creates a [ScrollbarVisibility.WhenScrolling] configured with macOS-specific dimensions and animations. */ public fun ScrollbarVisibility.WhenScrolling.Companion.macOs( trackThickness: Dp = 11.dp, trackThicknessExpanded: Dp = 14.dp, @@ -306,6 +308,7 @@ public fun ScrollbarVisibility.WhenScrolling.Companion.macOs( lingerDuration = lingerDuration, ) +/** Creates a [ScrollbarVisibility.WhenScrolling] configured with Windows/Linux-specific dimensions and animations. */ public fun ScrollbarVisibility.WhenScrolling.Companion.windowsAndLinux( trackThickness: Dp = 11.dp, trackThicknessExpanded: Dp = 14.dp, @@ -327,6 +330,7 @@ public fun ScrollbarVisibility.WhenScrolling.Companion.windowsAndLinux( lingerDuration = lingerDuration, ) +/** Creates the default [ScrollbarVisibility.AlwaysVisible] for the current platform: macOS or Windows/Linux. */ public fun ScrollbarVisibility.AlwaysVisible.Companion.default(): ScrollbarVisibility.AlwaysVisible = if (hostOs.isMacOS) { ScrollbarVisibility.AlwaysVisible.macOs() @@ -334,6 +338,7 @@ public fun ScrollbarVisibility.AlwaysVisible.Companion.default(): ScrollbarVisib ScrollbarVisibility.AlwaysVisible.windowsAndLinux() } +/** Creates a [ScrollbarVisibility.AlwaysVisible] configured with macOS-specific dimensions and colors. */ public fun ScrollbarVisibility.AlwaysVisible.Companion.macOs( trackThickness: Dp = 14.dp, trackPadding: PaddingValues = PaddingValues(2.dp), @@ -351,6 +356,7 @@ public fun ScrollbarVisibility.AlwaysVisible.Companion.macOs( scrollbarBackgroundColorDark = scrollbarBackgroundColorDark, ) +/** Creates a [ScrollbarVisibility.AlwaysVisible] configured with Windows/Linux-specific dimensions. */ public fun ScrollbarVisibility.AlwaysVisible.Companion.windowsAndLinux( trackThickness: Dp = 10.dp, trackPadding: PaddingValues = PaddingValues(0.5.dp), diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSlider.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSlider.kt index 0c55c32f369c..cf2c2b7e190e 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSlider.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSlider.kt @@ -19,6 +19,7 @@ internal fun readSliderStyle(dark: Boolean): SliderStyle { return SliderStyle(colors, SliderMetrics.defaults(), CircleShape) } +/** Creates Int UI light [SliderColors] by reading values from the IntelliJ color palette, with hardcoded fallbacks. */ public fun SliderColors.Companion.light( track: Color = retrieveColorOrUnspecified("ColorPalette.Gray10").takeOrElse { Color(0xFFD3D5DB) }, trackFilled: Color = retrieveColorOrUnspecified("ColorPalette.Blue6").takeOrElse { Color(0xFF588CF3) }, @@ -54,6 +55,7 @@ public fun SliderColors.Companion.light( thumbBorderHovered, ) +/** Creates Int UI dark [SliderColors] by reading values from the IntelliJ color palette, with hardcoded fallbacks. */ public fun SliderColors.Companion.dark( track: Color = retrieveColorOrUnspecified("ColorPalette.Gray4").takeOrElse { Color(0xFF43454A) }, trackFilled: Color = retrieveColorOrUnspecified("ColorPalette.Blue7").takeOrElse { Color(0xFF467FF2) }, @@ -89,6 +91,7 @@ public fun SliderColors.Companion.dark( thumbBorderHovered, ) +/** Creates default [SliderMetrics] with standard Int UI sizing values. */ public fun SliderMetrics.Companion.defaults( trackHeight: Dp = 4.dp, thumbSize: DpSize = DpSize(14.dp, 14.dp), diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSplitButton.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSplitButton.kt index 2c9cba712b24..8afb90e176d2 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSplitButton.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeSplitButton.kt @@ -14,6 +14,7 @@ import org.jetbrains.jewel.ui.component.styling.SplitButtonStyle private val dividerPadding: Int get() = if (isNewUiTheme()) 4 else 1 +/** Reads the [SplitButtonStyle] for the outlined variant from the current IntelliJ JBUI theme values. */ public fun readOutlinedSplitButtonStyle(): SplitButtonStyle = SplitButtonStyle( button = readOutlinedButtonStyle(), @@ -26,6 +27,7 @@ public fun readOutlinedSplitButtonStyle(): SplitButtonStyle = metrics = SplitButtonMetrics(dividerMetrics = readDividerStyle().metrics, dividerPadding = dividerPadding.dp), ) +/** Reads the [SplitButtonStyle] for the default (filled) variant from the current IntelliJ JBUI theme values. */ public fun readDefaultSplitButtonStyle(): SplitButtonStyle = SplitButtonStyle( button = readDefaultButtonStyle(), diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeText.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeText.kt index 83688eb256aa..bd3f8e899c02 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeText.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeText.kt @@ -279,6 +279,7 @@ private val image = ImageUtil.createImage(1, 1, TYPE_INT_ARGB) * Computes the "base" line height with the same logic used by * [com.intellij.openapi.editor.impl.view.EditorView.initMetricsIfNeeded]. * + * @param font The font for which to compute the line height. * @param treatAsUnscaled When true, the font metrics are treated as "unscaled" (i.e., they do not need compensation for * the IDE scale). This is useful e.g., for editor scheme fonts, which are not scaled, contrary to LaF fonts. */ diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt index 8254931a7296..6f316f38e5a0 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/SwingBridgeTheme.kt @@ -33,6 +33,13 @@ import org.jetbrains.jewel.ui.util.LocalMessageResourceResolverProvider private val bridgeThemeReader by lazy { SwingBridgeReader() } +/** + * Entry-point composable for using Jewel inside an IntelliJ Platform plugin. Reads the current IntelliJ theme via + * [SwingBridgeReader] and applies it as a [BaseJewelTheme] with Swing compatibility mode enabled and the appropriate + * platform bridge providers wired up. + * + * @param content The composable content to render under the bridged theme. + */ @ApiStatus.Experimental @ExperimentalJewelApi @Composable diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/InterFont.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/InterFont.kt index f1ac2ea303fe..60570465c6f0 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/InterFont.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/InterFont.kt @@ -39,5 +39,6 @@ private val InterFontFamily = Font(resource = "/fonts/inter/Inter-BlackItalic.ttf", weight = FontWeight.Black, style = FontStyle.Italic), ) +/** The Inter font family, bundled with Jewel for use in standalone (non-IDE) applications. */ public val FontFamily.Companion.Inter: FontFamily get() = InterFontFamily diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/JetBrainsMonoFont.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/JetBrainsMonoFont.kt index e38f5919a8b6..7986093cbe5c 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/JetBrainsMonoFont.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/JetBrainsMonoFont.kt @@ -63,5 +63,6 @@ private val JetBrainsMonoFontFamily = ), ) +/** The JetBrains Mono font family, bundled with Jewel. */ public val FontFamily.Companion.JetBrainsMono: FontFamily get() = JetBrainsMonoFontFamily diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandalonePainterHintsProvider.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandalonePainterHintsProvider.kt index 728eaa9f6be9..cec2301d7577 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandalonePainterHintsProvider.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandalonePainterHintsProvider.kt @@ -100,6 +100,7 @@ public class StandalonePainterHintsProvider(theme: ThemeDefinition) : add(Dark(JewelTheme.isDark)) } + /** Companion object for [StandalonePainterHintsProvider]. */ public companion object { // Extracted from com.intellij.ide.ui.UITheme#colorPalette private val intellijColorPalette = diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandaloneScrollbarHelper.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandaloneScrollbarHelper.kt index 71a5f0ea5cc1..9f6b8fd8a3c0 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandaloneScrollbarHelper.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/StandaloneScrollbarHelper.kt @@ -44,6 +44,7 @@ public interface ScrollbarHelper { */ public val scrollbarVisibilityStyle: ScrollbarVisibility + /** Delegates to the macOS-specific [StandaloneScrollbarHelper] on macOS, or a no-op dummy on other platforms. */ public companion object : ScrollbarHelper by if (hostOs == OS.MacOS) scrollbarService else DummyScrollbarHelper } diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/bundle/DynamicBundle.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/bundle/DynamicBundle.kt index 72c2aa8f80ca..0607ebaeac97 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/bundle/DynamicBundle.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/bundle/DynamicBundle.kt @@ -49,9 +49,11 @@ public open class DynamicBundle(bundleClass: Class<*>, private val pathToBundle: private val cache = ConcurrentHashMap() + /** Returns the localized message for [key], substituting any [params] into the format pattern. */ public fun getMessage(key: @NonNls String, vararg params: Any?): @Nls String = @Suppress("HardCodedStringLiteral") getResourceBundle().messageOrDefault(key, params = params) + /** Returns a lazy [Supplier] that retrieves the localized message for [key] with optional [params] on demand. */ public fun getLazyMessage(key: @NonNls String, vararg params: Any?): Supplier<@Nls String> = Supplier { getMessage(key, params = params) } @@ -82,6 +84,7 @@ public open class DynamicBundle(bundleClass: Class<*>, private val pathToBundle: } } + /** Companion object for [DynamicBundle]. */ public companion object { @Suppress("HardCodedStringLiteral") internal fun postprocessValue( diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/menuShortcut/StandaloneShortcutProvider.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/menuShortcut/StandaloneShortcutProvider.kt index bcf8aceda61e..13042cedf2ff 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/menuShortcut/StandaloneShortcutProvider.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/menuShortcut/StandaloneShortcutProvider.kt @@ -13,6 +13,10 @@ import org.jetbrains.jewel.ui.component.ContextMenuItemOptionAction.PasteMenuIte import org.jetbrains.jewel.ui.component.ContextMenuItemOptionAction.SelectAllMenuItemOptionAction import org.jetbrains.skiko.hostOs +/** + * Standalone implementation of [MenuItemShortcutProvider] that maps context menu actions to platform-appropriate key + * strokes. + */ @ApiStatus.Internal @InternalJewelApi public object StandaloneShortcutProvider : MenuItemShortcutProvider { diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUIBannerStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUIBannerStyling.kt index d212d357b440..3481d74256fb 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUIBannerStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUIBannerStyling.kt @@ -14,10 +14,13 @@ import org.jetbrains.jewel.ui.component.styling.DefaultBannerStyles import org.jetbrains.jewel.ui.component.styling.InlineBannerStyle import org.jetbrains.jewel.ui.component.styling.InlineBannerStyles +/** Provides access to the [IntUiDefaultBannerStylesFactory] via the [DefaultBannerStyles] companion. */ public val DefaultBannerStyles.Companion.Default: IntUiDefaultBannerStylesFactory get() = IntUiDefaultBannerStylesFactory +/** Factory object for creating Int UI [DefaultBannerStyles] instances. */ public object IntUiDefaultBannerStylesFactory { + /** Creates an Int UI light [DefaultBannerStyles] with the provided parameters. */ public fun light( information: DefaultBannerStyle = DefaultBannerStyle.Information.light(), success: DefaultBannerStyle = DefaultBannerStyle.Success.light(), @@ -26,6 +29,7 @@ public object IntUiDefaultBannerStylesFactory { ): DefaultBannerStyles = DefaultBannerStyles(information = information, success = success, warning = warning, error = error) + /** Creates an Int UI dark [DefaultBannerStyles] with the provided parameters. */ public fun dark( information: DefaultBannerStyle = DefaultBannerStyle.Information.dark(), success: DefaultBannerStyle = DefaultBannerStyle.Success.dark(), @@ -35,127 +39,148 @@ public object IntUiDefaultBannerStylesFactory { DefaultBannerStyles(information = information, success = success, warning = warning, error = error) } -// region Information Banner +/** Provides access to the [IntUiDefaultInformationBannerStyleFactory] via the [DefaultBannerStyle] companion. */ public val DefaultBannerStyle.Companion.Information: IntUiDefaultInformationBannerStyleFactory get() = IntUiDefaultInformationBannerStyleFactory +/** Factory object for creating Int UI information-variant [DefaultBannerStyle] instances. */ public object IntUiDefaultInformationBannerStyleFactory { + /** Creates an Int UI light information [DefaultBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Information.light(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark information [DefaultBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Information.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) } +/** Provides access to the [IntUiInformationBannerColorFactory] via the [BannerColors] companion. */ public val BannerColors.Companion.Information: IntUiInformationBannerColorFactory get() = IntUiInformationBannerColorFactory +/** Factory object for creating Int UI information-variant [BannerColors] instances. */ public object IntUiInformationBannerColorFactory { + /** Creates an Int UI light information [BannerColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.blue(13), border: Color = IntUiLightTheme.colors.blue(10), ): BannerColors = BannerColors(background = background, border = border) + /** Creates an Int UI dark information [BannerColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.blue(1), border: Color = IntUiDarkTheme.colors.blue(3), ): BannerColors = BannerColors(background = background, border = border) } -// endregion - -// region Success Banner +/** Provides access to the [IntUiDefaultSuccessBannerStyleFactory] via the [DefaultBannerStyle] companion. */ public val DefaultBannerStyle.Companion.Success: IntUiDefaultSuccessBannerStyleFactory get() = IntUiDefaultSuccessBannerStyleFactory +/** Factory object for creating Int UI success-variant [DefaultBannerStyle] instances. */ public object IntUiDefaultSuccessBannerStyleFactory { + /** Creates an Int UI light success [DefaultBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Success.light(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark success [DefaultBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Success.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) } +/** Factory object for creating Int UI success-variant [BannerColors] instances. */ public object IntUiSuccessBannerColorFactory { + /** Creates an Int UI light success [BannerColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.green(11), border: Color = IntUiLightTheme.colors.green(9), ): BannerColors = BannerColors(background = background, border = border) + /** Creates an Int UI dark success [BannerColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.green(1), border: Color = IntUiDarkTheme.colors.green(3), ): BannerColors = BannerColors(background = background, border = border) } -// endregion - -// region Warning Banner +/** Provides access to the [IntUiDefaultWarningBannerStyleFactory] via the [DefaultBannerStyle] companion. */ public val DefaultBannerStyle.Companion.Warning: IntUiDefaultWarningBannerStyleFactory get() = IntUiDefaultWarningBannerStyleFactory +/** Factory object for creating Int UI warning-variant [DefaultBannerStyle] instances. */ public object IntUiDefaultWarningBannerStyleFactory { + /** Creates an Int UI light warning [DefaultBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Warning.light(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark warning [DefaultBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Warning.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) } +/** Provides access to the [IntUiWarningBannerColorFactory] via the [BannerColors] companion. */ public val BannerColors.Companion.Warning: IntUiWarningBannerColorFactory get() = IntUiWarningBannerColorFactory +/** Factory object for creating Int UI warning-variant [BannerColors] instances. */ public object IntUiWarningBannerColorFactory { + /** Creates an Int UI light warning [BannerColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.yellow(10), border: Color = IntUiLightTheme.colors.yellow(6), ): BannerColors = BannerColors(background = background, border = border) + /** Creates an Int UI dark warning [BannerColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.yellow(1), border: Color = IntUiDarkTheme.colors.yellow(2), ): BannerColors = BannerColors(background = background, border = border) } -// endregion - -// region Error Banner +/** Provides access to the [IntUiDefaultErrorBannerStyleFactory] via the [DefaultBannerStyle] companion. */ public val DefaultBannerStyle.Companion.Error: IntUiDefaultErrorBannerStyleFactory get() = IntUiDefaultErrorBannerStyleFactory +/** Factory object for creating Int UI error-variant [DefaultBannerStyle] instances. */ public object IntUiDefaultErrorBannerStyleFactory { + /** Creates an Int UI light error [DefaultBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Error.light(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark error [DefaultBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Error.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): DefaultBannerStyle = DefaultBannerStyle(colors = colors, metrics = metrics) } +/** Provides access to the [IntUiErrorBannerColorFactory] via the [BannerColors] companion. */ public val BannerColors.Companion.Error: IntUiErrorBannerColorFactory get() = IntUiErrorBannerColorFactory +/** Factory object for creating Int UI error-variant [BannerColors] instances. */ public object IntUiErrorBannerColorFactory { + /** Creates an Int UI light error [BannerColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.red(12), border: Color = IntUiLightTheme.colors.red(9), ): BannerColors = BannerColors(background = background, border = border) + /** Creates an Int UI dark error [BannerColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.red(1), border: Color = IntUiDarkTheme.colors.red(3), @@ -164,10 +189,13 @@ public object IntUiErrorBannerColorFactory { // endregion +/** Provides access to the [IntUiInlineBannerStylesFactory] via the [InlineBannerStyles] companion. */ public val InlineBannerStyles.Companion.Default: IntUiInlineBannerStylesFactory get() = IntUiInlineBannerStylesFactory +/** Factory object for creating Int UI [InlineBannerStyles] instances. */ public object IntUiInlineBannerStylesFactory { + /** Creates an Int UI light [InlineBannerStyles] with the provided parameters. */ public fun light( information: InlineBannerStyle = InlineBannerStyle.Information.light(), success: InlineBannerStyle = InlineBannerStyle.Success.light(), @@ -176,6 +204,7 @@ public object IntUiInlineBannerStylesFactory { ): InlineBannerStyles = InlineBannerStyles(information = information, success = success, warning = warning, error = error) + /** Creates an Int UI dark [InlineBannerStyles] with the provided parameters. */ public fun dark( information: InlineBannerStyle = InlineBannerStyle.Information.dark(), success: InlineBannerStyle = InlineBannerStyle.Success.dark(), @@ -185,6 +214,7 @@ public object IntUiInlineBannerStylesFactory { InlineBannerStyles(information = information, success = success, warning = warning, error = error) } +/** Creates an Int UI default [BannerMetrics] with the provided parameters. */ @Deprecated( "Use the `default()` function with `cornerSize` and `paddingValues`", replaceWith = ReplaceWith("default(borderWidth, cornerSize = TODO(), paddingValues = TODO())"), @@ -192,79 +222,87 @@ public object IntUiInlineBannerStylesFactory { public fun BannerMetrics.Companion.default(borderWidth: Dp = 1.dp): BannerMetrics = BannerMetrics(borderWidth, CornerSize(8.dp), PaddingValues(12.dp)) +/** Creates an Int UI default [BannerMetrics] with the provided parameters. */ public fun BannerMetrics.Companion.default( borderWidth: Dp = 1.dp, cornerSize: CornerSize = CornerSize(8.dp), paddingValues: PaddingValues = PaddingValues(12.dp), ): BannerMetrics = BannerMetrics(borderWidth, cornerSize, paddingValues) -// region Inline Information Banner +/** Provides access to the [IntUiInlineInformationBannerStyleFactory] via the [InlineBannerStyle] companion. */ public val InlineBannerStyle.Companion.Information: IntUiInlineInformationBannerStyleFactory get() = IntUiInlineInformationBannerStyleFactory +/** Factory object for creating Int UI information-variant [InlineBannerStyle] instances. */ public object IntUiInlineInformationBannerStyleFactory { + /** Creates an Int UI light information [InlineBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Information.light(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark information [InlineBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Information.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) } -// endregion - -// region Inline Success Banner +/** Provides access to the [IntUiInlineSuccessBannerStyleFactory] via the [InlineBannerStyle] companion. */ public val InlineBannerStyle.Companion.Success: IntUiInlineSuccessBannerStyleFactory get() = IntUiInlineSuccessBannerStyleFactory +/** Factory object for creating Int UI success-variant [InlineBannerStyle] instances. */ public object IntUiInlineSuccessBannerStyleFactory { + /** Creates an Int UI light success [InlineBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Success.light(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark success [InlineBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Success.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) } +/** Provides access to the [IntUiSuccessBannerColorFactory] via the [BannerColors] companion. */ public val BannerColors.Companion.Success: IntUiSuccessBannerColorFactory get() = IntUiSuccessBannerColorFactory -// endregion - -// region Inline Warning Banner +/** Provides access to the [IntUiInlineWarningBannerStyleFactory] via the [InlineBannerStyle] companion. */ public val InlineBannerStyle.Companion.Warning: IntUiInlineWarningBannerStyleFactory get() = IntUiInlineWarningBannerStyleFactory +/** Factory object for creating Int UI warning-variant [InlineBannerStyle] instances. */ public object IntUiInlineWarningBannerStyleFactory { + /** Creates an Int UI light warning [InlineBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Warning.light(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark warning [InlineBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Warning.dark(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) } -// endregion - -// region Inline Error Banner +/** Provides access to the [IntUiInlineErrorBannerStyleFactory] via the [InlineBannerStyle] companion. */ public val InlineBannerStyle.Companion.Error: IntUiInlineErrorBannerStyleFactory get() = IntUiInlineErrorBannerStyleFactory +/** Factory object for creating Int UI error-variant [InlineBannerStyle] instances. */ public object IntUiInlineErrorBannerStyleFactory { + /** Creates an Int UI light error [InlineBannerStyle] with the provided parameters. */ public fun light( colors: BannerColors = BannerColors.Error.light(), metrics: BannerMetrics = BannerMetrics.default(), ): InlineBannerStyle = InlineBannerStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark error [InlineBannerStyle] with the provided parameters. */ public fun dark( colors: BannerColors = BannerColors.Error.dark(), metrics: BannerMetrics = BannerMetrics.default(), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiBadgeStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiBadgeStyling.kt index 33d6d61ac6e5..8eeba1707e57 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiBadgeStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiBadgeStyling.kt @@ -14,6 +14,7 @@ import org.jetbrains.jewel.ui.component.styling.BadgeMetrics import org.jetbrains.jewel.ui.component.styling.BadgeStyle import org.jetbrains.jewel.ui.component.styling.BadgeStyles +/** Creates an Int UI light [BadgeStyles] with the provided parameters. */ public fun BadgeStyles.Companion.light( blue: BadgeStyle = BadgeStyle.Blue.light(), blueSecondary: BadgeStyle = BadgeStyle.BlueSecondary.light(), @@ -31,6 +32,7 @@ public fun BadgeStyles.Companion.light( graySecondary = graySecondary, ) +/** Creates an Int UI dark [BadgeStyles] with the provided parameters. */ public fun BadgeStyles.Companion.dark( blue: BadgeStyle = BadgeStyle.Blue.dark(), blueSecondary: BadgeStyle = BadgeStyle.BlueSecondary.dark(), @@ -48,24 +50,30 @@ public fun BadgeStyles.Companion.dark( graySecondary = graySecondary, ) +/** Provides access to the Int UI blue [BadgeStyle] factory. */ public val BadgeStyle.Companion.Blue: IntUiBlueBadgeStyleFactory get() = IntUiBlueBadgeStyleFactory +/** Factory object for creating Int UI blue [BadgeStyle] instances. */ public object IntUiBlueBadgeStyleFactory { + /** Creates an Int UI light blue [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.Blue.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark blue [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.Blue.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI blue [BadgeColors] factory. */ public val BadgeColors.Companion.Blue: IntUiBlueBadgeColorsFactory get() = IntUiBlueBadgeColorsFactory +/** Factory object for creating Int UI blue [BadgeColors] instances. */ public object IntUiBlueBadgeColorsFactory { private val lightBackground = IntUiLightTheme.colors.blueOrNull(4) ?: Color(0xFF3574F0) private val lightContent = IntUiLightTheme.colors.grayOrNull(14) ?: Color(0xFFFFFFFF) @@ -75,6 +83,7 @@ public object IntUiBlueBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.grayOrNull(1) ?: Color(0xFF1E1F22) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light blue [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -100,6 +109,7 @@ public object IntUiBlueBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark blue [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -126,24 +136,30 @@ public object IntUiBlueBadgeColorsFactory { ) } +/** Provides access to the Int UI blue-secondary [BadgeStyle] factory. */ public val BadgeStyle.Companion.BlueSecondary: IntUiBlueSecondaryBadgeStyleFactory get() = IntUiBlueSecondaryBadgeStyleFactory +/** Factory object for creating Int UI blue-secondary [BadgeStyle] instances. */ public object IntUiBlueSecondaryBadgeStyleFactory { + /** Creates an Int UI light blue-secondary [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.BlueSecondary.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark blue-secondary [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.BlueSecondary.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI blue-secondary [BadgeColors] factory. */ public val BadgeColors.Companion.BlueSecondary: IntUiBlueSecondaryBadgeColorsFactory get() = IntUiBlueSecondaryBadgeColorsFactory +/** Factory object for creating Int UI blue-secondary [BadgeColors] instances. */ public object IntUiBlueSecondaryBadgeColorsFactory { private val lightBackground = Color(0x293574F0) private val lightContent = IntUiLightTheme.colors.blueOrNull(1) ?: Color(0xFF2E55A3) @@ -153,6 +169,7 @@ public object IntUiBlueSecondaryBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.blueOrNull(12) ?: Color(0xFFB5CEFF) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light blue-secondary [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -178,6 +195,7 @@ public object IntUiBlueSecondaryBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark blue-secondary [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -204,24 +222,30 @@ public object IntUiBlueSecondaryBadgeColorsFactory { ) } +/** Provides access to the Int UI purple-secondary [BadgeStyle] factory. */ public val BadgeStyle.Companion.PurpleSecondary: IntUiPurpleSecondaryBadgeStyleFactory get() = IntUiPurpleSecondaryBadgeStyleFactory +/** Factory object for creating Int UI purple-secondary [BadgeStyle] instances. */ public object IntUiPurpleSecondaryBadgeStyleFactory { + /** Creates an Int UI light purple-secondary [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.PurpleSecondary.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark purple-secondary [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.PurpleSecondary.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI purple-secondary [BadgeColors] factory. */ public val BadgeColors.Companion.PurpleSecondary: IntUiPurpleSecondaryBadgeColorsFactory get() = IntUiPurpleSecondaryBadgeColorsFactory +/** Factory object for creating Int UI purple-secondary [BadgeColors] instances. */ public object IntUiPurpleSecondaryBadgeColorsFactory { private val lightBackground = Color(0x29834DF0) private val lightContent = IntUiLightTheme.colors.purpleOrNull(1) ?: Color(0xFF55339C) @@ -231,6 +255,7 @@ public object IntUiPurpleSecondaryBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.purpleOrNull(12) ?: Color(0xFFE4CEFF) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light purple-secondary [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -256,6 +281,7 @@ public object IntUiPurpleSecondaryBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark purple-secondary [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -282,24 +308,30 @@ public object IntUiPurpleSecondaryBadgeColorsFactory { ) } +/** Provides access to the Int UI green [BadgeStyle] factory. */ public val BadgeStyle.Companion.Green: IntUiGreenBadgeStyleFactory get() = IntUiGreenBadgeStyleFactory +/** Factory object for creating Int UI green [BadgeStyle] instances. */ public object IntUiGreenBadgeStyleFactory { + /** Creates an Int UI light green [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.Green.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark green [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.Green.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI green [BadgeColors] factory. */ public val BadgeColors.Companion.Green: IntUiGreenBadgeColorsFactory get() = IntUiGreenBadgeColorsFactory +/** Factory object for creating Int UI green [BadgeColors] instances. */ public object IntUiGreenBadgeColorsFactory { private val lightBackground = IntUiLightTheme.colors.greenOrNull(4) ?: Color(0xFF208A3C) private val lightContent = IntUiLightTheme.colors.grayOrNull(14) ?: Color(0xFFFFFFFF) @@ -309,6 +341,7 @@ public object IntUiGreenBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.grayOrNull(1) ?: Color(0xFF1E1F22) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light green [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -334,6 +367,7 @@ public object IntUiGreenBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark green [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -360,24 +394,30 @@ public object IntUiGreenBadgeColorsFactory { ) } +/** Provides access to the Int UI green-secondary [BadgeStyle] factory. */ public val BadgeStyle.Companion.GreenSecondary: IntUiGreenSecondaryBadgeStyleFactory get() = IntUiGreenSecondaryBadgeStyleFactory +/** Factory object for creating Int UI green-secondary [BadgeStyle] instances. */ public object IntUiGreenSecondaryBadgeStyleFactory { + /** Creates an Int UI light green-secondary [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.GreenSecondary.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark green-secondary [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.GreenSecondary.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI green-secondary [BadgeColors] factory. */ public val BadgeColors.Companion.GreenSecondary: IntUiGreenSecondaryBadgeColorsFactory get() = IntUiGreenSecondaryBadgeColorsFactory +/** Factory object for creating Int UI green-secondary [BadgeColors] instances. */ public object IntUiGreenSecondaryBadgeColorsFactory { private val lightBackground = Color(0x29208A3C) private val lightContent = IntUiLightTheme.colors.greenOrNull(1) ?: Color(0xFF1E6B33) @@ -387,6 +427,7 @@ public object IntUiGreenSecondaryBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.greenOrNull(12) ?: Color(0xFFD4FAD7) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light green-secondary [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -412,6 +453,7 @@ public object IntUiGreenSecondaryBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark green-secondary [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -438,24 +480,30 @@ public object IntUiGreenSecondaryBadgeColorsFactory { ) } +/** Provides access to the Int UI gray-secondary [BadgeStyle] factory. */ public val BadgeStyle.Companion.GraySecondary: IntUiGraySecondaryBadgeStyleFactory get() = IntUiGraySecondaryBadgeStyleFactory +/** Factory object for creating Int UI gray-secondary [BadgeStyle] instances. */ public object IntUiGraySecondaryBadgeStyleFactory { + /** Creates an Int UI light gray-secondary [BadgeStyle] with the provided parameters. */ public fun light( colors: BadgeColors = BadgeColors.GraySecondary.light(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) + /** Creates an Int UI dark gray-secondary [BadgeStyle] with the provided parameters. */ public fun dark( colors: BadgeColors = BadgeColors.GraySecondary.dark(), metrics: BadgeMetrics = BadgeMetrics.default(), ): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics) } +/** Provides access to the Int UI gray-secondary [BadgeColors] factory. */ public val BadgeColors.Companion.GraySecondary: IntUiGraySecondaryBadgeColorsFactory get() = IntUiGraySecondaryBadgeColorsFactory +/** Factory object for creating Int UI gray-secondary [BadgeColors] instances. */ public object IntUiGraySecondaryBadgeColorsFactory { private val lightBackground = Color(0x1F6C707E) private val lightContent = IntUiLightTheme.colors.grayOrNull(6) ?: Color(0xFF6C707E) @@ -465,6 +513,7 @@ public object IntUiGraySecondaryBadgeColorsFactory { private val darkContent = IntUiDarkTheme.colors.grayOrNull(10) ?: Color(0xFFB4B8BF) private val darkDisabled = IntUiDisabledBadgeColorsFactory.dark() + /** Creates an Int UI light gray-secondary [BadgeColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(lightBackground.copy(alpha = .12f)), backgroundDisabled: Brush = SolidColor(lightDisabled.background), @@ -490,6 +539,7 @@ public object IntUiGraySecondaryBadgeColorsFactory { contentHovered = contentHovered, ) + /** Creates an Int UI dark gray-secondary [BadgeColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(darkBackground.copy(alpha = .20f)), backgroundDisabled: Brush = SolidColor(darkDisabled.background), @@ -516,6 +566,7 @@ public object IntUiGraySecondaryBadgeColorsFactory { ) } +/** Creates an Int UI default [BadgeMetrics] with the provided parameters. */ public fun BadgeMetrics.Companion.default( cornerSize: CornerSize = CornerSize(100), padding: PaddingValues = PaddingValues(horizontal = 6.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt index c15129b96df6..04a507312b46 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt @@ -15,16 +15,20 @@ import org.jetbrains.jewel.ui.component.styling.ButtonColors import org.jetbrains.jewel.ui.component.styling.ButtonMetrics import org.jetbrains.jewel.ui.component.styling.ButtonStyle +/** Factory for creating Int UI default [ButtonStyle] instances. */ public val ButtonStyle.Companion.Default: IntUiDefaultButtonStyleFactory get() = IntUiDefaultButtonStyleFactory +/** Factory object that creates Int UI default [ButtonStyle] instances for light and dark themes. */ public object IntUiDefaultButtonStyleFactory { + /** Creates an Int UI light default [ButtonStyle] with the provided parameters. */ public fun light( colors: ButtonColors = ButtonColors.Default.light(), metrics: ButtonMetrics = ButtonMetrics.default(), focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) + /** Creates an Int UI dark default [ButtonStyle] with the provided parameters. */ public fun dark( colors: ButtonColors = ButtonColors.Default.dark(), metrics: ButtonMetrics = ButtonMetrics.default(), @@ -32,16 +36,20 @@ public object IntUiDefaultButtonStyleFactory { ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) } +/** Factory for creating Int UI outlined [ButtonStyle] instances. */ public val ButtonStyle.Companion.Outlined: IntUiOutlinedButtonStyleFactory get() = IntUiOutlinedButtonStyleFactory +/** Factory object that creates Int UI outlined [ButtonStyle] instances for light and dark themes. */ public object IntUiOutlinedButtonStyleFactory { + /** Creates an Int UI light outlined [ButtonStyle] with the provided parameters. */ public fun light( colors: ButtonColors = ButtonColors.Outlined.light(), metrics: ButtonMetrics = ButtonMetrics.outlined(), focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) + /** Creates an Int UI dark outlined [ButtonStyle] with the provided parameters. */ public fun dark( colors: ButtonColors = ButtonColors.Outlined.dark(), metrics: ButtonMetrics = ButtonMetrics.outlined(), @@ -49,10 +57,13 @@ public object IntUiOutlinedButtonStyleFactory { ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) } +/** Factory for creating Int UI default [ButtonColors] instances. */ public val ButtonColors.Companion.Default: IntUiDefaultButtonColorFactory get() = IntUiDefaultButtonColorFactory +/** Factory object that creates Int UI default [ButtonColors] instances for light and dark themes. */ public object IntUiDefaultButtonColorFactory { + /** Creates an Int UI light default [ButtonColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(IntUiLightTheme.colors.blue(4)), backgroundDisabled: Brush = SolidColor(Color.Unspecified), @@ -88,6 +99,7 @@ public object IntUiDefaultButtonColorFactory { borderHovered = borderHovered, ) + /** Creates an Int UI dark default [ButtonColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(IntUiDarkTheme.colors.blue(6)), backgroundDisabled: Brush = SolidColor(Color.Unspecified), @@ -124,10 +136,13 @@ public object IntUiDefaultButtonColorFactory { ) } +/** Factory for creating Int UI outlined [ButtonColors] instances. */ public val ButtonColors.Companion.Outlined: IntUiOutlinedButtonColorFactory get() = IntUiOutlinedButtonColorFactory +/** Factory object that creates Int UI outlined [ButtonColors] instances for light and dark themes. */ public object IntUiOutlinedButtonColorFactory { + /** Creates an Int UI light outlined [ButtonColors] with the provided parameters. */ public fun light( background: Brush = SolidColor(IntUiLightTheme.colors.gray(14)), backgroundDisabled: Brush = SolidColor(Color.Unspecified), @@ -163,6 +178,7 @@ public object IntUiOutlinedButtonColorFactory { borderHovered = borderHovered, ) + /** Creates an Int UI dark outlined [ButtonColors] with the provided parameters. */ public fun dark( background: Brush = SolidColor(Color.Transparent), backgroundDisabled: Brush = SolidColor(Color.Unspecified), @@ -199,6 +215,7 @@ public object IntUiOutlinedButtonColorFactory { ) } +/** Creates an Int UI default [ButtonMetrics] with the provided parameters. */ public fun ButtonMetrics.Companion.default( cornerSize: CornerSize = CornerSize(4.dp), padding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 6.dp), @@ -207,6 +224,7 @@ public fun ButtonMetrics.Companion.default( focusOutlineExpand: Dp = 1.5.dp, ): ButtonMetrics = ButtonMetrics(cornerSize, padding, minSize, borderWidth, focusOutlineExpand) +/** Creates an Int UI outlined [ButtonMetrics] with the provided parameters. */ public fun ButtonMetrics.Companion.outlined( cornerSize: CornerSize = CornerSize(4.dp), padding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 6.dp), @@ -215,24 +233,31 @@ public fun ButtonMetrics.Companion.outlined( focusOutlineExpand: Dp = Dp.Unspecified, ): ButtonMetrics = ButtonMetrics(cornerSize, padding, minSize, borderWidth, focusOutlineExpand) +/** Factory for creating Int UI slim [ButtonStyle] instances. */ public val ButtonStyle.Companion.Slim: IntUiSlimButtonStyleFactory get() = IntUiSlimButtonStyleFactory +/** Factory object that provides access to slim default and outlined [ButtonStyle] factories. */ public object IntUiSlimButtonStyleFactory { + /** Factory for creating Int UI slim default [ButtonStyle] instances. */ public val Default: IntUiSlimDefaultButtonStyleFactory get() = IntUiSlimDefaultButtonStyleFactory + /** Factory for creating Int UI slim outlined [ButtonStyle] instances. */ public val Outlined: IntUiSlimOutlinedButtonStyleFactory get() = IntUiSlimOutlinedButtonStyleFactory } +/** Factory object that creates Int UI slim default [ButtonStyle] instances for light and dark themes. */ public object IntUiSlimDefaultButtonStyleFactory { + /** Creates an Int UI light slim default [ButtonStyle] with the provided parameters. */ public fun light( colors: ButtonColors = ButtonColors.Default.light(), metrics: ButtonMetrics = ButtonMetrics.Slim.default(), focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) + /** Creates an Int UI dark slim default [ButtonStyle] with the provided parameters. */ public fun dark( colors: ButtonColors = ButtonColors.Default.dark(), metrics: ButtonMetrics = ButtonMetrics.Slim.default(), @@ -240,13 +265,16 @@ public object IntUiSlimDefaultButtonStyleFactory { ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) } +/** Factory object that creates Int UI slim outlined [ButtonStyle] instances for light and dark themes. */ public object IntUiSlimOutlinedButtonStyleFactory { + /** Creates an Int UI light slim outlined [ButtonStyle] with the provided parameters. */ public fun light( colors: ButtonColors = ButtonColors.Outlined.light(), metrics: ButtonMetrics = ButtonMetrics.Slim.outlined(), focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) + /** Creates an Int UI dark slim outlined [ButtonStyle] with the provided parameters. */ public fun dark( colors: ButtonColors = ButtonColors.Outlined.dark(), metrics: ButtonMetrics = ButtonMetrics.Slim.outlined(), @@ -254,10 +282,13 @@ public object IntUiSlimOutlinedButtonStyleFactory { ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) } +/** Factory for creating Int UI slim [ButtonMetrics] instances. */ public val ButtonMetrics.Companion.Slim: IntUiSlimButtonMetricsFactory get() = IntUiSlimButtonMetricsFactory +/** Factory object that creates Int UI slim [ButtonMetrics] instances. */ public object IntUiSlimButtonMetricsFactory { + /** Creates an Int UI slim default [ButtonMetrics] with the provided parameters. */ public fun default( cornerSize: CornerSize = CornerSize(4.dp), padding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 2.dp), @@ -266,6 +297,7 @@ public object IntUiSlimButtonMetricsFactory { focusOutlineExpand: Dp = 1.5.dp, ): ButtonMetrics = ButtonMetrics(cornerSize, padding, minSize, borderWidth, focusOutlineExpand) + /** Creates an Int UI slim outlined [ButtonMetrics] with the provided parameters. */ public fun outlined( cornerSize: CornerSize = CornerSize(4.dp), padding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 2.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCheckboxStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCheckboxStyling.kt index ea823c522b91..01eabe938c8f 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCheckboxStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCheckboxStyling.kt @@ -14,30 +14,35 @@ import org.jetbrains.jewel.ui.component.styling.CheckboxStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icon.PathIconKey +/** Creates an Int UI light [CheckboxStyle] with the provided parameters. */ public fun CheckboxStyle.Companion.light( colors: CheckboxColors = CheckboxColors.light(), metrics: CheckboxMetrics = CheckboxMetrics.defaults(), icons: CheckboxIcons = CheckboxIcons.light(), ): CheckboxStyle = CheckboxStyle(colors, metrics, icons) +/** Creates an Int UI dark [CheckboxStyle] with the provided parameters. */ public fun CheckboxStyle.Companion.dark( colors: CheckboxColors = CheckboxColors.dark(), metrics: CheckboxMetrics = CheckboxMetrics.defaults(), icons: CheckboxIcons = CheckboxIcons.dark(), ): CheckboxStyle = CheckboxStyle(colors, metrics, icons) +/** Creates an Int UI light [CheckboxColors] with the provided parameters. */ public fun CheckboxColors.Companion.light( content: Color = Color.Unspecified, contentDisabled: Color = IntUiLightTheme.colors.gray(8), contentSelected: Color = content, ): CheckboxColors = CheckboxColors(content, contentDisabled, contentSelected) +/** Creates an Int UI dark [CheckboxColors] with the provided parameters. */ public fun CheckboxColors.Companion.dark( content: Color = Color.Unspecified, contentDisabled: Color = IntUiDarkTheme.colors.gray(7), contentSelected: Color = content, ): CheckboxColors = CheckboxColors(content, contentDisabled, contentSelected) +/** Creates an Int UI default [CheckboxMetrics] with the provided parameters. */ public fun CheckboxMetrics.Companion.defaults( checkboxSize: DpSize = DpSize(24.dp, 24.dp), outlineCornerSize: CornerSize = CornerSize(3.dp), @@ -63,11 +68,13 @@ public fun CheckboxMetrics.Companion.defaults( iconContentGap = iconContentGap, ) +/** Creates an Int UI light [CheckboxIcons] with the provided parameters. */ public fun CheckboxIcons.Companion.light( checkbox: IconKey = PathIconKey(path = "com/intellij/ide/ui/laf/icons/intellij/checkBox.svg", iconClass = CheckboxIcons::class.java) ): CheckboxIcons = CheckboxIcons(checkbox) +/** Creates an Int UI dark [CheckboxIcons] with the provided parameters. */ public fun CheckboxIcons.Companion.dark( checkbox: IconKey = PathIconKey(path = "com/intellij/ide/ui/laf/icons/darcula/checkBox.svg", iconClass = CheckboxIcons::class.java) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiChipStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiChipStyling.kt index 79a288a7a740..0cda64f61df9 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiChipStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiChipStyling.kt @@ -14,16 +14,19 @@ import org.jetbrains.jewel.ui.component.styling.ChipColors import org.jetbrains.jewel.ui.component.styling.ChipMetrics import org.jetbrains.jewel.ui.component.styling.ChipStyle +/** Creates an Int UI light [ChipStyle] with the provided parameters. */ public fun ChipStyle.Companion.light( colors: ChipColors = ChipColors.light(), metrics: ChipMetrics = ChipMetrics.defaults(), ): ChipStyle = ChipStyle(colors, metrics) +/** Creates an Int UI dark [ChipStyle] with the provided parameters. */ public fun ChipStyle.Companion.dark( colors: ChipColors = ChipColors.dark(), metrics: ChipMetrics = ChipMetrics.defaults(), ): ChipStyle = ChipStyle(colors, metrics) +/** Creates an Int UI light [ChipColors] with the provided parameters. */ public fun ChipColors.Companion.light( background: Brush = SolidColor(IntUiLightTheme.colors.gray(14)), backgroundDisabled: Brush = SolidColor(IntUiLightTheme.colors.gray(12)), @@ -89,6 +92,7 @@ public fun ChipColors.Companion.light( borderSelectedHovered = borderSelectedHovered, ) +/** Creates an Int UI dark [ChipColors] with the provided parameters. */ public fun ChipColors.Companion.dark( background: Brush = SolidColor(IntUiDarkTheme.colors.gray(2)), backgroundDisabled: Brush = SolidColor(IntUiDarkTheme.colors.gray(4)), @@ -154,6 +158,7 @@ public fun ChipColors.Companion.dark( borderSelectedHovered = borderSelectedHovered, ) +/** Creates an Int UI default [ChipMetrics] with the provided parameters. */ @Deprecated("Use the version with 'minSize' instead", level = DeprecationLevel.HIDDEN) public fun ChipMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(100), @@ -162,6 +167,7 @@ public fun ChipMetrics.Companion.defaults( borderWidthSelected: Dp = 2.dp, ): ChipMetrics = ChipMetrics(cornerSize, padding, borderWidth, borderWidthSelected, DpSize(72.dp, 28.dp)) +/** Creates an Int UI default [ChipMetrics] with the provided parameters. */ public fun ChipMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(100), padding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCircularProgressStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCircularProgressStyling.kt index 9024c466e17e..47174ef9e962 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCircularProgressStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiCircularProgressStyling.kt @@ -7,11 +7,13 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds import org.jetbrains.jewel.ui.component.styling.CircularProgressStyle +/** Creates an Int UI dark [CircularProgressStyle] with the provided parameters. */ public fun CircularProgressStyle.Companion.dark( frameTime: Duration = 125.milliseconds, color: Color = Color(0xFF6F737A), ): CircularProgressStyle = CircularProgressStyle(frameTime, color) +/** Creates an Int UI light [CircularProgressStyle] with the provided parameters. */ public fun CircularProgressStyle.Companion.light( frameTime: Duration = 125.milliseconds, color: Color = Color(0xFFA8ADBD), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiComboBoxStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiComboBoxStyling.kt index 4eae89e76900..a78901040f1e 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiComboBoxStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiComboBoxStyling.kt @@ -16,16 +16,20 @@ import org.jetbrains.jewel.ui.component.styling.ComboBoxStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Provides access to [IntUiDefaultComboBoxStyleFactory] for creating default-style [ComboBoxStyle] instances. */ public val ComboBoxStyle.Companion.Default: IntUiDefaultComboBoxStyleFactory get() = IntUiDefaultComboBoxStyleFactory +/** Factory object for creating Int UI default [ComboBoxStyle] instances. */ public object IntUiDefaultComboBoxStyleFactory { + /** Creates an Int UI light default [ComboBoxStyle] with the provided parameters. */ public fun light( colors: ComboBoxColors = ComboBoxColors.Default.light(), metrics: ComboBoxMetrics = ComboBoxMetrics.defaultWithRowCount(maxPopupRowCount = 10), icons: ComboBoxIcons = ComboBoxIcons.defaults(), ): ComboBoxStyle = ComboBoxStyle(colors, metrics, icons) + /** Creates an Int UI dark default [ComboBoxStyle] with the provided parameters. */ public fun dark( colors: ComboBoxColors = ComboBoxColors.Default.dark(), metrics: ComboBoxMetrics = ComboBoxMetrics.defaultWithRowCount(maxPopupRowCount = 10), @@ -33,16 +37,20 @@ public object IntUiDefaultComboBoxStyleFactory { ): ComboBoxStyle = ComboBoxStyle(colors, metrics, icons) } +/** Provides access to [IntUiUndecoratedComboBoxStyleFactory] for creating undecorated [ComboBoxStyle] instances. */ public val ComboBoxStyle.Companion.Undecorated: IntUiUndecoratedComboBoxStyleFactory get() = IntUiUndecoratedComboBoxStyleFactory +/** Factory object for creating Int UI undecorated [ComboBoxStyle] instances. */ public object IntUiUndecoratedComboBoxStyleFactory { + /** Creates an Int UI light undecorated [ComboBoxStyle] with the provided parameters. */ public fun light( colors: ComboBoxColors = ComboBoxColors.Undecorated.light(), metrics: ComboBoxMetrics = ComboBoxMetrics.undecoratedWithRowCount(maxPopupRowCount = 10), icons: ComboBoxIcons = ComboBoxIcons.defaults(), ): ComboBoxStyle = ComboBoxStyle(colors, metrics, icons) + /** Creates an Int UI dark undecorated [ComboBoxStyle] with the provided parameters. */ public fun dark( colors: ComboBoxColors = ComboBoxColors.Undecorated.dark(), metrics: ComboBoxMetrics = ComboBoxMetrics.undecoratedWithRowCount(maxPopupRowCount = 10), @@ -50,10 +58,13 @@ public object IntUiUndecoratedComboBoxStyleFactory { ): ComboBoxStyle = ComboBoxStyle(colors, metrics, icons) } +/** Provides access to [IntUiDefaultComboBoxColorsFactory] for creating default-style [ComboBoxColors] instances. */ public val ComboBoxColors.Companion.Default: IntUiDefaultComboBoxColorsFactory get() = IntUiDefaultComboBoxColorsFactory +/** Factory object for creating Int UI default [ComboBoxColors] instances. */ public object IntUiDefaultComboBoxColorsFactory { + /** Creates an Int UI light default [ComboBoxColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.gray(14), backgroundDisabled: Color = IntUiLightTheme.colors.gray(13), @@ -91,6 +102,7 @@ public object IntUiDefaultComboBoxColorsFactory { borderHovered = borderHovered, ) + /** Creates an Int UI dark default [ComboBoxColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.gray(2), backgroundDisabled: Color = background, @@ -129,10 +141,13 @@ public object IntUiDefaultComboBoxColorsFactory { ) } +/** Provides access to [IntUiUndecoratedComboBoxColorsFactory] for creating undecorated [ComboBoxColors] instances. */ public val ComboBoxColors.Companion.Undecorated: IntUiUndecoratedComboBoxColorsFactory get() = IntUiUndecoratedComboBoxColorsFactory +/** Factory object for creating Int UI undecorated [ComboBoxColors] instances. */ public object IntUiUndecoratedComboBoxColorsFactory { + /** Creates an Int UI light undecorated [ComboBoxColors] with the provided parameters. */ public fun light( background: Color = Color.Transparent, backgroundDisabled: Color = background, @@ -165,6 +180,7 @@ public object IntUiUndecoratedComboBoxColorsFactory { borderHovered = Color.Transparent, ) + /** Creates an Int UI dark undecorated [ComboBoxColors] with the provided parameters. */ public fun dark( background: Color = Color.Transparent, backgroundDisabled: Color = background, @@ -198,6 +214,7 @@ public object IntUiUndecoratedComboBoxColorsFactory { ) } +/** Creates an Int UI default [ComboBoxMetrics] constrained by a maximum popup row count. */ public fun ComboBoxMetrics.Companion.defaultWithRowCount( arrowAreaSize: DpSize = DpSize(28.dp, 28.dp), minSize: DpSize = DpSize(77.dp, 28.dp), @@ -218,6 +235,7 @@ public fun ComboBoxMetrics.Companion.defaultWithRowCount( maxPopupRowCount, ) +/** Creates an Int UI default [ComboBoxMetrics] constrained by a maximum popup height. */ public fun ComboBoxMetrics.Companion.default( arrowAreaSize: DpSize = DpSize(28.dp, 28.dp), minSize: DpSize = DpSize(77.dp, 28.dp), @@ -238,6 +256,7 @@ public fun ComboBoxMetrics.Companion.default( 8, // For backwards compatibility ) +/** Creates an Int UI undecorated [ComboBoxMetrics] constrained by a maximum popup row count. */ public fun ComboBoxMetrics.Companion.undecoratedWithRowCount( arrowAreaSize: DpSize = DpSize(28.dp, 28.dp), minSize: DpSize = DpSize(77.dp, 28.dp), @@ -258,6 +277,7 @@ public fun ComboBoxMetrics.Companion.undecoratedWithRowCount( maxPopupRowCount, ) +/** Creates an Int UI undecorated [ComboBoxMetrics] constrained by a maximum popup height. */ public fun ComboBoxMetrics.Companion.undecorated( arrowAreaSize: DpSize = DpSize(28.dp, 28.dp), minSize: DpSize = DpSize(77.dp, 28.dp), @@ -278,5 +298,6 @@ public fun ComboBoxMetrics.Companion.undecorated( 8, ) +/** Creates a default [ComboBoxIcons] with the provided parameters. */ public fun ComboBoxIcons.Companion.defaults(chevronDown: IconKey = AllIconsKeys.General.ChevronDown): ComboBoxIcons = ComboBoxIcons(chevronDown) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDividerStyle.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDividerStyle.kt index 379da5990616..1be226c43154 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDividerStyle.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDividerStyle.kt @@ -6,11 +6,13 @@ import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme import org.jetbrains.jewel.ui.component.styling.DividerMetrics import org.jetbrains.jewel.ui.component.styling.DividerStyle +/** Creates an Int UI light [DividerStyle] with the provided parameters. */ public fun DividerStyle.Companion.light( color: Color = IntUiLightTheme.colors.gray(12), metrics: DividerMetrics = DividerMetrics.defaults(), ): DividerStyle = DividerStyle(color, metrics) +/** Creates an Int UI dark [DividerStyle] with the provided parameters. */ public fun DividerStyle.Companion.dark( color: Color = IntUiDarkTheme.colors.gray(1), metrics: DividerMetrics = DividerMetrics.defaults(), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDropdownStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDropdownStyling.kt index 55d37e4df2cf..6c4e9b97f430 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDropdownStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiDropdownStyling.kt @@ -16,10 +16,13 @@ import org.jetbrains.jewel.ui.component.styling.MenuStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Provides access to the factory for creating Int UI default [DropdownStyle] instances. */ public val DropdownStyle.Companion.Default: IntUiDefaultDropdownStyleFactory get() = IntUiDefaultDropdownStyleFactory +/** Factory for creating Int UI default [DropdownStyle] instances. */ public object IntUiDefaultDropdownStyleFactory { + /** Creates an Int UI light default [DropdownStyle] with the provided parameters. */ public fun light( colors: DropdownColors = DropdownColors.Default.light(), metrics: DropdownMetrics = DropdownMetrics.default(), @@ -27,6 +30,7 @@ public object IntUiDefaultDropdownStyleFactory { menuStyle: MenuStyle = MenuStyle.light(), ): DropdownStyle = DropdownStyle(colors, metrics, icons, menuStyle) + /** Creates an Int UI dark default [DropdownStyle] with the provided parameters. */ public fun dark( colors: DropdownColors = DropdownColors.Default.dark(), metrics: DropdownMetrics = DropdownMetrics.default(), @@ -35,10 +39,13 @@ public object IntUiDefaultDropdownStyleFactory { ): DropdownStyle = DropdownStyle(colors, metrics, icons, menuStyle) } +/** Provides access to the factory for creating Int UI undecorated [DropdownStyle] instances. */ public val DropdownStyle.Companion.Undecorated: IntUiUndecoratedDropdownStyleFactory get() = IntUiUndecoratedDropdownStyleFactory +/** Factory for creating Int UI undecorated [DropdownStyle] instances. */ public object IntUiUndecoratedDropdownStyleFactory { + /** Creates an Int UI light undecorated [DropdownStyle] with the provided parameters. */ public fun light( colors: DropdownColors = DropdownColors.Undecorated.light(), metrics: DropdownMetrics = DropdownMetrics.undecorated(), @@ -46,6 +53,7 @@ public object IntUiUndecoratedDropdownStyleFactory { menuStyle: MenuStyle = MenuStyle.light(), ): DropdownStyle = DropdownStyle(colors, metrics, icons, menuStyle) + /** Creates an Int UI dark undecorated [DropdownStyle] with the provided parameters. */ public fun dark( colors: DropdownColors = DropdownColors.Undecorated.dark(), metrics: DropdownMetrics = DropdownMetrics.undecorated(), @@ -54,10 +62,13 @@ public object IntUiUndecoratedDropdownStyleFactory { ): DropdownStyle = DropdownStyle(colors, metrics, icons, menuStyle) } +/** Provides access to the factory for creating Int UI default [DropdownColors] instances. */ public val DropdownColors.Companion.Default: IntUiDefaultDropdownColorsFactory get() = IntUiDefaultDropdownColorsFactory +/** Factory for creating Int UI default [DropdownColors] instances. */ public object IntUiDefaultDropdownColorsFactory { + /** Creates an Int UI light default [DropdownColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.gray(14), backgroundDisabled: Color = IntUiLightTheme.colors.gray(13), @@ -103,6 +114,7 @@ public object IntUiDefaultDropdownColorsFactory { iconTintHovered = iconTintHovered, ) + /** Creates an Int UI dark default [DropdownColors] with the provided parameters. */ public fun dark( background: Color = IntUiDarkTheme.colors.gray(2), backgroundDisabled: Color = background, @@ -149,10 +161,13 @@ public object IntUiDefaultDropdownColorsFactory { ) } +/** Provides access to the factory for creating Int UI undecorated [DropdownColors] instances. */ public val DropdownColors.Companion.Undecorated: IntUiUndecoratedDropdownColorsFactory get() = IntUiUndecoratedDropdownColorsFactory +/** Factory for creating Int UI undecorated [DropdownColors] instances. */ public object IntUiUndecoratedDropdownColorsFactory { + /** Creates an Int UI light undecorated [DropdownColors] with the provided parameters. */ public fun light( background: Color = Color.Transparent, backgroundDisabled: Color = background, @@ -193,6 +208,7 @@ public object IntUiUndecoratedDropdownColorsFactory { iconTintHovered = iconTintHovered, ) + /** Creates an Int UI dark undecorated [DropdownColors] with the provided parameters. */ public fun dark( background: Color = Color.Transparent, backgroundDisabled: Color = background, @@ -234,6 +250,7 @@ public object IntUiUndecoratedDropdownColorsFactory { ) } +/** Creates an Int UI default [DropdownMetrics] with the provided parameters. */ public fun DropdownMetrics.Companion.default( arrowMinSize: DpSize = DpSize((23 + 3).dp, 24.dp), minSize: DpSize = DpSize((49 + 23 + 6).dp, 24.dp), @@ -242,6 +259,7 @@ public fun DropdownMetrics.Companion.default( borderWidth: Dp = 1.dp, ): DropdownMetrics = DropdownMetrics(arrowMinSize, minSize, cornerSize, contentPadding, borderWidth) +/** Creates an Int UI undecorated [DropdownMetrics] with the provided parameters. */ public fun DropdownMetrics.Companion.undecorated( arrowMinSize: DpSize = DpSize((23 + 3).dp, 24.dp), minSize: DpSize = DpSize((49 + 23 + 6).dp, 24.dp), @@ -250,5 +268,6 @@ public fun DropdownMetrics.Companion.undecorated( borderWidth: Dp = 0.dp, ): DropdownMetrics = DropdownMetrics(arrowMinSize, minSize, cornerSize, contentPadding, borderWidth) +/** Creates an Int UI default [DropdownIcons] with the provided parameters. */ public fun DropdownIcons.Companion.defaults(chevronDown: IconKey = AllIconsKeys.General.ChevronDown): DropdownIcons = DropdownIcons(chevronDown) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiGroupHeaderStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiGroupHeaderStyling.kt index eb7333c126df..3e4590d89eaa 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiGroupHeaderStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiGroupHeaderStyling.kt @@ -9,21 +9,26 @@ import org.jetbrains.jewel.ui.component.styling.GroupHeaderColors import org.jetbrains.jewel.ui.component.styling.GroupHeaderMetrics import org.jetbrains.jewel.ui.component.styling.GroupHeaderStyle +/** Creates an Int UI light [GroupHeaderStyle] with the provided parameters. */ public fun GroupHeaderStyle.Companion.light( colors: GroupHeaderColors = GroupHeaderColors.light(), metrics: GroupHeaderMetrics = GroupHeaderMetrics.defaults(), ): GroupHeaderStyle = GroupHeaderStyle(colors, metrics) +/** Creates an Int UI dark [GroupHeaderStyle] with the provided parameters. */ public fun GroupHeaderStyle.Companion.dark( colors: GroupHeaderColors = GroupHeaderColors.dark(), metrics: GroupHeaderMetrics = GroupHeaderMetrics.defaults(), ): GroupHeaderStyle = GroupHeaderStyle(colors, metrics) +/** Creates an Int UI light [GroupHeaderColors] with the provided parameters. */ public fun GroupHeaderColors.Companion.light(divider: Color = IntUiLightTheme.colors.gray(12)): GroupHeaderColors = GroupHeaderColors(divider) +/** Creates an Int UI dark [GroupHeaderColors] with the provided parameters. */ public fun GroupHeaderColors.Companion.dark(divider: Color = IntUiDarkTheme.colors.gray(3)): GroupHeaderColors = GroupHeaderColors(divider) +/** Creates an Int UI default [GroupHeaderMetrics] with the provided parameters. */ public fun GroupHeaderMetrics.Companion.defaults(dividerThickness: Dp = 1.dp, indent: Dp = 8.dp): GroupHeaderMetrics = GroupHeaderMetrics(dividerThickness, indent) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiHorizontalProgressBarStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiHorizontalProgressBarStyling.kt index 8bed179be6b2..438b5e783864 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiHorizontalProgressBarStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiHorizontalProgressBarStyling.kt @@ -12,18 +12,21 @@ import org.jetbrains.jewel.ui.component.styling.HorizontalProgressBarColors import org.jetbrains.jewel.ui.component.styling.HorizontalProgressBarMetrics import org.jetbrains.jewel.ui.component.styling.HorizontalProgressBarStyle +/** Creates an Int UI light [HorizontalProgressBarStyle] with the provided parameters. */ public fun HorizontalProgressBarStyle.Companion.light( colors: HorizontalProgressBarColors = HorizontalProgressBarColors.light(), metrics: HorizontalProgressBarMetrics = HorizontalProgressBarMetrics.defaults(), indeterminateCycleDuration: Duration = 800.milliseconds, ): HorizontalProgressBarStyle = HorizontalProgressBarStyle(colors, metrics, indeterminateCycleDuration) +/** Creates an Int UI dark [HorizontalProgressBarStyle] with the provided parameters. */ public fun HorizontalProgressBarStyle.Companion.dark( colors: HorizontalProgressBarColors = HorizontalProgressBarColors.dark(), metrics: HorizontalProgressBarMetrics = HorizontalProgressBarMetrics.defaults(), indeterminateCycleDuration: Duration = 800.milliseconds, ): HorizontalProgressBarStyle = HorizontalProgressBarStyle(colors, metrics, indeterminateCycleDuration) +/** Creates an Int UI light [HorizontalProgressBarColors] with the provided parameters. */ public fun HorizontalProgressBarColors.Companion.light( track: Color = IntUiLightTheme.colors.gray(11), progress: Color = IntUiLightTheme.colors.blue(4), @@ -37,6 +40,7 @@ public fun HorizontalProgressBarColors.Companion.light( indeterminateHighlight = indeterminateHighlight, ) +/** Creates an Int UI dark [HorizontalProgressBarColors] with the provided parameters. */ public fun HorizontalProgressBarColors.Companion.dark( track: Color = IntUiDarkTheme.colors.gray(4), progress: Color = IntUiDarkTheme.colors.blue(7), @@ -50,6 +54,7 @@ public fun HorizontalProgressBarColors.Companion.dark( indeterminateHighlight = indeterminateHighlight, ) +/** Creates an Int UI default [HorizontalProgressBarMetrics] with the provided parameters. */ public fun HorizontalProgressBarMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(100), minHeight: Dp = 4.dp, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt index a8f45a0f2b37..f7439b583e82 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiIconButtonStyling.kt @@ -14,16 +14,19 @@ import org.jetbrains.jewel.ui.component.styling.IconButtonColors import org.jetbrains.jewel.ui.component.styling.IconButtonMetrics import org.jetbrains.jewel.ui.component.styling.IconButtonStyle +/** Creates an Int UI light [IconButtonStyle] with the provided parameters. */ public fun IconButtonStyle.Companion.light( colors: IconButtonColors = IconButtonColors.light(), metrics: IconButtonMetrics = IconButtonMetrics.defaults(), ): IconButtonStyle = IconButtonStyle(colors, metrics) +/** Creates an Int UI dark [IconButtonStyle] with the provided parameters. */ public fun IconButtonStyle.Companion.dark( colors: IconButtonColors = IconButtonColors.dark(), metrics: IconButtonMetrics = IconButtonMetrics.defaults(), ): IconButtonStyle = IconButtonStyle(colors, metrics) +/** Creates an Int UI light [IconButtonStyle] with a fully transparent background. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun IconButtonStyle.Companion.lightTransparentBackground( @@ -31,6 +34,7 @@ public fun IconButtonStyle.Companion.lightTransparentBackground( metrics: IconButtonMetrics = IconButtonMetrics.defaults(), ): IconButtonStyle = IconButtonStyle(colors, metrics) +/** Creates an Int UI dark [IconButtonStyle] with a fully transparent background. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun IconButtonStyle.Companion.darkTransparentBackground( @@ -38,6 +42,7 @@ public fun IconButtonStyle.Companion.darkTransparentBackground( metrics: IconButtonMetrics = IconButtonMetrics.defaults(), ): IconButtonStyle = IconButtonStyle(colors, metrics) +/** Creates an Int UI light [IconButtonColors] with the provided parameters. */ public fun IconButtonColors.Companion.light( foregroundSelectedActivated: Color = IntUiLightTheme.colors.gray(14), background: Color = Color.Unspecified, @@ -73,6 +78,7 @@ public fun IconButtonColors.Companion.light( borderHovered = borderHovered, ) +/** Creates an Int UI light [IconButtonColors] with a fully transparent background. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun IconButtonColors.Companion.lightTransparentBackground( @@ -96,6 +102,7 @@ public fun IconButtonColors.Companion.lightTransparentBackground( borderHovered = Color.Transparent, ) +/** Creates an Int UI dark [IconButtonColors] with the provided parameters. */ public fun IconButtonColors.Companion.dark( foregroundSelectedActivated: Color = IntUiDarkTheme.colors.gray(14), background: Color = Color.Unspecified, @@ -131,6 +138,7 @@ public fun IconButtonColors.Companion.dark( borderHovered = borderHovered, ) +/** Creates an Int UI dark [IconButtonColors] with a fully transparent background. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun IconButtonColors.Companion.darkTransparentBackground( @@ -154,6 +162,7 @@ public fun IconButtonColors.Companion.darkTransparentBackground( borderHovered = Color.Transparent, ) +/** Creates an Int UI default [IconButtonMetrics] with the provided parameters. */ public fun IconButtonMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(4.dp), borderWidth: Dp = 1.dp, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLazyTreeStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLazyTreeStyling.kt index 63907a8bcd87..132d94f983be 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLazyTreeStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLazyTreeStyling.kt @@ -19,7 +19,9 @@ import org.jetbrains.jewel.ui.icons.AllIconsKeys private val SimpleListItemStyle.Companion.LazyTree: IntUiDefaultSimpleListItemLazyTreeStyleFactory get() = IntUiDefaultSimpleListItemLazyTreeStyleFactory +/** Factory object for creating Int UI [SimpleListItemColors] instances for lazy tree nodes. */ public object IntUiDefaultSimpleListItemLazyTreeStyleFactory { + /** Creates an Int UI light [SimpleListItemColors] for lazy tree nodes with the provided parameters. */ public fun light( content: Color = Color.Unspecified, contentActive: Color = content, @@ -41,6 +43,7 @@ public object IntUiDefaultSimpleListItemLazyTreeStyleFactory { contentSelectedActive = contentSelectedActive, ) + /** Creates an Int UI dark [SimpleListItemColors] for lazy tree nodes with the provided parameters. */ public fun dark( content: Color = Color.Unspecified, contentActive: Color = content, @@ -63,18 +66,21 @@ public object IntUiDefaultSimpleListItemLazyTreeStyleFactory { ) } +/** Creates an Int UI light [LazyTreeStyle] with the provided parameters. */ public fun LazyTreeStyle.Companion.light( colors: SimpleListItemColors = SimpleListItemStyle.LazyTree.light(), metrics: LazyTreeMetrics = LazyTreeMetrics.defaults(), icons: LazyTreeIcons = LazyTreeIcons.defaults(), ): LazyTreeStyle = LazyTreeStyle(colors, metrics, icons) +/** Creates an Int UI dark [LazyTreeStyle] with the provided parameters. */ public fun LazyTreeStyle.Companion.dark( colors: SimpleListItemColors = SimpleListItemStyle.LazyTree.dark(), metrics: LazyTreeMetrics = LazyTreeMetrics.defaults(), icons: LazyTreeIcons = LazyTreeIcons.defaults(), ): LazyTreeStyle = LazyTreeStyle(colors, metrics, icons) +/** Creates an Int UI default [LazyTreeMetrics] with the provided parameters. */ public fun LazyTreeMetrics.Companion.defaults( indentSize: Dp = 7.dp + 16.dp, elementBackgroundCornerSize: CornerSize = CornerSize(2.dp), @@ -97,6 +103,7 @@ public fun LazyTreeMetrics.Companion.defaults( ), ) +/** Creates an Int UI default [LazyTreeIcons] with the provided parameters. */ public fun LazyTreeIcons.Companion.defaults( chevronCollapsed: IconKey = AllIconsKeys.General.ChevronRight, chevronExpanded: IconKey = AllIconsKeys.General.ChevronDown, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLinkStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLinkStyling.kt index 37ed55f5e599..3ee7bd7b99dd 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLinkStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiLinkStyling.kt @@ -15,6 +15,7 @@ import org.jetbrains.jewel.ui.component.styling.LinkUnderlineBehavior import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Creates an Int UI light [LinkStyle] with the provided parameters. */ public fun LinkStyle.Companion.light( colors: LinkColors = LinkColors.light(), metrics: LinkMetrics = LinkMetrics.defaults(), @@ -22,6 +23,7 @@ public fun LinkStyle.Companion.light( underlineBehavior: LinkUnderlineBehavior = LinkUnderlineBehavior.ShowOnHover, ): LinkStyle = LinkStyle(colors, metrics, icons, underlineBehavior) +/** Creates an Int UI dark [LinkStyle] with the provided parameters. */ public fun LinkStyle.Companion.dark( colors: LinkColors = LinkColors.dark(), metrics: LinkMetrics = LinkMetrics.defaults(), @@ -29,6 +31,7 @@ public fun LinkStyle.Companion.dark( underlineBehavior: LinkUnderlineBehavior = LinkUnderlineBehavior.ShowOnHover, ): LinkStyle = LinkStyle(colors, metrics, icons, underlineBehavior) +/** Creates an Int UI light [LinkColors] with the provided parameters. */ public fun LinkColors.Companion.light( content: Color = IntUiLightTheme.colors.blue(2), contentDisabled: Color = IntUiLightTheme.colors.gray(8), @@ -46,6 +49,7 @@ public fun LinkColors.Companion.light( contentVisited = contentVisited, ) +/** Creates an Int UI dark [LinkColors] with the provided parameters. */ public fun LinkColors.Companion.dark( content: Color = IntUiDarkTheme.colors.blue(9), contentDisabled: Color = IntUiDarkTheme.colors.gray(7), @@ -63,12 +67,14 @@ public fun LinkColors.Companion.dark( contentVisited = contentVisited, ) +/** Creates an Int UI default [LinkMetrics] with the provided parameters. */ public fun LinkMetrics.Companion.defaults( focusHaloCornerSize: CornerSize = CornerSize(2.dp), textIconGap: Dp = 0.dp, iconSize: DpSize = DpSize(16.dp, 16.dp), ): LinkMetrics = LinkMetrics(focusHaloCornerSize, textIconGap, iconSize) +/** Creates an Int UI default [LinkIcons] with the provided parameters. */ public fun LinkIcons.Companion.defaults( dropdownChevron: IconKey = AllIconsKeys.General.ChevronDown, externalLink: IconKey = AllIconsKeys.Ide.External_link_arrow, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiMenuStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiMenuStyling.kt index 7a9b290b00d6..15b02f748b9c 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiMenuStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiMenuStyling.kt @@ -18,18 +18,21 @@ import org.jetbrains.jewel.ui.component.styling.SubmenuMetrics import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Creates an Int UI light [MenuStyle] with the provided parameters. */ public fun MenuStyle.Companion.light( colors: MenuColors = MenuColors.light(), metrics: MenuMetrics = MenuMetrics.defaults(), icons: MenuIcons = MenuIcons.defaults(), ): MenuStyle = MenuStyle(isDark = false, colors, metrics, icons) +/** Creates an Int UI dark [MenuStyle] with the provided parameters. */ public fun MenuStyle.Companion.dark( colors: MenuColors = MenuColors.dark(), metrics: MenuMetrics = MenuMetrics.defaults(), icons: MenuIcons = MenuIcons.defaults(), ): MenuStyle = MenuStyle(isDark = true, colors, metrics, icons) +/** Creates an Int UI light [MenuColors] with the provided parameters. */ public fun MenuColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), border: Color = IntUiLightTheme.colors.gray(9), @@ -37,6 +40,7 @@ public fun MenuColors.Companion.light( itemColors: MenuItemColors = MenuItemColors.light(), ): MenuColors = MenuColors(background = background, border = border, shadow = shadow, itemColors = itemColors) +/** Creates an Int UI dark [MenuColors] with the provided parameters. */ public fun MenuColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), border: Color = IntUiDarkTheme.colors.gray(3), @@ -44,6 +48,7 @@ public fun MenuColors.Companion.dark( itemColors: MenuItemColors = MenuItemColors.dark(), ): MenuColors = MenuColors(background = background, border = border, shadow = shadow, itemColors = itemColors) +/** Creates an Int UI light [MenuItemColors] with the provided parameters. */ public fun MenuItemColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), backgroundDisabled: Color = IntUiLightTheme.colors.gray(14), @@ -91,6 +96,7 @@ public fun MenuItemColors.Companion.light( separator = separator, ) +/** Creates an Int UI dark [MenuItemColors] with the provided parameters. */ public fun MenuItemColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), backgroundDisabled: Color = IntUiDarkTheme.colors.gray(2), @@ -138,6 +144,7 @@ public fun MenuItemColors.Companion.dark( keybindingTintHovered = keybindingTintHovered, ) +/** Creates an Int UI default [MenuMetrics] with the provided parameters. */ public fun MenuMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(8.dp), menuMargin: PaddingValues = PaddingValues(vertical = 6.dp), @@ -150,6 +157,7 @@ public fun MenuMetrics.Companion.defaults( ): MenuMetrics = MenuMetrics(cornerSize, menuMargin, contentPadding, offset, shadowSize, borderWidth, itemMetrics, submenuMetrics) +/** Creates an Int UI default [MenuItemMetrics] with the provided parameters. */ public fun MenuItemMetrics.Companion.defaults( selectionCornerSize: CornerSize = CornerSize(4.dp), outerPadding: PaddingValues = PaddingValues(horizontal = 6.dp), @@ -173,8 +181,10 @@ public fun MenuItemMetrics.Companion.defaults( minHeight, ) +/** Creates an Int UI default [SubmenuMetrics] with the provided parameters. */ public fun SubmenuMetrics.Companion.defaults(offset: DpOffset = DpOffset(0.dp, (-8).dp)): SubmenuMetrics = SubmenuMetrics(offset) +/** Creates an Int UI default [MenuIcons] with the provided parameters. */ public fun MenuIcons.Companion.defaults(submenuChevron: IconKey = AllIconsKeys.General.ChevronRight): MenuIcons = MenuIcons(submenuChevron) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupAdStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupAdStyling.kt index 15c683d8c2a1..39a2ae0ff898 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupAdStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupAdStyling.kt @@ -10,28 +10,34 @@ import org.jetbrains.jewel.ui.component.styling.PopupAdColors import org.jetbrains.jewel.ui.component.styling.PopupAdMetrics import org.jetbrains.jewel.ui.component.styling.PopupAdStyle +/** Creates an Int UI light [PopupAdStyle] with the provided parameters. */ public fun PopupAdStyle.Companion.light( colors: PopupAdColors = PopupAdColors.light(), metrics: PopupAdMetrics = PopupAdMetrics.light(), ): PopupAdStyle = PopupAdStyle(colors = colors, metrics = metrics) +/** Creates an Int UI light [PopupAdColors] with the provided parameters. */ public fun PopupAdColors.Companion.light(background: Color = Color(0xFFF2F2F2)): PopupAdColors = PopupAdColors(background = background) +/** Creates an Int UI light [PopupAdMetrics] with the provided parameters. */ public fun PopupAdMetrics.Companion.light( padding: PaddingValues = PaddingValues(horizontal = 20.dp, vertical = 6.dp), minHeight: Dp = 20.dp, ): PopupAdMetrics = PopupAdMetrics(padding = padding, minHeight = minHeight) +/** Creates an Int UI dark [PopupAdStyle] with the provided parameters. */ public fun PopupAdStyle.Companion.dark( colors: PopupAdColors = PopupAdColors.dark(), metrics: PopupAdMetrics = PopupAdMetrics.dark(), ): PopupAdStyle = PopupAdStyle(colors = colors, metrics = metrics) +/** Creates an Int UI dark [PopupAdColors] with the provided parameters. */ public fun PopupAdColors.Companion.dark( background: Color = IntUiDarkTheme.colors.grayOrNull(2) ?: Color(0xFF2B2B2B) ): PopupAdColors = PopupAdColors(background = background) +/** Creates an Int UI dark [PopupAdMetrics] with the provided parameters. */ public fun PopupAdMetrics.Companion.dark( padding: PaddingValues = PaddingValues(horizontal = 20.dp, vertical = 6.dp), minHeight: Dp = 20.dp, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupContainerStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupContainerStyling.kt index 69a87b4f7e65..86d30fdcc1b7 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupContainerStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiPopupContainerStyling.kt @@ -12,28 +12,33 @@ import org.jetbrains.jewel.ui.component.styling.PopupContainerColors import org.jetbrains.jewel.ui.component.styling.PopupContainerMetrics import org.jetbrains.jewel.ui.component.styling.PopupContainerStyle +/** Creates an Int UI light [PopupContainerStyle] with the provided parameters. */ public fun PopupContainerStyle.Companion.light( colors: PopupContainerColors = PopupContainerColors.light(), metrics: PopupContainerMetrics = PopupContainerMetrics.defaults(), ): PopupContainerStyle = PopupContainerStyle(isDark = false, colors, metrics) +/** Creates an Int UI dark [PopupContainerStyle] with the provided parameters. */ public fun PopupContainerStyle.Companion.dark( colors: PopupContainerColors = PopupContainerColors.dark(), metrics: PopupContainerMetrics = PopupContainerMetrics.defaults(), ): PopupContainerStyle = PopupContainerStyle(isDark = true, colors, metrics) +/** Creates an Int UI light [PopupContainerColors] with the provided parameters. */ public fun PopupContainerColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), border: Color = IntUiLightTheme.colors.gray(9), shadow: Color = Color(0x78919191), // Not a palette color ): PopupContainerColors = PopupContainerColors(background = background, border = border, shadow = shadow) +/** Creates an Int UI dark [PopupContainerColors] with the provided parameters. */ public fun PopupContainerColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), border: Color = IntUiDarkTheme.colors.gray(3), shadow: Color = Color(0x66000000), // Not a palette color ): PopupContainerColors = PopupContainerColors(background = background, border = border, shadow = shadow) +/** Creates an Int UI default [PopupContainerMetrics] with the provided parameters. */ public fun PopupContainerMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(8.dp), menuMargin: PaddingValues = PaddingValues(vertical = 6.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt index 4fda03a8b5fb..25437bde04ec 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt @@ -13,18 +13,21 @@ import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icon.PathIconKey +/** Creates an Int UI light [RadioButtonStyle] with the provided parameters. */ public fun RadioButtonStyle.Companion.light( colors: RadioButtonColors = RadioButtonColors.light(), metrics: RadioButtonMetrics = RadioButtonMetrics.defaults(), icons: RadioButtonIcons = RadioButtonIcons.light(), ): RadioButtonStyle = RadioButtonStyle(colors, metrics, icons) +/** Creates an Int UI dark [RadioButtonStyle] with the provided parameters. */ public fun RadioButtonStyle.Companion.dark( colors: RadioButtonColors = RadioButtonColors.dark(), metrics: RadioButtonMetrics = RadioButtonMetrics.defaults(), icons: RadioButtonIcons = RadioButtonIcons.dark(), ): RadioButtonStyle = RadioButtonStyle(colors, metrics, icons) +/** Creates an Int UI light [RadioButtonColors] with the provided parameters. */ public fun RadioButtonColors.Companion.light( content: Color = Color.Unspecified, contentHovered: Color = content, @@ -42,6 +45,7 @@ public fun RadioButtonColors.Companion.light( contentSelectedDisabled = contentSelectedDisabled, ) +/** Creates an Int UI dark [RadioButtonColors] with the provided parameters. */ public fun RadioButtonColors.Companion.dark( content: Color = Color.Unspecified, contentHovered: Color = content, @@ -59,6 +63,7 @@ public fun RadioButtonColors.Companion.dark( contentSelectedDisabled = contentSelectedDisabled, ) +/** Creates an Int UI default [RadioButtonMetrics] with the provided parameters. */ public fun RadioButtonMetrics.Companion.defaults( radioButtonSize: DpSize = DpSize(24.dp, 24.dp), outlineSize: DpSize = DpSize(17.dp, 17.dp), @@ -76,11 +81,13 @@ public fun RadioButtonMetrics.Companion.defaults( iconContentGap = iconContentGap, ) +/** Creates an Int UI light [RadioButtonIcons] with the provided parameters. */ public fun RadioButtonIcons.Companion.light( radioButton: IconKey = PathIconKey(path = "com/intellij/ide/ui/laf/icons/intellij/radio.svg", iconClass = RadioButtonIcons::class.java) ): RadioButtonIcons = RadioButtonIcons(radioButton) +/** Creates an Int UI dark [RadioButtonIcons] with the provided parameters. */ public fun RadioButtonIcons.Companion.dark( radioButton: IconKey = PathIconKey(path = "com/intellij/ide/ui/laf/icons/darcula/radio.svg", iconClass = RadioButtonIcons::class.java) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSearchMatchStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSearchMatchStyling.kt index 67c7c3deaa3c..8dbe0a4ed91a 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSearchMatchStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSearchMatchStyling.kt @@ -11,16 +11,19 @@ import org.jetbrains.jewel.ui.component.styling.SearchMatchColors import org.jetbrains.jewel.ui.component.styling.SearchMatchMetrics import org.jetbrains.jewel.ui.component.styling.SearchMatchStyle +/** Creates an Int UI light [SearchMatchStyle] with the provided parameters. */ public fun SearchMatchStyle.Companion.light( colors: SearchMatchColors = SearchMatchColors.light(), metrics: SearchMatchMetrics = SearchMatchMetrics.default(), ): SearchMatchStyle = SearchMatchStyle(colors, metrics) +/** Creates an Int UI dark [SearchMatchStyle] with the provided parameters. */ public fun SearchMatchStyle.Companion.dark( colors: SearchMatchColors = SearchMatchColors.dark(), metrics: SearchMatchMetrics = SearchMatchMetrics.default(), ): SearchMatchStyle = SearchMatchStyle(colors, metrics) +/** Creates an Int UI light [SearchMatchColors] with the provided parameters. */ public fun SearchMatchColors.Companion.light( startBackground: Color = IntUiLightTheme.colors.yellow(7), endBackground: Color = IntUiLightTheme.colors.yellow(7), @@ -28,6 +31,7 @@ public fun SearchMatchColors.Companion.light( ): SearchMatchColors = SearchMatchColors(startBackground = startBackground, endBackground = endBackground, foreground = foreground) +/** Creates an Int UI dark [SearchMatchColors] with the provided parameters. */ public fun SearchMatchColors.Companion.dark( startBackground: Color = IntUiDarkTheme.colors.yellow(5), endBackground: Color = IntUiDarkTheme.colors.yellow(5), @@ -35,6 +39,7 @@ public fun SearchMatchColors.Companion.dark( ): SearchMatchColors = SearchMatchColors(startBackground = startBackground, endBackground = endBackground, foreground = foreground) +/** Creates an Int UI default [SearchMatchMetrics] with the provided parameters. */ public fun SearchMatchMetrics.Companion.default( cornerSize: CornerSize = CornerSize(2.5.dp), padding: PaddingValues = PaddingValues(2.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlButtonStyling.kt index 8b6cf325224a..33e301c36c03 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlButtonStyling.kt @@ -14,16 +14,19 @@ import org.jetbrains.jewel.ui.component.styling.SegmentedControlButtonColors import org.jetbrains.jewel.ui.component.styling.SegmentedControlButtonMetrics import org.jetbrains.jewel.ui.component.styling.SegmentedControlButtonStyle +/** Creates an Int UI light [SegmentedControlButtonStyle] with the provided parameters. */ public fun SegmentedControlButtonStyle.Companion.light( colors: SegmentedControlButtonColors = SegmentedControlButtonColors.light(), metrics: SegmentedControlButtonMetrics = SegmentedControlButtonMetrics.defaults(), ): SegmentedControlButtonStyle = SegmentedControlButtonStyle(colors, metrics) +/** Creates an Int UI dark [SegmentedControlButtonStyle] with the provided parameters. */ public fun SegmentedControlButtonStyle.Companion.dark( colors: SegmentedControlButtonColors = SegmentedControlButtonColors.dark(), metrics: SegmentedControlButtonMetrics = SegmentedControlButtonMetrics.defaults(), ): SegmentedControlButtonStyle = SegmentedControlButtonStyle(colors, metrics) +/** Creates an Int UI light [SegmentedControlButtonColors] with the provided parameters. */ public fun SegmentedControlButtonColors.Companion.light( background: Brush = SolidColor(Color.Transparent), backgroundPressed: Brush = SolidColor(IntUiLightTheme.colors.gray(14)), @@ -51,6 +54,7 @@ public fun SegmentedControlButtonColors.Companion.light( borderSelectedFocused = borderSelectedFocused, ) +/** Creates an Int UI dark [SegmentedControlButtonColors] with the provided parameters. */ public fun SegmentedControlButtonColors.Companion.dark( background: Brush = SolidColor(Color.Transparent), backgroundPressed: Brush = SolidColor(IntUiDarkTheme.colors.gray(3)), @@ -78,6 +82,7 @@ public fun SegmentedControlButtonColors.Companion.dark( borderSelectedFocused = borderSelectedFocused, ) +/** Creates an Int UI default [SegmentedControlButtonMetrics] with the provided parameters. */ public fun SegmentedControlButtonMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(3.dp), segmentedButtonPadding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 6.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlStyling.kt index 24b90d9928c8..11db4feff336 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlStyling.kt @@ -12,16 +12,19 @@ import org.jetbrains.jewel.ui.component.styling.SegmentedControlColors import org.jetbrains.jewel.ui.component.styling.SegmentedControlMetrics import org.jetbrains.jewel.ui.component.styling.SegmentedControlStyle +/** Creates an Int UI light [SegmentedControlStyle] with the provided parameters. */ public fun SegmentedControlStyle.Companion.light( colors: SegmentedControlColors = SegmentedControlColors.light(), metrics: SegmentedControlMetrics = SegmentedControlMetrics.defaults(), ): SegmentedControlStyle = SegmentedControlStyle(colors, metrics) +/** Creates an Int UI dark [SegmentedControlStyle] with the provided parameters. */ public fun SegmentedControlStyle.Companion.dark( colors: SegmentedControlColors = SegmentedControlColors.dark(), metrics: SegmentedControlMetrics = SegmentedControlMetrics.defaults(), ): SegmentedControlStyle = SegmentedControlStyle(colors, metrics) +/** Creates an Int UI light [SegmentedControlColors] with the provided parameters. */ public fun SegmentedControlColors.Companion.light( border: Brush = SolidColor(IntUiLightTheme.colors.gray(9)), borderDisabled: Brush = SolidColor(IntUiLightTheme.colors.gray(11)), @@ -37,6 +40,7 @@ public fun SegmentedControlColors.Companion.light( borderFocused = borderFocused, ) +/** Creates an Int UI dark [SegmentedControlColors] with the provided parameters. */ public fun SegmentedControlColors.Companion.dark( border: Brush = SolidColor(IntUiDarkTheme.colors.gray(5)), borderDisabled: Brush = SolidColor(IntUiDarkTheme.colors.gray(4)), @@ -52,6 +56,7 @@ public fun SegmentedControlColors.Companion.dark( borderFocused = borderFocused, ) +/** Creates an Int UI default [SegmentedControlMetrics] with the provided parameters. */ public fun SegmentedControlMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(3.dp), borderWidth: Dp = 1.dp, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSelectableLazyColumnStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSelectableLazyColumnStyling.kt index 379595f76ada..0ca6c8dbc996 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSelectableLazyColumnStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSelectableLazyColumnStyling.kt @@ -7,12 +7,14 @@ import org.jetbrains.jewel.ui.component.styling.SimpleListItemColors import org.jetbrains.jewel.ui.component.styling.SimpleListItemMetrics import org.jetbrains.jewel.ui.component.styling.SimpleListItemStyle +/** Creates an Int UI light [SelectableLazyColumnStyle] with the provided parameters. */ public fun SelectableLazyColumnStyle.Companion.light( itemHeight: Dp = 24.dp, itemColors: SimpleListItemColors = SimpleListItemColors.light(), itemMetrics: SimpleListItemMetrics = SimpleListItemMetrics.default(), ): SelectableLazyColumnStyle = SelectableLazyColumnStyle(itemHeight, SimpleListItemStyle(itemColors, itemMetrics)) +/** Creates an Int UI dark [SelectableLazyColumnStyle] with the provided parameters. */ public fun SelectableLazyColumnStyle.Companion.dark( itemHeight: Dp = 24.dp, itemColors: SimpleListItemColors = SimpleListItemColors.dark(), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSimpleListItemStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSimpleListItemStyling.kt index c95f61a2bbfb..ed1d27b79dda 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSimpleListItemStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSimpleListItemStyling.kt @@ -13,33 +13,43 @@ import org.jetbrains.jewel.ui.component.styling.SimpleListItemColors import org.jetbrains.jewel.ui.component.styling.SimpleListItemMetrics import org.jetbrains.jewel.ui.component.styling.SimpleListItemStyle +/** Creates an Int UI default [SimpleListItemStyle], choosing between light and dark based on the current theme. */ @Composable public fun SimpleListItemStyle.Companion.default(): SimpleListItemStyle = if (JewelTheme.isDark) dark() else light() +/** Creates an Int UI light [SimpleListItemStyle] with the provided parameters. */ public fun SimpleListItemStyle.Companion.light( colors: SimpleListItemColors = SimpleListItemColors.light(), metrics: SimpleListItemMetrics = SimpleListItemMetrics.default(), ): SimpleListItemStyle = SimpleListItemStyle(colors, metrics) +/** Creates an Int UI dark [SimpleListItemStyle] with the provided parameters. */ public fun SimpleListItemStyle.Companion.dark( colors: SimpleListItemColors = SimpleListItemColors.dark(), metrics: SimpleListItemMetrics = SimpleListItemMetrics.default(), ): SimpleListItemStyle = SimpleListItemStyle(colors, metrics) +/** + * Creates an Int UI full-width default [SimpleListItemStyle], choosing between light and dark based on the current + * theme. + */ @Composable public fun SimpleListItemStyle.Companion.fullWidth(): SimpleListItemStyle = if (JewelTheme.isDark) darkFullWidth() else lightFullWidth() +/** Creates an Int UI light full-width [SimpleListItemStyle] with the provided parameters. */ public fun SimpleListItemStyle.Companion.lightFullWidth( colors: SimpleListItemColors = SimpleListItemColors.light(), metrics: SimpleListItemMetrics = SimpleListItemMetrics.fullWidth(), ): SimpleListItemStyle = SimpleListItemStyle(colors, metrics) +/** Creates an Int UI dark full-width [SimpleListItemStyle] with the provided parameters. */ public fun SimpleListItemStyle.Companion.darkFullWidth( colors: SimpleListItemColors = SimpleListItemColors.dark(), metrics: SimpleListItemMetrics = SimpleListItemMetrics.fullWidth(), ): SimpleListItemStyle = SimpleListItemStyle(colors, metrics) +/** Creates an Int UI light [SimpleListItemColors] with the provided parameters. */ public fun SimpleListItemColors.Companion.light( background: Color = Color.Unspecified, backgroundActive: Color = background, @@ -61,6 +71,7 @@ public fun SimpleListItemColors.Companion.light( contentSelectedActive = contentSelectedActive, ) +/** Creates an Int UI dark [SimpleListItemColors] with the provided parameters. */ public fun SimpleListItemColors.Companion.dark( background: Color = Color.Unspecified, backgroundActive: Color = background, @@ -82,6 +93,7 @@ public fun SimpleListItemColors.Companion.dark( contentSelectedActive = contentSelectedActive, ) +/** Creates an Int UI default [SimpleListItemMetrics] with the provided parameters. */ public fun SimpleListItemMetrics.Companion.default( innerPadding: PaddingValues = PaddingValues(horizontal = 6.dp, vertical = 2.dp), outerPadding: PaddingValues = PaddingValues(horizontal = 7.dp, vertical = 1.dp), @@ -89,6 +101,7 @@ public fun SimpleListItemMetrics.Companion.default( iconTextGap: Dp = 3.dp, ): SimpleListItemMetrics = SimpleListItemMetrics(innerPadding, outerPadding, selectionBackgroundCornerSize, iconTextGap) +/** Creates an Int UI full-width [SimpleListItemMetrics] with the provided parameters. */ public fun SimpleListItemMetrics.Companion.fullWidth( innerPadding: PaddingValues = PaddingValues(horizontal = 6.dp, vertical = 2.dp), outerPadding: PaddingValues = PaddingValues(), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSliderStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSliderStyling.kt index d2c446b614bb..0242c2ca9604 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSliderStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSliderStyling.kt @@ -12,18 +12,21 @@ import org.jetbrains.jewel.ui.component.styling.SliderColors import org.jetbrains.jewel.ui.component.styling.SliderMetrics import org.jetbrains.jewel.ui.component.styling.SliderStyle +/** Creates an Int UI light [SliderStyle] with the provided parameters. */ public fun SliderStyle.Companion.light( colors: SliderColors = SliderColors.light(), metrics: SliderMetrics = SliderMetrics.defaults(), thumbShape: Shape = CircleShape, ): SliderStyle = SliderStyle(colors, metrics, thumbShape) +/** Creates an Int UI dark [SliderStyle] with the provided parameters. */ public fun SliderStyle.Companion.dark( colors: SliderColors = SliderColors.dark(), metrics: SliderMetrics = SliderMetrics.defaults(), thumbShape: Shape = CircleShape, ): SliderStyle = SliderStyle(colors, metrics, thumbShape) +/** Creates an Int UI light [SliderColors] with the provided parameters. */ public fun SliderColors.Companion.light( track: Color = IntUiLightTheme.colors.gray(10), trackFilled: Color = IntUiLightTheme.colors.blue(6), @@ -59,6 +62,7 @@ public fun SliderColors.Companion.light( thumbBorderHovered, ) +/** Creates an Int UI dark [SliderColors] with the provided parameters. */ public fun SliderColors.Companion.dark( track: Color = IntUiDarkTheme.colors.gray(4), trackFilled: Color = IntUiDarkTheme.colors.blue(7), @@ -94,6 +98,7 @@ public fun SliderColors.Companion.dark( thumbBorderHovered, ) +/** Creates an Int UI default [SliderMetrics] with the provided parameters. */ public fun SliderMetrics.Companion.defaults( trackHeight: Dp = 4.dp, thumbSize: DpSize = DpSize(14.dp, 14.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSpeedSearchStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSpeedSearchStyling.kt index 2adb5cc6eef8..2f953082f475 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSpeedSearchStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSpeedSearchStyling.kt @@ -12,18 +12,21 @@ import org.jetbrains.jewel.ui.component.styling.SpeedSearchMetrics import org.jetbrains.jewel.ui.component.styling.SpeedSearchStyle import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Creates an Int UI light [SpeedSearchStyle] with the provided parameters. */ public fun SpeedSearchStyle.Companion.light( colors: SpeedSearchColors = SpeedSearchColors.light(), metrics: SpeedSearchMetrics = SpeedSearchMetrics.defaults(), icons: SpeedSearchIcons = SpeedSearchIcons.defaults(), ): SpeedSearchStyle = SpeedSearchStyle(colors, metrics, icons) +/** Creates an Int UI dark [SpeedSearchStyle] with the provided parameters. */ public fun SpeedSearchStyle.Companion.dark( colors: SpeedSearchColors = SpeedSearchColors.dark(), metrics: SpeedSearchMetrics = SpeedSearchMetrics.defaults(), icons: SpeedSearchIcons = SpeedSearchIcons.defaults(), ): SpeedSearchStyle = SpeedSearchStyle(colors, metrics, icons) +/** Creates an Int UI light [SpeedSearchColors] with the provided parameters. */ public fun SpeedSearchColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), border: Color = IntUiLightTheme.colors.gray(12), @@ -31,6 +34,7 @@ public fun SpeedSearchColors.Companion.light( error: Color = IntUiLightTheme.colors.red(4), ): SpeedSearchColors = SpeedSearchColors(background, border, foreground, error) +/** Creates an Int UI dark [SpeedSearchColors] with the provided parameters. */ public fun SpeedSearchColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(1), border: Color = IntUiDarkTheme.colors.gray(3), @@ -38,6 +42,8 @@ public fun SpeedSearchColors.Companion.dark( error: Color = IntUiDarkTheme.colors.red(7), ): SpeedSearchColors = SpeedSearchColors(background, border, foreground, error) +/** Creates an Int UI default [SpeedSearchMetrics] with a default 4.dp padding. */ public fun SpeedSearchMetrics.Companion.defaults(): SpeedSearchMetrics = SpeedSearchMetrics(PaddingValues(4.dp)) +/** Creates an Int UI default [SpeedSearchIcons] using the default search icon. */ public fun SpeedSearchIcons.Companion.defaults(): SpeedSearchIcons = SpeedSearchIcons(AllIconsKeys.Actions.Search) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSplitButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSplitButtonStyling.kt index 282adb2799f7..7682a94d8b0d 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSplitButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiSplitButtonStyling.kt @@ -13,10 +13,13 @@ import org.jetbrains.jewel.ui.component.styling.SplitButtonColors import org.jetbrains.jewel.ui.component.styling.SplitButtonMetrics import org.jetbrains.jewel.ui.component.styling.SplitButtonStyle +/** The default [SplitButtonStyle] factory for the Int UI theme. */ public val SplitButtonStyle.Companion.Default: IntUiDefaultSplitButtonStyleFactory get() = IntUiDefaultSplitButtonStyleFactory +/** Factory object for creating Int UI default [SplitButtonStyle] instances. */ public object IntUiDefaultSplitButtonStyleFactory { + /** Creates an Int UI light default [SplitButtonStyle] with the provided parameters. */ public fun light( buttonStyle: ButtonStyle = ButtonStyle.Default.light(), dividerMetrics: DividerMetrics = DividerMetrics.defaults(), @@ -31,6 +34,7 @@ public object IntUiDefaultSplitButtonStyleFactory { colors = SplitButtonColors(dividerColor, dividerDisabledColor, chevronColor), ) + /** Creates an Int UI dark default [SplitButtonStyle] with the provided parameters. */ public fun dark( buttonStyle: ButtonStyle = ButtonStyle.Default.dark(), dividerMetrics: DividerMetrics = DividerMetrics.defaults(), @@ -46,10 +50,13 @@ public object IntUiDefaultSplitButtonStyleFactory { ) } +/** The outlined [SplitButtonStyle] factory for the Int UI theme. */ public val SplitButtonStyle.Companion.Outlined: IntUiOutlinedSplitButtonStyleFactory get() = IntUiOutlinedSplitButtonStyleFactory +/** Factory object for creating Int UI outlined [SplitButtonStyle] instances. */ public object IntUiOutlinedSplitButtonStyleFactory { + /** Creates an Int UI light outlined [SplitButtonStyle] with the provided parameters. */ public fun light( buttonStyle: ButtonStyle = ButtonStyle.Outlined.light(), dividerMetrics: DividerMetrics = DividerMetrics.defaults(), @@ -64,6 +71,7 @@ public object IntUiOutlinedSplitButtonStyleFactory { colors = SplitButtonColors(dividerColor, dividerDisabledColor, chevronColor), ) + /** Creates an Int UI dark outlined [SplitButtonStyle] with the provided parameters. */ public fun dark( buttonStyle: ButtonStyle = ButtonStyle.Outlined.dark(), dividerMetrics: DividerMetrics = DividerMetrics.defaults(), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStripScrollbarStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStripScrollbarStyling.kt index c5bcf0379c90..12f244189227 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStripScrollbarStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStripScrollbarStyling.kt @@ -16,6 +16,7 @@ import org.jetbrains.jewel.ui.component.styling.ScrollbarVisibility.WhenScrollin import org.jetbrains.jewel.ui.component.styling.TrackClickBehavior import org.jetbrains.skiko.hostOs +/** Creates an Int UI light [ScrollbarStyle] for the tab strip, selected based on the current OS. */ public fun ScrollbarStyle.Companion.tabStripLight(): ScrollbarStyle = if (hostOs.isMacOS) { ScrollbarStyle.tabStripMacOsLight() @@ -23,6 +24,7 @@ public fun ScrollbarStyle.Companion.tabStripLight(): ScrollbarStyle = ScrollbarStyle.tabStripWindowsAndLinuxLight() } +/** Creates an Int UI dark [ScrollbarStyle] for the tab strip, selected based on the current OS. */ public fun ScrollbarStyle.Companion.tabStripDark(): ScrollbarStyle = if (hostOs.isMacOS) { ScrollbarStyle.tabStripMacOsDark() @@ -86,6 +88,7 @@ public fun ScrollbarStyle.Companion.tabStripMacOsDark( }, ) +/** Creates an Int UI light [ScrollbarStyle] for the tab strip on Windows and Linux with the provided parameters. */ public fun ScrollbarStyle.Companion.tabStripWindowsAndLinuxLight( colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxLight(), metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripWindowsAndLinux(), @@ -99,6 +102,7 @@ public fun ScrollbarStyle.Companion.tabStripWindowsAndLinuxLight( scrollbarVisibility = scrollbarVisibility, ) +/** Creates an Int UI dark [ScrollbarStyle] for the tab strip on Windows and Linux with the provided parameters. */ public fun ScrollbarStyle.Companion.tabStripWindowsAndLinuxDark( colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxDark(), metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripWindowsAndLinux(), @@ -123,11 +127,13 @@ public fun ScrollbarMetrics.Companion.tabStripMacOs( minThumbLength: Dp = 20.dp, ): ScrollbarMetrics = ScrollbarMetrics(thumbCornerSize, minThumbLength) +/** Creates an Int UI default [ScrollbarMetrics] for the tab strip on Windows and Linux with the provided parameters. */ public fun ScrollbarMetrics.Companion.tabStripWindowsAndLinux( thumbCornerSize: CornerSize = CornerSize(0), minThumbLength: Dp = 20.dp, ): ScrollbarMetrics = ScrollbarMetrics(thumbCornerSize, minThumbLength) +/** Creates an Int UI default [ScrollbarVisibility.AlwaysVisible] for the tab strip with the provided parameters. */ @Deprecated( "Replace with 'ScrollbarVisibility.tabStrip()' version", ReplaceWith( diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt index 42188e08200c..45c8a1b99390 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt @@ -15,10 +15,13 @@ import org.jetbrains.jewel.ui.component.styling.TabStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** The factory for creating Int UI default [TabStyle] instances. */ public val TabStyle.Companion.Default: IntUiDefaultTabStyleFactory get() = IntUiDefaultTabStyleFactory +/** Factory object for creating Int UI default [TabStyle] instances. */ public object IntUiDefaultTabStyleFactory { + /** Creates an Int UI light default [TabStyle] with the provided parameters. */ public fun light( colors: TabColors = TabColors.Default.light(), metrics: TabMetrics = TabMetrics.defaults(), @@ -27,6 +30,7 @@ public object IntUiDefaultTabStyleFactory { scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripLight(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) + /** Creates an Int UI dark default [TabStyle] with the provided parameters. */ public fun dark( colors: TabColors = TabColors.Default.dark(), metrics: TabMetrics = TabMetrics.defaults(), @@ -36,10 +40,13 @@ public object IntUiDefaultTabStyleFactory { ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) } +/** The factory for creating Int UI editor [TabStyle] instances. */ public val TabStyle.Companion.Editor: IntUiEditorTabStyleFactory get() = IntUiEditorTabStyleFactory +/** Factory object for creating Int UI editor [TabStyle] instances. */ public object IntUiEditorTabStyleFactory { + /** Creates an Int UI light editor [TabStyle] with the provided parameters. */ public fun light( colors: TabColors = TabColors.Editor.light(), metrics: TabMetrics = TabMetrics.defaults(), @@ -48,6 +55,7 @@ public object IntUiEditorTabStyleFactory { scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripLight(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) + /** Creates an Int UI dark editor [TabStyle] with the provided parameters. */ public fun dark( colors: TabColors = TabColors.Editor.dark(), metrics: TabMetrics = TabMetrics.defaults(), @@ -57,10 +65,13 @@ public object IntUiEditorTabStyleFactory { ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) } +/** The factory for creating Int UI default [TabColors] instances. */ public val TabColors.Companion.Default: IntUiDefaultTabColorsFactory get() = IntUiDefaultTabColorsFactory +/** Factory object for creating Int UI default [TabColors] instances. */ public object IntUiDefaultTabColorsFactory { + /** Creates an Int UI light default [TabColors] with the provided parameters. */ public fun light( background: Color = IntUiLightTheme.colors.gray(14), backgroundHovered: Color = IntUiLightTheme.colors.gray(12), @@ -96,6 +107,7 @@ public object IntUiDefaultTabColorsFactory { underlineSelected = underlineSelected, ) + /** Creates an Int UI dark default [TabColors] with the provided parameters. */ public fun dark( background: Color = Color.Unspecified, backgroundHovered: Color = IntUiDarkTheme.colors.gray(4), @@ -132,10 +144,13 @@ public object IntUiDefaultTabColorsFactory { ) } +/** The factory for creating Int UI editor [TabColors] instances. */ public val TabColors.Companion.Editor: IntUiEditorTabColorsFactory get() = IntUiEditorTabColorsFactory +/** Factory object for creating Int UI editor [TabColors] instances. */ public object IntUiEditorTabColorsFactory { + /** Creates an Int UI light editor [TabColors] with the provided parameters. */ public fun light( background: Color = Color.Transparent, backgroundHovered: Color = background, @@ -171,6 +186,7 @@ public object IntUiEditorTabColorsFactory { underlineSelected = underlineSelected, ) + /** Creates an Int UI dark editor [TabColors] with the provided parameters. */ public fun dark( background: Color = Color.Unspecified, backgroundHovered: Color = background, @@ -207,6 +223,7 @@ public object IntUiEditorTabColorsFactory { ) } +/** Creates an Int UI default [TabMetrics] with the provided parameters. */ public fun TabMetrics.Companion.defaults( underlineThickness: Dp = 3.dp, tabPadding: PaddingValues = PaddingValues(horizontal = 8.dp), @@ -215,6 +232,7 @@ public fun TabMetrics.Companion.defaults( tabHeight: Dp = 40.dp, ): TabMetrics = TabMetrics(underlineThickness, tabPadding, tabHeight, tabContentSpacing, closeContentGap) +/** Creates an Int UI default [TabContentAlpha] with the provided parameters. */ public fun TabContentAlpha.Companion.default( iconNormal: Float = 1f, iconDisabled: Float = iconNormal, @@ -240,6 +258,7 @@ public fun TabContentAlpha.Companion.default( contentSelected = contentSelected, ) +/** Creates an Int UI editor [TabContentAlpha] with the provided parameters. */ public fun TabContentAlpha.Companion.editor( iconNormal: Float = .7f, iconDisabled: Float = iconNormal, @@ -265,4 +284,5 @@ public fun TabContentAlpha.Companion.editor( contentSelected = contentSelected, ) +/** Creates an Int UI default [TabIcons] with the provided parameters. */ public fun TabIcons.Companion.defaults(close: IconKey = AllIconsKeys.General.CloseSmall): TabIcons = TabIcons(close) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt index 794f08ec600c..3e9183d94c32 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt @@ -12,16 +12,19 @@ import org.jetbrains.jewel.ui.component.styling.TextAreaColors import org.jetbrains.jewel.ui.component.styling.TextAreaMetrics import org.jetbrains.jewel.ui.component.styling.TextAreaStyle +/** Creates an Int UI light [TextAreaStyle] with the provided parameters. */ public fun TextAreaStyle.Companion.light( colors: TextAreaColors = TextAreaColors.light(), metrics: TextAreaMetrics = TextAreaMetrics.defaults(), ): TextAreaStyle = TextAreaStyle(colors, metrics) +/** Creates an Int UI dark [TextAreaStyle] with the provided parameters. */ public fun TextAreaStyle.Companion.dark( colors: TextAreaColors = TextAreaColors.dark(), metrics: TextAreaMetrics = TextAreaMetrics.defaults(), ): TextAreaStyle = TextAreaStyle(colors, metrics) +/** Creates an Int UI light [TextAreaColors] with the provided parameters. */ public fun TextAreaColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), backgroundDisabled: Color = Color.Unspecified, @@ -69,6 +72,7 @@ public fun TextAreaColors.Companion.light( placeholder = placeholder, ) +/** Creates an Int UI dark [TextAreaColors] with the provided parameters. */ public fun TextAreaColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), backgroundDisabled: Color = Color.Unspecified, @@ -116,6 +120,7 @@ public fun TextAreaColors.Companion.dark( placeholder = placeholder, ) +/** Creates an Int UI default [TextAreaMetrics] with the provided parameters. */ public fun TextAreaMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(4.dp), contentPadding: PaddingValues = PaddingValues(horizontal = 5.dp, vertical = 4.dp), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt index e0e528014918..20f0a955efa5 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt @@ -14,6 +14,7 @@ import org.jetbrains.jewel.ui.component.styling.TextFieldColors import org.jetbrains.jewel.ui.component.styling.TextFieldMetrics import org.jetbrains.jewel.ui.component.styling.TextFieldStyle +/** Creates an Int UI light [TextFieldStyle] with the provided parameters. */ public fun TextFieldStyle.Companion.light( colors: TextFieldColors = TextFieldColors.light(), metrics: TextFieldMetrics = TextFieldMetrics.defaults(), @@ -32,6 +33,7 @@ public fun TextFieldStyle.Companion.light( ), ): TextFieldStyle = TextFieldStyle(colors, metrics, iconButtonStyle) +/** Creates an Int UI dark [TextFieldStyle] with the provided parameters. */ public fun TextFieldStyle.Companion.dark( colors: TextFieldColors = TextFieldColors.dark(), metrics: TextFieldMetrics = TextFieldMetrics.defaults(), @@ -49,6 +51,7 @@ public fun TextFieldStyle.Companion.dark( ), ): TextFieldStyle = TextFieldStyle(colors, metrics, iconButtonStyle) +/** Creates an Int UI light [TextFieldColors] with the provided parameters. */ public fun TextFieldColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), backgroundDisabled: Color = Color.Unspecified, @@ -96,6 +99,7 @@ public fun TextFieldColors.Companion.light( placeholder = placeholder, ) +/** Creates an Int UI dark [TextFieldColors] with the provided parameters. */ public fun TextFieldColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), backgroundDisabled: Color = Color.Unspecified, @@ -143,6 +147,7 @@ public fun TextFieldColors.Companion.dark( placeholder = placeholder, ) +/** Creates an Int UI default [TextFieldMetrics] with the provided parameters. */ public fun TextFieldMetrics.Companion.defaults( cornerSize: CornerSize = CornerSize(4.dp), contentPadding: PaddingValues = PaddingValues(horizontal = 9.dp), // 8 + 1 (border) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTooltipStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTooltipStyling.kt index 2283deee7da2..2ce47f1e9f6d 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTooltipStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTooltipStyling.kt @@ -20,6 +20,7 @@ public fun TooltipStyle.Companion.light( autoHideBehavior = TooltipAutoHideBehavior.Normal, ) +/** Creates an Int UI light [TooltipStyle] with the provided parameters. */ public fun TooltipStyle.Companion.light( intUiTooltipColors: TooltipColors = TooltipColors.light(), intUiTooltipMetrics: TooltipMetrics = TooltipMetrics.defaults(regularDisappearDelay = 10000.milliseconds), @@ -38,6 +39,7 @@ public fun TooltipStyle.Companion.dark( autoHideBehavior = TooltipAutoHideBehavior.Normal, ) +/** Creates an Int UI dark [TooltipStyle] with the provided parameters. */ public fun TooltipStyle.Companion.dark( intUiTooltipColors: TooltipColors = TooltipColors.dark(), intUiTooltipMetrics: TooltipMetrics = TooltipMetrics.defaults(regularDisappearDelay = 10000.milliseconds), @@ -45,6 +47,7 @@ public fun TooltipStyle.Companion.dark( ): TooltipStyle = TooltipStyle(colors = intUiTooltipColors, metrics = intUiTooltipMetrics, autoHideBehavior = autoHideBehavior) +/** Creates an Int UI light [TooltipColors] with the provided parameters. */ public fun TooltipColors.Companion.light( backgroundColor: Color = IntUiLightTheme.colors.gray(2), contentColor: Color = IntUiLightTheme.colors.gray(12), @@ -52,6 +55,7 @@ public fun TooltipColors.Companion.light( shadow: Color = Color(0x78919191), // Not a palette color ): TooltipColors = TooltipColors(backgroundColor, contentColor, borderColor, shadow) +/** Creates an Int UI dark [TooltipColors] with the provided parameters. */ public fun TooltipColors.Companion.dark( backgroundColor: Color = IntUiDarkTheme.colors.gray(2), contentColor: Color = IntUiDarkTheme.colors.gray(12), diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiGlobalMetrics.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiGlobalMetrics.kt index 51cc00bdcef4..5c03bf676bd1 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiGlobalMetrics.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiGlobalMetrics.kt @@ -4,5 +4,6 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.GlobalMetrics +/** Creates an Int UI default [GlobalMetrics] with the provided parameters. */ public fun GlobalMetrics.Companion.defaults(outlineWidth: Dp = 2.dp, rowHeight: Dp = 24.dp): GlobalMetrics = GlobalMetrics(outlineWidth, rowHeight) diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt index 40bca752b1e2..2557a378937d 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt @@ -236,6 +236,10 @@ public fun JewelTheme.Companion.darkThemeDefinition( disabledAppearanceValues, ) +/** + * Creates the default Int UI [ComponentStyling] by automatically selecting the light or dark variant based on the + * current theme. + */ @Composable public fun ComponentStyling.default(): ComponentStyling = with { // It's ok to use isDark here instead of instanceUuid, since we're building @@ -260,6 +264,7 @@ public fun ComponentStyling.default(): ComponentStyling = with { } } +/** Creates an Int UI dark [ComponentStyling] with the provided parameters. */ @Suppress("UnusedReceiverParameter") public fun ComponentStyling.dark( checkboxStyle: CheckboxStyle = CheckboxStyle.dark(), @@ -852,6 +857,7 @@ public fun ComponentStyling.dark( gotItButtonStyle = ButtonStyle.GotIt.dark(), ) +/** Creates an Int UI light [ComponentStyling] with the provided parameters. */ @Suppress("UnusedReceiverParameter") public fun ComponentStyling.light( checkboxStyle: CheckboxStyle = CheckboxStyle.light(), @@ -1444,6 +1450,7 @@ public fun ComponentStyling.light( gotItButtonStyle = ButtonStyle.GotIt.light(), ) +/** Applies the Int UI standalone theme with automatically selected light or dark component styling. */ @Composable public fun IntUiTheme(isDark: Boolean = false, swingCompatMode: Boolean = false, content: @Composable () -> Unit) { // It's ok to use isDark here instead of instanceUuid, since we're building @@ -1465,6 +1472,7 @@ public fun IntUiTheme(isDark: Boolean = false, swingCompatMode: Boolean = false, ) } +/** Applies the Int UI standalone theme using the given [ThemeDefinition] and [ComponentStyling]. */ @Composable public fun IntUiTheme( theme: ThemeDefinition, diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/TextStyles.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/TextStyles.kt index 4dcfe2e6f174..63bae89017dd 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/TextStyles.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/TextStyles.kt @@ -436,6 +436,7 @@ private fun computeJetBrainsMonoLineHeightPx(@Px fontSize: Float): Int { */ private const val EDITOR_LINE_HEIGHT_FACTOR = 0.87f +/** The multiplier applied to the computed line height when creating an editor text style. */ @ApiStatus.Experimental @ExperimentalJewelApi @Suppress("ktlint:standard:property-naming", "TopLevelPropertyNaming") diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/JnaLoader.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/JnaLoader.kt index 2b9385edd355..6dfabc2351ec 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/JnaLoader.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/JnaLoader.kt @@ -8,12 +8,18 @@ import kotlin.system.measureTimeMillis import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.InternalJewelApi +/** + * Lazily initialises the JNA native library and exposes whether the load succeeded. + * + * Calls are thread-safe: both [load] and [isLoaded] are `@Synchronized`. + */ @ApiStatus.Internal @InternalJewelApi public object JnaLoader { private var loaded: Boolean? = null private val logger = Logger.getLogger(JnaLoader::class.java.simpleName) + /** Loads the JNA native library if not already loaded. On failure, logs a warning and leaves [isLoaded] false. */ @Synchronized public fun load() { if (loaded == null) { @@ -36,6 +42,7 @@ public object JnaLoader { } } + /** Whether the JNA library was successfully loaded. Triggers [load] on first access. */ @get:Synchronized public val isLoaded: Boolean get() { diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/macos/ID.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/macos/ID.kt index d728dd17183f..e23e4ea589c3 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/macos/ID.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/window/macos/ID.kt @@ -13,6 +13,7 @@ public class ID : NativeLong { public constructor(peer: Long) : super(peer) + /** Returns `true` if this ID's underlying value is non-zero. */ public fun booleanValue(): Boolean = toInt() != 0 override fun toByte(): Byte = toInt().toByte() @@ -24,7 +25,9 @@ public class ID : NativeLong { @Suppress("RedundantOverride") // Without this, we get a SOE override fun toInt(): Int = super.toInt() + /** Provides the [NIL] sentinel value. */ public companion object { + /** The nil/null Objective-C object reference (pointer value 0). */ @JvmField public val NIL: ID = ID(0L) } } diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/InlineMarkdown.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/InlineMarkdown.kt index ada7169550cd..dfda8caa83a2 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/InlineMarkdown.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/InlineMarkdown.kt @@ -11,6 +11,7 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions @ApiStatus.Experimental @ExperimentalJewelApi public sealed interface InlineMarkdown { + /** An inline code span, rendered with a monospace font. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -53,6 +54,7 @@ public sealed interface InlineMarkdown { get() = openingDelimiter } + /** An inline emphasis (italic) node, delimited by [delimiter] and containing [inlineContent]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -84,8 +86,10 @@ public sealed interface InlineMarkdown { override fun toString(): String = "Emphasis(delimiter='$delimiter', inlineContent=$inlineContent)" } + /** A hard line break, rendered as a newline that forces a new line in the output. */ public data object HardLineBreak : InlineMarkdown + /** A raw inline HTML tag or entity, passed through as-is during rendering. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -194,6 +198,10 @@ public sealed interface InlineMarkdown { } } + /** + * An inline hyperlink node holding a [destination] URL, an optional [title], and [inlineContent] for the link + * label. + */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -231,8 +239,10 @@ public sealed interface InlineMarkdown { override fun toString(): String = "Link(destination='$destination', title=$title, inlineContent=$inlineContent)" } + /** A soft line break, typically rendered as a space or ignored depending on the renderer. */ public data object SoftLineBreak : InlineMarkdown + /** An inline strong emphasis (bold) node, delimited by [delimiter] and containing [inlineContent]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -264,6 +274,7 @@ public sealed interface InlineMarkdown { override fun toString(): String = "StrongEmphasis(delimiter='$delimiter', inlineContent=$inlineContent)" } + /** A plain text node holding a literal [content] string. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownBlock.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownBlock.kt index 6fc5468f163d..0da636dc13ff 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownBlock.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownBlock.kt @@ -5,9 +5,11 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.foundation.code.MimeType +/** Represents a block-level element in a parsed Markdown document. */ @ApiStatus.Experimental @ExperimentalJewelApi public sealed interface MarkdownBlock { + /** A block quote containing one or more nested [MarkdownBlock] children. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -28,11 +30,14 @@ public sealed interface MarkdownBlock { override fun toString(): String = "BlockQuote(children=$children)" } + /** A block-level code element containing raw source [content]. */ @ApiStatus.Experimental @ExperimentalJewelApi public sealed interface CodeBlock : MarkdownBlock { + /** The raw source content of the code block. */ public val content: String + /** A code block delimited by four spaces or a tab of indentation, holding the raw [content]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -51,6 +56,10 @@ public sealed interface MarkdownBlock { override fun toString(): String = "IndentedCodeBlock(content='$content')" } + /** + * A code block delimited by backtick or tilde fences, holding the raw [content] and an optional [language] + * identifier. + */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -91,8 +100,10 @@ public sealed interface MarkdownBlock { } } + /** A custom extension block that is not part of the standard Markdown specification. */ @ApiStatus.Experimental @ExperimentalJewelApi public interface CustomBlock : MarkdownBlock + /** A heading at the given [level] (1–6) with inline [inlineContent]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -121,6 +132,7 @@ public sealed interface MarkdownBlock { override fun toString(): String = "Heading(inlineContent=$inlineContent, level=$level)" } + /** A raw HTML block, with [content] holding the literal HTML source as written in the Markdown. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -139,12 +151,16 @@ public sealed interface MarkdownBlock { override fun toString(): String = "HtmlBlock(content='$content')" } + /** A list block containing [ListItem] children, either ordered or unordered. */ @ApiStatus.Experimental @ExperimentalJewelApi public sealed interface ListBlock : MarkdownBlock, WithChildBlocks { + /** The list items contained in this list. */ override val children: List + /** Whether the list is tight (no blank lines between items). */ public val isTight: Boolean + /** An ordered (numbered) list, starting from [startFrom] and using [delimiter] after each number. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -193,6 +209,7 @@ public sealed interface MarkdownBlock { } } + /** An unordered (bulleted) list whose items are preceded by [marker]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -231,6 +248,7 @@ public sealed interface MarkdownBlock { } } + /** A single item within a [ListBlock], containing nested [children] blocks at the given nesting [level]. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -261,8 +279,10 @@ public sealed interface MarkdownBlock { override fun toString(): String = "ListItem(children=$children, level=$level)" } + /** A thematic break (horizontal rule) used to separate sections of content. */ @ApiStatus.Experimental @ExperimentalJewelApi public data object ThematicBreak : MarkdownBlock + /** A paragraph of inline content. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -283,13 +303,16 @@ public sealed interface MarkdownBlock { override fun toString(): String = "Paragraph(inlineContent=$inlineContent)" } + /** A [MarkdownBlock] decorated with additional HTML [attributes] parsed from an attribute block. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class HtmlBlockWithAttributes( + /** The wrapped [MarkdownBlock] content that the HTML [attributes] apply to. */ public val mdBlock: MarkdownBlock, public val attributes: Map, ) : MarkdownBlock, WithChildBlocks { + /** The wrapped [mdBlock] as a single-element list. */ override val children: List get() = listOf(mdBlock) diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownMode.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownMode.kt index 674b1edac68e..83c349ad8e34 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownMode.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownMode.kt @@ -33,6 +33,13 @@ public sealed interface MarkdownMode { public class EditorPreview(public val scrollingSynchronizer: ScrollingSynchronizer?) : MarkdownMode } +/** + * Provides a [MarkdownMode] to the composition via [LocalMarkdownMode], making it available to all descendant + * composables. + * + * @param mode The [MarkdownMode] to provide. + * @param content The composable content that will have access to the provided [mode]. + */ @ApiStatus.Experimental @ExperimentalJewelApi @Composable diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownText.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownText.kt index 4f8af27a1086..36ca9b112c52 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownText.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/MarkdownText.kt @@ -35,8 +35,8 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownStyling * High-level element that renders Markdown text. * * @param text The text to be displayed. - * @param enabled True if the block should be enabled, false otherwise. * @param modifier The modifier to be applied to the composable. + * @param enabled True if the block should be enabled, false otherwise. * @param color [Color] to apply to the text. If it is [Color.Unspecified], this will be [LocalContentColor]. * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize]. * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). See [TextStyle.fontStyle]. @@ -50,6 +50,7 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownStyling * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the text will be * positioned as if there was unlimited horizontal space. If [softWrap] is false, [overflow] and [textAlign] may have * unexpected effects. + * @param maxLines The maximum number of lines to display. * @param onTextLayout Callback that is executed when a new text layout is calculated. A [TextLayoutResult] object that * callback provides contains paragraph information, size of the text, baselines and other details. The callback can * be used to add additional decoration or functionality to the text. For example, to draw selection around the text. @@ -115,8 +116,8 @@ public fun MarkdownText( * High-level element that renders Markdown text. * * @param paragraph The paragraph to render. - * @param enabled True if the block should be enabled, false otherwise. * @param modifier The modifier to be applied to the composable. + * @param enabled True if the block should be enabled, false otherwise. * @param color [Color] to apply to the text. If it is [Color.Unspecified], this will be [LocalContentColor]. * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize]. * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). See [TextStyle.fontStyle]. @@ -130,6 +131,7 @@ public fun MarkdownText( * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the text will be * positioned as if there was unlimited horizontal space. If [softWrap] is false, [overflow] and [textAlign] may have * unexpected effects. + * @param maxLines The maximum number of lines to display. * @param onTextLayout Callback that is executed when a new text layout is calculated. A [TextLayoutResult] object that * callback provides contains paragraph information, size of the text, baselines and other details. The callback can * be used to add additional decoration or functionality to the text. For example, to draw selection around the text. diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/WithChildBlocks.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/WithChildBlocks.kt index 5ce262965c46..fde006e52bdb 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/WithChildBlocks.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/WithChildBlocks.kt @@ -9,5 +9,6 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi @ApiStatus.Experimental @ExperimentalJewelApi public interface WithChildBlocks { + /** The child blocks contained within this block. */ public val children: List } diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/Markdown.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/Markdown.kt index 457efebc8532..91dd18457508 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/Markdown.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/Markdown.kt @@ -11,45 +11,53 @@ import org.jetbrains.jewel.markdown.processing.MarkdownProcessor import org.jetbrains.jewel.markdown.rendering.MarkdownBlockRenderer import org.jetbrains.jewel.markdown.rendering.MarkdownStyling +/** CompositionLocal that provides the current [MarkdownStyling]. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val LocalMarkdownStyling: ProvidableCompositionLocal = staticCompositionLocalOf { error("No MarkdownStyling defined, have you forgotten to provide it?") } +/** The current [MarkdownStyling] from the composition. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val JewelTheme.Companion.markdownStyling: MarkdownStyling @Composable get() = LocalMarkdownStyling.current +/** CompositionLocal that provides the current [MarkdownProcessor]. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val LocalMarkdownProcessor: ProvidableCompositionLocal = staticCompositionLocalOf { error("No MarkdownProcessor defined, have you forgotten to provide it?") } +/** The current [MarkdownProcessor] from the composition. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val JewelTheme.Companion.markdownProcessor: MarkdownProcessor @Composable get() = LocalMarkdownProcessor.current +/** CompositionLocal that provides the current [MarkdownBlockRenderer]. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val LocalMarkdownBlockRenderer: ProvidableCompositionLocal = staticCompositionLocalOf { error("No MarkdownBlockRenderer defined, have you forgotten to provide it?") } +/** The current [MarkdownBlockRenderer] from the composition. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val JewelTheme.Companion.markdownBlockRenderer: MarkdownBlockRenderer @Composable get() = LocalMarkdownBlockRenderer.current +/** CompositionLocal that provides the current [MarkdownMode]. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val LocalMarkdownMode: ProvidableCompositionLocal = staticCompositionLocalOf { MarkdownMode.Standalone } +/** The current [MarkdownMode] from the composition. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val JewelTheme.Companion.markdownMode: MarkdownMode diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt index c7576f767353..a6a17c89d717 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/MarkdownProcessor.kt @@ -427,10 +427,6 @@ public class MarkdownProcessor( return level - 1 } - /** - * Processes the children of a CommonMark [Node]. This function is public so that it can be accessed from - * [MarkdownProcessorExtension]s, but should not be used in other scenarios. - */ @ApiStatus.Internal @InternalJewelApi public fun processChildren(node: Node): List = buildList { diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/html/MarkdownHtmlNode.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/html/MarkdownHtmlNode.kt index 8b66bf55c908..6356e37c0b72 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/html/MarkdownHtmlNode.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/processing/html/MarkdownHtmlNode.kt @@ -56,6 +56,7 @@ public sealed interface MarkdownHtmlNode { override val htmlContent: String, ) : MarkdownHtmlNode + /** Factory functions for parsing raw HTML into [MarkdownHtmlNode] trees. */ public companion object { private val contextElement = JsoupElement("p") diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt index e1cf7d0d1c65..b701a821cfdb 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/DefaultMarkdownBlockRenderer.kt @@ -864,6 +864,10 @@ public open class DefaultMarkdownBlockRenderer( return map to failedSources } + /** + * Wraps [content] in a [HorizontallyScrollableContainer] when [isScrollable] is `true`, or renders it directly + * otherwise. Uses [movableContentOf] to preserve the content's state across toggling. + */ @Composable protected fun MaybeScrollingContainer( isScrollable: Boolean, @@ -1225,6 +1229,7 @@ public open class DefaultMarkdownBlockRenderer( override operator fun plus(extension: MarkdownRendererExtension): MarkdownBlockRenderer = DefaultMarkdownBlockRenderer(rootStyling, rendererExtensions = rendererExtensions + extension, inlineRenderer) + /** Companion object for [DefaultMarkdownBlockRenderer]. */ public companion object { /** * Holds the current text alignment for the subtree of the composition. Used by the HTML parsing path to diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/ImageSourceResolver.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/ImageSourceResolver.kt index c8eaaa329fd6..43f5a9aa3e1d 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/ImageSourceResolver.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/ImageSourceResolver.kt @@ -34,6 +34,7 @@ public interface ImageSourceResolver { */ public fun resolve(rawDestination: String): String? + /** Companion object for [ImageSourceResolver]. */ public companion object { @VisibleForTesting internal val defaultCapabilities = diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownBlockRenderer.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownBlockRenderer.kt index 2e57bf701a21..e3e62bfe897f 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownBlockRenderer.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownBlockRenderer.kt @@ -3,14 +3,10 @@ package org.jetbrains.jewel.markdown.rendering import androidx.compose.foundation.text.InlineTextContent import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextLayoutResult -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.TextUnit import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.ExperimentalJewelApi -import org.jetbrains.jewel.foundation.theme.LocalContentColor import org.jetbrains.jewel.markdown.MarkdownBlock import org.jetbrains.jewel.markdown.MarkdownBlock.BlockQuote import org.jetbrains.jewel.markdown.MarkdownBlock.CodeBlock @@ -24,20 +20,18 @@ import org.jetbrains.jewel.markdown.MarkdownBlock.ListItem import org.jetbrains.jewel.markdown.MarkdownBlock.Paragraph import org.jetbrains.jewel.markdown.extensions.MarkdownRendererExtension -/** - * Renders one or more [MarkdownBlock]s into a Compose UI. - * - * @param rootStyling The [MarkdownStyling] to use to render the Markdown into composables. - * @param rendererExtensions The [MarkdownRendererExtension]s used to render [MarkdownBlock.CustomBlock]s. - * @param inlineRenderer The [InlineMarkdownRenderer] used to render - * [inline content][org.jetbrains.jewel.markdown.InlineMarkdown]. - */ +/** Renders one or more [MarkdownBlock]s into a Compose UI. */ @Suppress("ComposableNaming") @ApiStatus.Experimental @ExperimentalJewelApi public interface MarkdownBlockRenderer { + /** The [MarkdownStyling] used to style the rendered Markdown composables. */ public val rootStyling: MarkdownStyling + + /** The list of [MarkdownRendererExtension]s used to render custom blocks. */ public val rendererExtensions: List + + /** The [InlineMarkdownRenderer] used to render inline Markdown content. */ public val inlineRenderer: InlineMarkdownRenderer /** @@ -160,25 +154,16 @@ public interface MarkdownBlockRenderer { * @param styling The [`Paragraph`][MarkdownStyling.Paragraph] styling to use to render. * @param enabled True if the block should be enabled, false otherwise. * @param onUrlClick The callback invoked when the user clicks on a URL. - * @param modifier The modifier to be applied to the composable. - * @param color [Color] to apply to the text. If [Color.Unspecified], and [style] has no color set, this will be - * [LocalContentColor]. - * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize]. - * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). See [TextStyle.fontStyle]. - * @param fontWeight The typeface thickness to use when painting the text (e.g., [FontWeight.Bold]). - * @param fontFamily The font family to be used when rendering the text. See [TextStyle.fontFamily]. - * @param letterSpacing The amount of space to add between each letter. See [TextStyle.letterSpacing]. - * @param textDecoration The decorations to paint on the text (e.g., an underline). See [TextStyle.textDecoration]. - * @param textAlign The alignment of the text within the lines of the paragraph. See [TextStyle.textAlign]. - * @param lineHeight Line height for the paragraph in [TextUnit] unit, e.g., SP or EM. See [TextStyle.lineHeight]. - * @param overflow How visual overflow should be handled. - * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the text will be - * positioned as if there was unlimited horizontal space. If [softWrap] is false, [overflow] and [textAlign] may - * have unexpected effects. * @param onTextLayout Callback that is executed when a new text layout is calculated. A [TextLayoutResult] object * that callback provides contains paragraph information, size of the text, baselines and other details. The * callback can be used to add additional decoration or functionality to the text. For example, to draw selection * around the text. + * @param modifier The modifier to be applied to the composable. + * @param overflow How visual overflow should be handled. + * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the text will be + * positioned as if there was unlimited horizontal space. If [softWrap] is false, [overflow] and [textAlign] may + * have unexpected effects. + * @param maxLines The maximum number of lines to display. */ @Composable public fun RenderParagraph( diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownStyling.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownStyling.kt index e969874ada2d..b9ead6f8d5a9 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownStyling.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/rendering/MarkdownStyling.kt @@ -26,24 +26,42 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.Code.Fenced.InfoPo import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.Code.Fenced.InfoPosition.TopEnd import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.Code.Fenced.InfoPosition.TopStart +/** + * Holds all styling configuration for rendering Markdown content, grouping per-block-type styling classes for + * paragraphs, headings, block quotes, code blocks, lists, images, thematic breaks, and HTML blocks. + */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class MarkdownStyling( + /** + * The vertical spacing applied between sibling Markdown block elements, both at the top level and within container + * blocks such as block quotes. + */ public val blockVerticalSpacing: Dp, + /** Styling for paragraph blocks. */ public val paragraph: Paragraph, + /** Styling for heading blocks (H1–H6). */ public val heading: Heading, + /** Styling for block quote elements. */ public val blockQuote: BlockQuote, + /** Styling for code blocks (indented and fenced). */ public val code: Code, + /** Styling for ordered and unordered list blocks. */ public val list: List, + /** Styling for image elements. */ public val image: Image, + /** Styling for thematic break (horizontal rule) elements. */ public val thematicBreak: ThematicBreak, + /** Styling for HTML block elements. */ public val htmlBlock: HtmlBlock, ) { + /** The base [InlinesStyling] derived from the [paragraph] styling, used as a fallback for inline rendering. */ @ApiStatus.Experimental @ExperimentalJewelApi public val baseInlinesStyling: InlinesStyling = paragraph.inlinesStyling + /** Styling for Markdown paragraph blocks. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -61,24 +79,35 @@ public class MarkdownStyling( override fun toString(): String = "Paragraph(inlinesStyling=$inlinesStyling)" + /** Companion object for [Paragraph]. */ public companion object } + /** Styling for Markdown heading blocks (H1–H6). */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Heading( + /** Styling for H1 headings. */ public val h1: H1, + /** Styling for H2 headings. */ public val h2: H2, + /** Styling for H3 headings. */ public val h3: H3, + /** Styling for H4 headings. */ public val h4: H4, + /** Styling for H5 headings. */ public val h5: H5, + /** Styling for H6 headings. */ public val h6: H6, ) { + /** Common styling contract for all heading levels (H1–H6), combining inline and underline styling. */ public sealed interface HN : WithInlinesStyling, WithUnderline { + /** The padding applied around the heading content. */ public val padding: PaddingValues } + /** Styling for the H1 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -123,9 +152,11 @@ public class MarkdownStyling( ")" } + /** Companion object for [H1]. */ public companion object } + /** Styling for the H2 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -170,9 +201,11 @@ public class MarkdownStyling( ")" } + /** Companion object for [H2]. */ public companion object } + /** Styling for the H3 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -217,9 +250,11 @@ public class MarkdownStyling( ")" } + /** Companion object for [H3]. */ public companion object } + /** Styling for the H4 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -264,9 +299,11 @@ public class MarkdownStyling( ")" } + /** Companion object for [H4]. */ public companion object } + /** Styling for the H5 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -311,9 +348,11 @@ public class MarkdownStyling( ")" } + /** Companion object for [H5]. */ public companion object } + /** Styling for the H6 heading level. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions @@ -358,6 +397,7 @@ public class MarkdownStyling( ")" } + /** Companion object for [H6]. */ public companion object } @@ -389,18 +429,26 @@ public class MarkdownStyling( override fun toString(): String = "Heading(h1=$h1, h2=$h2, h3=$h3, h4=$h4, h5=$h5, h6=$h6)" + /** Companion object for [Heading]. */ public companion object } + /** Styling for Markdown block quote elements, including the decorative left-side vertical bar. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class BlockQuote( + /** The padding applied inside the block quote container. */ public val padding: PaddingValues, + /** The width of the decorative left-side vertical bar. */ public val lineWidth: Dp, + /** The color of the decorative left-side vertical bar. */ public val lineColor: Color, + /** The optional path effect applied to the decorative bar stroke. */ public val pathEffect: PathEffect?, + /** The stroke cap style for the decorative bar. */ public val strokeCap: StrokeCap, + /** The text color for block quote content. */ public val textColor: Color, ) { override fun equals(other: Any?): Boolean { @@ -440,35 +488,63 @@ public class MarkdownStyling( ")" } + /** Companion object for [BlockQuote]. */ public companion object } + /** Styling for Markdown list blocks, covering both ordered and unordered list variants. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions - public class List(public val ordered: Ordered, public val unordered: Unordered) { + public class List( + /** Styling for ordered (numbered) list blocks. */ + public val ordered: Ordered, + /** Styling for unordered (bulleted) list blocks. */ + public val unordered: Unordered, + ) { + /** Styling for ordered (numbered) Markdown list blocks. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Ordered( + /** The text style applied to the item number markers. */ public val numberStyle: TextStyle, + /** The horizontal gap between the item number and its content. */ public val numberContentGap: Dp, + /** The minimum width reserved for item number markers. */ public val numberMinWidth: Dp, + /** The text alignment for item number markers. */ public val numberTextAlign: TextAlign, + /** The vertical spacing between list items in loose lists. */ public val itemVerticalSpacing: Dp, + /** The vertical spacing between list items in tight lists. */ public val itemVerticalSpacingTight: Dp, + /** The padding applied around the ordered list container. */ public val padding: PaddingValues, + /** The number format styles applied at each nesting level. */ public val numberFormatStyles: NumberFormatStyles, ) { + /** + * Holds the [NumberFormatStyle] to apply at the first, second, and third nesting levels of an ordered list. + */ @GenerateDataFunctions public class NumberFormatStyles( + /** The number format style applied at the first (outermost) nesting level. */ public val firstLevel: NumberFormatStyle, + /** The number format style applied at the second nesting level; defaults to [firstLevel]. */ public val secondLevel: NumberFormatStyle = firstLevel, + /** The number format style applied at the third nesting level; defaults to [secondLevel]. */ public val thirdLevel: NumberFormatStyle = secondLevel, ) { + /** + * Defines the format used to render item numbers in an ordered list. Implementations determine how a + * positive integer is converted to its display string. + */ public sealed interface NumberFormatStyle { + /** Converts a positive [number] to its display string for use in list item markers. */ public fun formatNumber(number: Int): String + /** Formats list item numbers as decimal digits (e.g., 1, 2, 3). */ public object Decimal : NumberFormatStyle { override fun formatNumber(number: Int): String { require(number >= 0) { "Input must not be a negative integer" } @@ -477,6 +553,7 @@ public class MarkdownStyling( } } + /** Formats list item numbers as lowercase Roman numerals (e.g., i, ii, iii). */ public object Roman : NumberFormatStyle { override fun formatNumber(number: Int): String { // Roman numerals can't represent 0; just render it as the literal "0". @@ -497,6 +574,7 @@ public class MarkdownStyling( } } + /** Formats list item numbers as lowercase alphabetical labels (e.g., a, b, c, aa, ab). */ public object Alphabetical : NumberFormatStyle { override fun formatNumber(number: Int): String { // Letters can't represent 0; just render it as the literal "0". @@ -587,26 +665,42 @@ public class MarkdownStyling( ")" } + /** Companion object for [Ordered]. */ public companion object } + /** Styling for unordered (bulleted) Markdown list blocks. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Unordered( + /** The bullet character used for all nesting levels when [bulletCharStyles] is null. */ public val bullet: Char?, + /** The text style applied to bullet marker characters. */ public val bulletStyle: TextStyle, + /** The horizontal gap between the bullet marker and its content. */ public val bulletContentGap: Dp, + /** The vertical spacing between list items in loose lists. */ public val itemVerticalSpacing: Dp, + /** The vertical spacing between list items in tight lists. */ public val itemVerticalSpacingTight: Dp, + /** The padding applied around the unordered list container. */ public val padding: PaddingValues, + /** The minimum width reserved for bullet markers. */ public val markerMinWidth: Dp, + /** The per-level bullet characters; when non-null, overrides [bullet]. */ public val bulletCharStyles: BulletCharStyles?, ) { + /** + * Holds the bullet characters to use at the first, second, and third nesting levels of an unordered list. + */ @GenerateDataFunctions public class BulletCharStyles( + /** The bullet character used at the first (outermost) nesting level. */ public val firstLevel: Char = '•', + /** The bullet character used at the second nesting level; defaults to [firstLevel]. */ public val secondLevel: Char = firstLevel, + /** The bullet character used at the third nesting level; defaults to [secondLevel]. */ public val thirdLevel: Char = secondLevel, ) { override fun equals(other: Any?): Boolean { @@ -680,6 +774,7 @@ public class MarkdownStyling( ")" } + /** Companion object for [Unordered]. */ public companion object } @@ -703,24 +798,40 @@ public class MarkdownStyling( override fun toString(): String = "List(ordered=$ordered, unordered=$unordered)" + /** Companion object for [List]. */ public companion object } + /** Styling for Markdown code blocks, covering both indented and fenced variants. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions - public class Code(public val indented: Indented, public val fenced: Fenced) { + public class Code( + /** Styling for indented code blocks. */ + public val indented: Indented, + /** Styling for fenced code blocks. */ + public val fenced: Fenced, + ) { + /** Styling for indented Markdown code blocks. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Indented( + /** The text style used to render code content. */ public val editorTextStyle: TextStyle, + /** The padding applied inside the code block container. */ public val padding: PaddingValues, + /** The shape of the code block container. */ public val shape: Shape, + /** The background color of the code block container. */ public val background: Color, + /** The width of the code block border. */ public val borderWidth: Dp, + /** The color of the code block border. */ public val borderColor: Color, + /** Whether the code block expands to fill the available width. */ public val fillWidth: Boolean, + /** Whether the code block scrolls horizontally when content overflows. */ public val scrollsHorizontally: Boolean, ) { override fun equals(other: Any?): Boolean { @@ -766,32 +877,56 @@ public class MarkdownStyling( ")" } + /** Companion object for [Indented]. */ public companion object } + /** Styling for fenced Markdown code blocks, including optional language info label rendering. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Fenced( + /** The text style used to render code content. */ public val editorTextStyle: TextStyle, + /** The padding applied inside the code block container. */ public val padding: PaddingValues, + /** The shape of the code block container. */ public val shape: Shape, + /** The background color of the code block container. */ public val background: Color, + /** The width of the code block border. */ public val borderWidth: Dp, + /** The color of the code block border. */ public val borderColor: Color, + /** Whether the code block expands to fill the available width. */ public val fillWidth: Boolean, + /** Whether the code block scrolls horizontally when content overflows. */ public val scrollsHorizontally: Boolean, + /** The text style applied to the language info label. */ public val infoTextStyle: TextStyle, + /** The padding applied around the language info label. */ public val infoPadding: PaddingValues, + /** The position of the language info label relative to the code block. */ public val infoPosition: InfoPosition, ) { + /** + * Controls where the language info string label is displayed relative to a fenced code block. Use [Hide] to + * suppress the label entirely. + */ public enum class InfoPosition { + /** Positions the info label at the top-start corner of the code block. */ TopStart, + /** Positions the info label at the top-center of the code block. */ TopCenter, + /** Positions the info label at the top-end corner of the code block. */ TopEnd, + /** Positions the info label at the bottom-start corner of the code block. */ BottomStart, + /** Positions the info label at the bottom-center of the code block. */ BottomCenter, + /** Positions the info label at the bottom-end corner of the code block. */ BottomEnd, + /** Hides the info label entirely. */ Hide, } @@ -847,6 +982,7 @@ public class MarkdownStyling( ")" } + /** Companion object for [Fenced]. */ public companion object } @@ -870,19 +1006,28 @@ public class MarkdownStyling( override fun toString(): String = "Code(indented=$indented, fenced=$fenced)" + /** Companion object for [Code]. */ public companion object } + /** Styling for Markdown image elements, controlling layout, scaling, and visual decoration. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class Image( + /** The alignment of the image within its container. */ public val alignment: Alignment, + /** The content scale strategy applied when rendering the image. */ public val contentScale: ContentScale, + /** The padding applied around the image. */ public val padding: PaddingValues, + /** The shape of the image container. */ public val shape: Shape, + /** The background color behind the image. */ public val background: Color, + /** The width of the image border. */ public val borderWidth: Dp, + /** The color of the image border. */ public val borderColor: Color, ) { override fun equals(other: Any?): Boolean { @@ -925,15 +1070,20 @@ public class MarkdownStyling( ")" } + /** Companion object for [Image]. */ public companion object } + /** Styling for the Markdown thematic break (horizontal rule) element. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class ThematicBreak( + /** The padding applied around the thematic break line. */ public val padding: PaddingValues, + /** The stroke width of the thematic break line. */ public val lineWidth: Dp, + /** The color of the thematic break line. */ public val lineColor: Color, ) { override fun equals(other: Any?): Boolean { @@ -958,19 +1108,31 @@ public class MarkdownStyling( override fun toString(): String = "ThematicBreak(padding=$padding, lineWidth=$lineWidth, lineColor=$lineColor)" + /** Companion object for [ThematicBreak]. */ public companion object } + /** + * Styling for Markdown HTML block elements. HTML blocks are not rendered by default; this styling only takes effect + * for custom renderers that opt in to rendering them. + */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class HtmlBlock( + /** The text style used to render the HTML block content. */ public val textStyle: TextStyle, + /** The padding applied inside the HTML block container. */ public val padding: PaddingValues, + /** The shape of the HTML block container. */ public val shape: Shape, + /** The background color of the HTML block container. */ public val background: Color, + /** The width of the HTML block border. */ public val borderWidth: Dp, + /** The color of the HTML block border. */ public val borderColor: Color, + /** Whether the HTML block expands to fill the available width. */ public val fillWidth: Boolean, ) { override fun equals(other: Any?): Boolean { @@ -1013,6 +1175,7 @@ public class MarkdownStyling( ")" } + /** Companion object for [HtmlBlock]. */ public companion object } @@ -1062,37 +1225,65 @@ public class MarkdownStyling( ")" } + /** Companion object for [MarkdownStyling]. */ public companion object } +/** + * Marks a Markdown rendering class as carrying [InlinesStyling] for its inline content, such as text spans within + * paragraphs or headings. + */ @ApiStatus.Experimental @ExperimentalJewelApi public interface WithInlinesStyling { + /** The styling applied to inline Markdown elements within this block. */ public val inlinesStyling: InlinesStyling } +/** + * Marks a Markdown rendering class as carrying underline decoration properties, used by heading levels that display a + * separator line below their content. + */ @ApiStatus.Experimental @ExperimentalJewelApi public interface WithUnderline { + /** The stroke width of the underline decoration. */ public val underlineWidth: Dp + /** The color of the underline decoration. */ public val underlineColor: Color + /** The gap between the heading text and the underline decoration. */ public val underlineGap: Dp } +/** + * Holds the styling applied to inline Markdown elements such as plain text, inline code, links (in all interactive + * states), emphasis, strong emphasis, and inline HTML spans. + */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class InlinesStyling( + /** The base text style applied to plain inline text. */ public val textStyle: TextStyle, + /** The span style applied to inline code spans. */ public val inlineCode: SpanStyle, + /** The span style applied to links in their default state. */ public val link: SpanStyle, + /** The span style applied to links in their disabled state. */ public val linkDisabled: SpanStyle, + /** The span style applied to links in their focused state. */ public val linkFocused: SpanStyle, + /** The span style applied to links in their hovered state. */ public val linkHovered: SpanStyle, + /** The span style applied to links in their pressed state. */ public val linkPressed: SpanStyle, + /** The span style applied to links in their visited state. */ public val linkVisited: SpanStyle, + /** The span style applied to emphasized (italic) text. */ public val emphasis: SpanStyle, + /** The span style applied to strongly emphasized (bold) text. */ public val strongEmphasis: SpanStyle, + /** The span style applied to inline HTML spans. */ public val inlineHtml: SpanStyle, ) { @Deprecated("Use variant without renderInlineHtml instead.", level = DeprecationLevel.HIDDEN) @@ -1123,6 +1314,7 @@ public class InlinesStyling( inlineHtml, ) + /** The aggregated [TextLinkStyles] composed from [link], [linkFocused], [linkHovered], and [linkPressed]. */ public val textLinkStyles: TextLinkStyles = TextLinkStyles(style = link, focusedStyle = linkFocused, hoveredStyle = linkHovered, pressedStyle = linkPressed) @@ -1181,6 +1373,7 @@ public class InlinesStyling( ")" } + /** Companion object for [InlinesStyling]. */ public companion object } diff --git a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/scrolling/ScrollingSynchronizer.kt b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/scrolling/ScrollingSynchronizer.kt index ac06c7fc723b..4e7147472822 100644 --- a/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/scrolling/ScrollingSynchronizer.kt +++ b/platform/jewel/markdown/core/src/main/kotlin/org/jetbrains/jewel/markdown/scrolling/ScrollingSynchronizer.kt @@ -143,7 +143,14 @@ public abstract class ScrollingSynchronizer { */ public abstract fun acceptTextLayout(block: MarkdownBlock, textLayout: TextLayoutResult) + /** Companion object for [ScrollingSynchronizer]. */ public companion object { + /** + * Creates a [ScrollingSynchronizer] for the given [scrollState], or `null` if the scroll state type is not + * supported. + * + * Currently, only [ScrollState] is supported. [LazyListState] is not yet supported. + */ public fun create(scrollState: ScrollableState): ScrollingSynchronizer? = when (scrollState) { is ScrollState -> PerLine(scrollState) diff --git a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertIcons.kt b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertIcons.kt index c5e7faa99dd9..f03fa10cc22d 100644 --- a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertIcons.kt +++ b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertIcons.kt @@ -5,29 +5,39 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icon.PathIconKey +/** Icon keys for the five GitHub Flavored Markdown alert types. */ @ApiStatus.Experimental @ExperimentalJewelApi public object GitHubAlertIcons { + /** Icon for the NOTE alert type. */ public val Note: IconKey = PathIconKey( path = "icons/markdown/extensions/github/alerts/alert-note.svg", iconClass = GitHubAlertIcons::class.java, ) + + /** Icon for the TIP alert type. */ public val Tip: IconKey = PathIconKey( path = "icons/markdown/extensions/github/alerts/alert-tip.svg", iconClass = GitHubAlertIcons::class.java, ) + + /** Icon for the IMPORTANT alert type. */ public val Important: IconKey = PathIconKey( path = "icons/markdown/extensions/github/alerts/alert-important.svg", iconClass = GitHubAlertIcons::class.java, ) + + /** Icon for the WARNING alert type. */ public val Warning: IconKey = PathIconKey( path = "icons/markdown/extensions/github/alerts/alert-warning.svg", iconClass = GitHubAlertIcons::class.java, ) + + /** Icon for the CAUTION alert type. */ public val Caution: IconKey = PathIconKey( path = "icons/markdown/extensions/github/alerts/alert-caution.svg", diff --git a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertRendererExtension.kt b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertRendererExtension.kt index 7b4406a243fd..7bd3ac6b82dd 100644 --- a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertRendererExtension.kt +++ b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertRendererExtension.kt @@ -7,6 +7,12 @@ import org.jetbrains.jewel.markdown.extensions.MarkdownBlockRendererExtension import org.jetbrains.jewel.markdown.extensions.MarkdownRendererExtension import org.jetbrains.jewel.markdown.rendering.MarkdownStyling +/** + * A [MarkdownRendererExtension] that renders GitHub Flavored Markdown alert blocks. + * + * @param alertStyling The styling to apply to alert blocks. + * @param rootStyling The root [MarkdownStyling] used for rendering content inside alerts. + */ @ApiStatus.Experimental @ExperimentalJewelApi public class GitHubAlertRendererExtension(alertStyling: AlertStyling, rootStyling: MarkdownStyling) : diff --git a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertStyling.kt b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertStyling.kt index 50394c9e6de5..0d4fab1db8a1 100644 --- a/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertStyling.kt +++ b/platform/jewel/markdown/extensions/gfm-alerts/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/alerts/GitHubAlertStyling.kt @@ -24,10 +24,15 @@ import org.jetbrains.jewel.ui.icon.IconKey @ExperimentalJewelApi @GenerateDataFunctions public class AlertStyling( + /** Styling for the "note" alert. */ public val note: NoteAlertStyling, + /** Styling for the "tip" alert. */ public val tip: TipAlertStyling, + /** Styling for the "important" alert. */ public val important: ImportantAlertStyling, + /** Styling for the "warning" alert. */ public val warning: WarningAlertStyling, + /** Styling for the "caution" alert. */ public val caution: CautionAlertStyling, ) { override fun equals(other: Any?): Boolean { @@ -64,33 +69,34 @@ public class AlertStyling( ")" } + /** Companion object for [AlertStyling]. */ public companion object } /** - * Base styling for a GFM alert. - * - * @property padding The padding to apply to the entire alert. - * @property lineWidth The width of the vertical line on the side of the alert. - * @property lineColor The color of the vertical line on the side of the alert. - * @property pathEffect The path effect to apply to the vertical line, e.g., for dashed lines. - * @property strokeCap The stroke cap to use for the vertical line. - * @property titleTextStyle The text style for the alert's title. - * @property titleIconKey The icon to use in the title. - * @property titleIconTint The tint to apply to the title icon. - * @property textColor The text color for the body of the alert. + * Base styling for a GFM alert, defining the vertical line, title, icon, and text color properties shared across all + * alert types. */ @ApiStatus.Experimental @ExperimentalJewelApi public sealed interface BaseAlertStyling { + /** The padding applied around the alert content. */ public val padding: PaddingValues + /** The width of the vertical accent line. */ public val lineWidth: Dp + /** The color of the vertical accent line. */ public val lineColor: Color + /** The path effect applied to the vertical accent line, or null for a solid line. */ public val pathEffect: PathEffect? + /** The stroke cap style for the vertical accent line. */ public val strokeCap: StrokeCap + /** The text style applied to the alert title. */ public val titleTextStyle: TextStyle + /** The icon displayed next to the alert title, or null for no icon. */ public val titleIconKey: IconKey? + /** The tint color applied to the title icon. */ public val titleIconTint: Color + /** The color applied to the alert body text. */ public val textColor: Color } @@ -155,6 +161,7 @@ public class NoteAlertStyling( ")" } + /** Companion object for [NoteAlertStyling]. */ public companion object } @@ -219,6 +226,7 @@ public class TipAlertStyling( ")" } + /** Companion object for [TipAlertStyling]. */ public companion object } @@ -283,6 +291,7 @@ public class ImportantAlertStyling( ")" } + /** Companion object for [ImportantAlertStyling]. */ public companion object } @@ -347,6 +356,7 @@ public class WarningAlertStyling( ")" } + /** Companion object for [WarningAlertStyling]. */ public companion object } @@ -411,5 +421,6 @@ public class CautionAlertStyling( ")" } + /** Companion object for [CautionAlertStyling]. */ public companion object } diff --git a/platform/jewel/markdown/extensions/gfm-strikethrough/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/strikethrough/GitHubStrikethroughNode.kt b/platform/jewel/markdown/extensions/gfm-strikethrough/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/strikethrough/GitHubStrikethroughNode.kt index e03d9e3709af..adb246954e97 100644 --- a/platform/jewel/markdown/extensions/gfm-strikethrough/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/strikethrough/GitHubStrikethroughNode.kt +++ b/platform/jewel/markdown/extensions/gfm-strikethrough/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/strikethrough/GitHubStrikethroughNode.kt @@ -17,7 +17,12 @@ import org.jetbrains.jewel.markdown.WithInlineMarkdown */ @ApiStatus.Experimental @ExperimentalJewelApi -public data class GitHubStrikethroughNode(val delimiter: String, override val inlineContent: List) : - InlineMarkdown.CustomDelimitedNode, WithInlineMarkdown { +public data class GitHubStrikethroughNode( + /** The delimiter string used to mark the start and end of the strikethrough (e.g., `~~`). */ + val delimiter: String, + /** The inline child nodes contained within this strikethrough span. */ + override val inlineContent: List, +) : InlineMarkdown.CustomDelimitedNode, WithInlineMarkdown { + /** The opening delimiter string, equal to [delimiter]. */ override val openingDelimiter: String = delimiter } diff --git a/platform/jewel/markdown/extensions/gfm-tables/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/tables/GitHubTableStyling.kt b/platform/jewel/markdown/extensions/gfm-tables/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/tables/GitHubTableStyling.kt index fbd6c9cebc27..cc7f6142cd36 100644 --- a/platform/jewel/markdown/extensions/gfm-tables/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/tables/GitHubTableStyling.kt +++ b/platform/jewel/markdown/extensions/gfm-tables/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/github/tables/GitHubTableStyling.kt @@ -11,12 +11,16 @@ import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Defines the overall visual style of a GFM table, combining its colors, metrics, and header font weight. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class GfmTableStyling( + /** The color tokens for the table. */ public val colors: GfmTableColors, + /** The layout metrics for the table. */ public val metrics: GfmTableMetrics, + /** The base font weight applied to header cells. */ public val headerBaseFontWeight: FontWeight, ) { public constructor( @@ -63,16 +67,22 @@ public class GfmTableStyling( "headerBaseFontWeight=$headerBaseFontWeight" + ")" + /** Companion object for [GfmTableStyling]. */ public companion object } +/** Holds the color tokens for a GFM table: border, row background, and alternate row background. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class GfmTableColors( + /** The color of the table borders. */ public val borderColor: Color, + /** The background color for standard (odd) rows. */ public val rowBackgroundColor: Color, + /** The background color for alternate (even) rows when using [RowBackgroundStyle.Striped]. */ public val alternateRowBackgroundColor: Color, + /** The row background style, controlling whether rows are uniform or striped. */ public val rowBackgroundStyle: RowBackgroundStyle, ) { override fun equals(other: Any?): Boolean { @@ -105,9 +115,11 @@ public class GfmTableColors( "rowBackgroundStyle=$rowBackgroundStyle" + ")" + /** Companion object for [GfmTableColors]. */ public companion object } +/** Controls whether GFM table rows are rendered with a uniform or alternating background color. */ @ApiStatus.Experimental @ExperimentalJewelApi public enum class RowBackgroundStyle { @@ -124,13 +136,18 @@ public enum class RowBackgroundStyle { Striped, } +/** Holds the layout metrics for a GFM table: border width, cell padding, and content alignment. */ @ApiStatus.Experimental @ExperimentalJewelApi @GenerateDataFunctions public class GfmTableMetrics( + /** The width of the table borders. */ public val borderWidth: Dp, + /** The padding applied inside each table cell. */ public val cellPadding: PaddingValues, + /** The default horizontal content alignment for body cells. */ public val defaultCellContentAlignment: Alignment.Horizontal, + /** The default horizontal content alignment for header cells. */ public val headerDefaultCellContentAlignment: Alignment.Horizontal, ) { override fun equals(other: Any?): Boolean { @@ -164,5 +181,6 @@ public class GfmTableMetrics( ")" } + /** Companion object for [GfmTableMetrics]. */ public companion object } diff --git a/platform/jewel/markdown/extensions/images/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/images/Coil3ImageRendererExtension.kt b/platform/jewel/markdown/extensions/images/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/images/Coil3ImageRendererExtension.kt index f8a6a755a379..d7fbb23a7f28 100644 --- a/platform/jewel/markdown/extensions/images/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/images/Coil3ImageRendererExtension.kt +++ b/platform/jewel/markdown/extensions/images/src/main/kotlin/org/jetbrains/jewel/markdown/extensions/images/Coil3ImageRendererExtension.kt @@ -28,6 +28,7 @@ public class Coil3ImageRendererExtension(private val imageLoader: ImageLoader) : override val imageRendererExtension: ImageRendererExtension get() = Coil3ImageRendererExtensionImpl(imageLoader) + /** Provides [withDefaultLoader] factory functions for use when no app-wide Coil image loader is available. */ public companion object { /** * A default image loader with a limited in-memory cache. diff --git a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/BridgeMarkdownBlockRendererExtensions.kt b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/BridgeMarkdownBlockRendererExtensions.kt index 8de5303d69ff..9b1e11e66aa4 100644 --- a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/BridgeMarkdownBlockRendererExtensions.kt +++ b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/BridgeMarkdownBlockRendererExtensions.kt @@ -10,6 +10,10 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownBlockRenderer import org.jetbrains.jewel.markdown.rendering.MarkdownStyling import org.jetbrains.jewel.markdown.rendering.create +/** + * Creates a [MarkdownBlockRenderer] backed by a [DefaultMarkdownBlockRenderer], using the current IntelliJ LaF theme + * for default styling. + */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownBlockRenderer.Companion.create( diff --git a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/BridgeMarkdownStyling.kt b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/BridgeMarkdownStyling.kt index 1c2b3c4773bd..ef532d05554f 100644 --- a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/BridgeMarkdownStyling.kt +++ b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/BridgeMarkdownStyling.kt @@ -44,6 +44,7 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.List.Unordered import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.Paragraph import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.ThematicBreak +/** Creates a [MarkdownStyling] by reading values from the current IntelliJ LaF theme and editor color scheme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownStyling.Companion.create( @@ -62,11 +63,16 @@ public fun MarkdownStyling.Companion.create( ): MarkdownStyling = MarkdownStyling(blockVerticalSpacing, paragraph, heading, blockQuote, code, list, image, thematicBreak, htmlBlock) +/** Creates a [Paragraph] styling using the provided [inlinesStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Paragraph.Companion.create(inlinesStyling: InlinesStyling = InlinesStyling.create()): Paragraph = Paragraph(inlinesStyling) +/** + * Creates a [Heading] styling with font sizes scaled from [baseTextStyle]; every heading level uses a fixed SemiBold + * weight. + */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.Companion.create( @@ -122,6 +128,7 @@ public fun Heading.Companion.create( ), ): Heading = Heading(h1, h2, h3, h4, h5, h6) +/** Creates a [Heading.H1] styling, including an optional underline separator below the heading. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H1.Companion.create( @@ -140,6 +147,7 @@ public fun Heading.H1.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H1 = Heading.H1(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates a [Heading.H2] styling, including an optional underline separator below the heading. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H2.Companion.create( @@ -158,9 +166,10 @@ public fun Heading.H2.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H2 = Heading.H2(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates a [Heading.H3] styling. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H3.Companion.create( baseTextStyle: TextStyle = defaultTextStyle, inlinesStyling: InlinesStyling = @@ -177,9 +186,10 @@ public fun Heading.H3.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H3 = Heading.H3(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates a [Heading.H4] styling. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H4.Companion.create( baseTextStyle: TextStyle = defaultTextStyle, inlinesStyling: InlinesStyling = @@ -196,9 +206,10 @@ public fun Heading.H4.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H4 = Heading.H4(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates a [Heading.H5] styling. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H5.Companion.create( baseTextStyle: TextStyle = defaultTextStyle, inlinesStyling: InlinesStyling = @@ -215,9 +226,10 @@ public fun Heading.H5.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H5 = Heading.H5(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates a [Heading.H6] styling, rendered in a muted color to match the H6 convention. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H6.Companion.create( baseTextStyle: TextStyle = defaultTextStyle, inlinesStyling: InlinesStyling = @@ -235,6 +247,7 @@ public fun Heading.H6.Companion.create( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H6 = Heading.H6(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates a [BlockQuote] styling with a vertical accent line and muted text color. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun BlockQuote.Companion.create( @@ -246,6 +259,7 @@ public fun BlockQuote.Companion.create( textColor: Color = Color(0xFF656d76), ): BlockQuote = BlockQuote(padding, lineWidth, lineColor, pathEffect, strokeCap, textColor) +/** Creates a [List] styling combining [Ordered] and [Unordered] list styles. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun List.Companion.create( @@ -281,6 +295,7 @@ public fun Ordered.Companion.create( ), ) +/** Creates an [Ordered] list styling with configurable number format styles per nesting level. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Ordered.Companion.create( @@ -332,6 +347,7 @@ public fun Unordered.Companion.create( Unordered.BulletCharStyles(firstLevel = '•', secondLevel = '◦', thirdLevel = '▪'), ) +/** Creates an [Unordered] list styling with configurable bullet character styles per nesting level. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Unordered.Companion.create( @@ -356,6 +372,7 @@ public fun Unordered.Companion.create( bulletCharStyles, ) +/** Creates a [Code] styling combining [Indented] and [Fenced] code block styles. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Code.Companion.create( @@ -364,6 +381,7 @@ public fun Code.Companion.create( fenced: Fenced = Fenced.create(editorTextStyle), ): Code = Code(indented, fenced) +/** Creates an [Indented] code block styling using the editor text style and theme background color. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Indented.Companion.create( @@ -377,6 +395,7 @@ public fun Indented.Companion.create( scrollsHorizontally: Boolean = true, ): Indented = Indented(textStyle, padding, shape, background, borderWidth, borderColor, fillWidth, scrollsHorizontally) +/** Creates a [Fenced] code block styling, including optional info string display configuration. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Fenced.Companion.create( @@ -406,6 +425,7 @@ public fun Fenced.Companion.create( infoPosition, ) +/** Creates a default [Image] styling with center alignment and fit content scaling. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Image.Companion.default( @@ -418,6 +438,7 @@ public fun Image.Companion.default( borderColor: Color = Color.Unspecified, ): Image = Image(alignment, contentScale, padding, shape, background, borderWidth, borderColor) +/** Creates a [ThematicBreak] styling using the current theme's separator color. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ThematicBreak.Companion.create( @@ -426,6 +447,7 @@ public fun ThematicBreak.Companion.create( lineColor: Color = dividerColor, ): ThematicBreak = ThematicBreak(padding, lineWidth, lineColor) +/** Creates an [HtmlBlock] styling using the editor text style and a bordered rounded container. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun HtmlBlock.Companion.create( @@ -438,6 +460,7 @@ public fun HtmlBlock.Companion.create( fillWidth: Boolean = true, ): HtmlBlock = HtmlBlock(textStyle, padding, shape, background, borderWidth, borderColor, fillWidth) +/** Creates an [InlinesStyling] by reading link and label colors from the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun InlinesStyling.Companion.create( diff --git a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/alerts/BridgeGitHubAlertStyling.kt b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/alerts/BridgeGitHubAlertStyling.kt index 2faf2dd1ba43..b86195e0ac3a 100644 --- a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/alerts/BridgeGitHubAlertStyling.kt +++ b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/alerts/BridgeGitHubAlertStyling.kt @@ -22,6 +22,10 @@ import org.jetbrains.jewel.markdown.extensions.github.alerts.TipAlertStyling import org.jetbrains.jewel.markdown.extensions.github.alerts.WarningAlertStyling import org.jetbrains.jewel.ui.icon.IconKey +/** + * Creates an [AlertStyling] by combining individual alert type stylings, adapting colors to the current IntelliJ LaF + * theme. + */ @ApiStatus.Experimental @ExperimentalJewelApi public fun AlertStyling.Companion.create( @@ -32,6 +36,7 @@ public fun AlertStyling.Companion.create( caution: CautionAlertStyling = CautionAlertStyling.create(), ): AlertStyling = AlertStyling(note, tip, important, warning, caution) +/** Creates a [NoteAlertStyling] with colors adapted to the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun NoteAlertStyling.Companion.create( @@ -57,6 +62,7 @@ public fun NoteAlertStyling.Companion.create( textColor, ) +/** Creates a [TipAlertStyling] with colors adapted to the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun TipAlertStyling.Companion.create( @@ -82,6 +88,7 @@ public fun TipAlertStyling.Companion.create( textColor, ) +/** Creates an [ImportantAlertStyling] with colors adapted to the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ImportantAlertStyling.Companion.create( @@ -107,6 +114,7 @@ public fun ImportantAlertStyling.Companion.create( textColor, ) +/** Creates a [WarningAlertStyling] with colors adapted to the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun WarningAlertStyling.Companion.create( @@ -132,6 +140,7 @@ public fun WarningAlertStyling.Companion.create( textColor, ) +/** Creates a [CautionAlertStyling] with colors adapted to the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun CautionAlertStyling.Companion.create( diff --git a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/tables/BridgeGitHubTableStyling.kt b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/tables/BridgeGitHubTableStyling.kt index 2f728c94c64e..b59cc04be86f 100644 --- a/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/tables/BridgeGitHubTableStyling.kt +++ b/platform/jewel/markdown/ide-laf-bridge-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/bridge/styling/extensions/github/tables/BridgeGitHubTableStyling.kt @@ -16,6 +16,7 @@ import org.jetbrains.jewel.markdown.extensions.github.tables.GfmTableMetrics import org.jetbrains.jewel.markdown.extensions.github.tables.GfmTableStyling import org.jetbrains.jewel.markdown.extensions.github.tables.RowBackgroundStyle +/** Creates a default [GfmTableStyling] for the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableStyling.Companion.create( @@ -24,6 +25,7 @@ public fun GfmTableStyling.Companion.create( headerBaseFontWeight: FontWeight = FontWeight.SemiBold, ): GfmTableStyling = GfmTableStyling(colors, metrics, headerBaseFontWeight) +/** Creates a default [GfmTableColors] for the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableColors.Companion.create( @@ -33,6 +35,7 @@ public fun GfmTableColors.Companion.create( rowBackgroundStyle: RowBackgroundStyle = RowBackgroundStyle.Striped, ): GfmTableColors = GfmTableColors(borderColor, rowBackgroundColor, alternateRowBackgroundColor, rowBackgroundStyle) +/** Creates a default [GfmTableMetrics] for the current IntelliJ LaF theme. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableMetrics.Companion.create( diff --git a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/IntUiMarkdownBlockRendererExtensions.kt b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/IntUiMarkdownBlockRendererExtensions.kt index 4f579c2ed3e1..6558bbb0d828 100644 --- a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/IntUiMarkdownBlockRendererExtensions.kt +++ b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/IntUiMarkdownBlockRendererExtensions.kt @@ -11,6 +11,7 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownBlockRenderer import org.jetbrains.jewel.markdown.rendering.MarkdownStyling import org.jetbrains.jewel.markdown.rendering.create +/** Creates an Int UI light [MarkdownBlockRenderer]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownBlockRenderer.Companion.light( @@ -19,6 +20,7 @@ public fun MarkdownBlockRenderer.Companion.light( inlineRenderer: InlineMarkdownRenderer = InlineMarkdownRenderer.create(rendererExtensions), ): MarkdownBlockRenderer = DefaultMarkdownBlockRenderer(styling, rendererExtensions, inlineRenderer) +/** Creates an Int UI dark [MarkdownBlockRenderer]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownBlockRenderer.Companion.dark( diff --git a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/IntUiMarkdownStyling.kt b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/IntUiMarkdownStyling.kt index 487824d5b444..3e0349476a17 100644 --- a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/IntUiMarkdownStyling.kt +++ b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/IntUiMarkdownStyling.kt @@ -42,6 +42,7 @@ import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.List.Unordered import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.Paragraph import org.jetbrains.jewel.markdown.rendering.MarkdownStyling.ThematicBreak +/** Creates an Int UI light [MarkdownStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownStyling.Companion.light( @@ -60,6 +61,7 @@ public fun MarkdownStyling.Companion.light( ): MarkdownStyling = MarkdownStyling(blockVerticalSpacing, paragraph, heading, blockQuote, code, list, image, thematicBreak, htmlBlock) +/** Creates an Int UI dark [MarkdownStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun MarkdownStyling.Companion.dark( @@ -78,18 +80,21 @@ public fun MarkdownStyling.Companion.dark( ): MarkdownStyling = MarkdownStyling(blockVerticalSpacing, paragraph, heading, blockQuote, code, list, image, thematicBreak, htmlBlock) +/** Creates an Int UI light [Paragraph]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Paragraph.Companion.light( inlinesStyling: InlinesStyling = InlinesStyling.light(defaultTextStyle, defaultEditorTextStyle) ): Paragraph = Paragraph(inlinesStyling) +/** Creates an Int UI dark [Paragraph]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Paragraph.Companion.dark( inlinesStyling: InlinesStyling = InlinesStyling.dark(defaultTextStyle, defaultEditorTextStyle) ): Paragraph = Paragraph(inlinesStyling) +/** Creates an Int UI light [Heading]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.Companion.light( @@ -145,6 +150,7 @@ public fun Heading.Companion.light( ), ): Heading = Heading(h1, h2, h3, h4, h5, h6) +/** Creates an Int UI dark [Heading]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.Companion.dark( @@ -200,6 +206,7 @@ public fun Heading.Companion.dark( ), ): Heading = Heading(h1, h2, h3, h4, h5, h6) +/** Creates an Int UI light [Heading.H1]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H1.Companion.light( @@ -216,6 +223,7 @@ public fun Heading.H1.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H1 = Heading.H1(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates an Int UI dark [Heading.H1]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H1.Companion.dark( @@ -232,6 +240,7 @@ public fun Heading.H1.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H1 = Heading.H1(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates an Int UI light [Heading.H2]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H2.Companion.light( @@ -248,6 +257,7 @@ public fun Heading.H2.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H2 = Heading.H2(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates an Int UI dark [Heading.H2]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Heading.H2.Companion.dark( @@ -264,9 +274,10 @@ public fun Heading.H2.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H2 = Heading.H2(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates an Int UI light [Heading.H3]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H3.Companion.light( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -281,9 +292,10 @@ public fun Heading.H3.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H3 = Heading.H3(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates an Int UI dark [Heading.H3]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H3.Companion.dark( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -298,9 +310,10 @@ public fun Heading.H3.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H3 = Heading.H3(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates an Int UI light [Heading.H4]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H4.Companion.light( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -315,9 +328,10 @@ public fun Heading.H4.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H4 = Heading.H4(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// This doesn't match Int UI specs as there is no spec for HTML rendering +/** Creates an Int UI dark [Heading.H4]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// This doesn't match Int UI specs as there is no spec for HTML rendering public fun Heading.H4.Companion.dark( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -332,9 +346,10 @@ public fun Heading.H4.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H4 = Heading.H4(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// H5 is identical to H4 and H6 +/** Creates an Int UI light [Heading.H5]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// H5 is identical to H4 and H6 public fun Heading.H5.Companion.light( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -349,9 +364,10 @@ public fun Heading.H5.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H5 = Heading.H5(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// H5 is identical to H4 and H6 +/** Creates an Int UI dark [Heading.H5]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// H5 is identical to H4 and H6 public fun Heading.H5.Companion.dark( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -366,9 +382,10 @@ public fun Heading.H5.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H5 = Heading.H5(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// H6 is identical to H4 and H5 +/** Creates an Int UI light [Heading.H6]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// H6 is identical to H4 and H5 public fun Heading.H6.Companion.light( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -384,9 +401,10 @@ public fun Heading.H6.Companion.light( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H6 = Heading.H6(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) -// H6 is identical to H4 and H5 +/** Creates an Int UI dark [Heading.H6]. */ @ApiStatus.Experimental @ExperimentalJewelApi +// H6 is identical to H4 and H5 public fun Heading.H6.Companion.dark( baseTextStyle: TextStyle = defaultTextStyle.copy( @@ -402,6 +420,7 @@ public fun Heading.H6.Companion.dark( padding: PaddingValues = PaddingValues(top = 24.dp, bottom = 16.dp), ): Heading.H6 = Heading.H6(inlinesStyling, underlineWidth, underlineColor, underlineGap, padding) +/** Creates an Int UI light [BlockQuote]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun BlockQuote.Companion.light( @@ -413,6 +432,7 @@ public fun BlockQuote.Companion.light( textColor: Color = Color(0xFF656d76), ): BlockQuote = BlockQuote(padding, lineWidth, lineColor, pathEffect, strokeCap, textColor) +/** Creates an Int UI dark [BlockQuote]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun BlockQuote.Companion.dark( @@ -424,6 +444,7 @@ public fun BlockQuote.Companion.dark( textColor: Color = Color(0xFF848d97), ): BlockQuote = BlockQuote(padding, lineWidth, lineColor, pathEffect, strokeCap, textColor) +/** Creates an Int UI light [List]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun List.Companion.light( @@ -445,6 +466,7 @@ public fun List.Companion.light( ), ): List = List(ordered, unordered) +/** Creates an Int UI dark [List]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun List.Companion.dark( @@ -493,6 +515,7 @@ public fun Ordered.Companion.light( ), ) +/** Creates an Int UI light [Ordered]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Ordered.Companion.light( @@ -548,6 +571,7 @@ public fun Ordered.Companion.dark( ), ) +/** Creates an Int UI dark [Ordered]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Ordered.Companion.dark( @@ -599,6 +623,7 @@ public fun Unordered.Companion.light( Unordered.BulletCharStyles(firstLevel = '•', secondLevel = '◦', thirdLevel = '▪'), ) +/** Creates an Int UI light [Unordered]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Unordered.Companion.light( @@ -646,6 +671,7 @@ public fun Unordered.Companion.dark( Unordered.BulletCharStyles(firstLevel = '•', secondLevel = '◦', thirdLevel = '▪'), ) +/** Creates an Int UI dark [Unordered]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Unordered.Companion.dark( @@ -670,6 +696,7 @@ public fun Unordered.Companion.dark( bulletCharStyles, ) +/** Creates an Int UI light [Code]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Code.Companion.light( @@ -678,6 +705,7 @@ public fun Code.Companion.light( fenced: Fenced = Fenced.light(editorTextStyle), ): Code = Code(indented, fenced) +/** Creates an Int UI dark [Code]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Code.Companion.dark( @@ -686,6 +714,7 @@ public fun Code.Companion.dark( fenced: Fenced = Fenced.dark(editorTextStyle), ): Code = Code(indented, fenced) +/** Creates an Int UI light [Indented]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Indented.Companion.light( @@ -700,6 +729,7 @@ public fun Indented.Companion.light( ): Indented = Indented(editorTextStyle, padding, shape, background, borderWidth, borderColor, fillWidth, scrollsHorizontally) +/** Creates an Int UI dark [Indented]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Indented.Companion.dark( @@ -714,6 +744,7 @@ public fun Indented.Companion.dark( ): Indented = Indented(editorTextStyle, padding, shape, background, borderWidth, borderColor, fillWidth, scrollsHorizontally) +/** Creates an Int UI light [Fenced]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Fenced.Companion.light( @@ -743,6 +774,7 @@ public fun Fenced.Companion.light( infoPosition, ) +/** Creates an Int UI dark [Fenced]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Fenced.Companion.dark( @@ -772,6 +804,7 @@ public fun Fenced.Companion.dark( infoPosition, ) +/** Creates an Int UI default [Image]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun Image.Companion.default( @@ -784,6 +817,7 @@ public fun Image.Companion.default( borderColor: Color = Color.Unspecified, ): Image = Image(alignment, contentScale, padding, shape, background, borderWidth, borderColor) +/** Creates an Int UI light [ThematicBreak]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ThematicBreak.Companion.light( @@ -792,6 +826,7 @@ public fun ThematicBreak.Companion.light( lineColor: Color = Color.LightGray, ): ThematicBreak = ThematicBreak(padding, lineWidth, lineColor) +/** Creates an Int UI dark [ThematicBreak]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ThematicBreak.Companion.dark( @@ -800,6 +835,7 @@ public fun ThematicBreak.Companion.dark( lineColor: Color = Color.DarkGray, ): ThematicBreak = ThematicBreak(padding, lineWidth, lineColor) +/** Creates an Int UI light [HtmlBlock]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun HtmlBlock.Companion.light( @@ -812,6 +848,7 @@ public fun HtmlBlock.Companion.light( fillWidth: Boolean = true, ): HtmlBlock = HtmlBlock(textStyle, padding, shape, background, borderWidth, borderColor, fillWidth) +/** Creates an Int UI dark [HtmlBlock]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun HtmlBlock.Companion.dark( @@ -824,6 +861,7 @@ public fun HtmlBlock.Companion.dark( fillWidth: Boolean = true, ): HtmlBlock = HtmlBlock(textStyle, padding, shape, background, borderWidth, borderColor, fillWidth) +/** Creates an Int UI light [InlinesStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun InlinesStyling.Companion.light( @@ -907,6 +945,7 @@ public fun InlinesStyling.Companion.light( inlineHtml = inlineHtml, ) +/** Creates an Int UI dark [InlinesStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun InlinesStyling.Companion.dark( diff --git a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/alerts/IntUiGitHubAlertStyling.kt b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/alerts/IntUiGitHubAlertStyling.kt index cb7204d1039b..a451011e7abd 100644 --- a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/alerts/IntUiGitHubAlertStyling.kt +++ b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/alerts/IntUiGitHubAlertStyling.kt @@ -19,6 +19,7 @@ import org.jetbrains.jewel.markdown.extensions.github.alerts.TipAlertStyling import org.jetbrains.jewel.markdown.extensions.github.alerts.WarningAlertStyling import org.jetbrains.jewel.ui.icon.IconKey +/** Creates an Int UI light [AlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun AlertStyling.Companion.light( @@ -29,6 +30,7 @@ public fun AlertStyling.Companion.light( caution: CautionAlertStyling = CautionAlertStyling.light(), ): AlertStyling = AlertStyling(note, tip, important, warning, caution) +/** Creates an Int UI dark [AlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun AlertStyling.Companion.dark( @@ -39,6 +41,7 @@ public fun AlertStyling.Companion.dark( caution: CautionAlertStyling = CautionAlertStyling.dark(), ): AlertStyling = AlertStyling(note, tip, important, warning, caution) +/** Creates an Int UI light [NoteAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun NoteAlertStyling.Companion.light( @@ -64,6 +67,7 @@ public fun NoteAlertStyling.Companion.light( textColor, ) +/** Creates an Int UI dark [NoteAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun NoteAlertStyling.Companion.dark( @@ -89,6 +93,7 @@ public fun NoteAlertStyling.Companion.dark( textColor, ) +/** Creates an Int UI light [TipAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun TipAlertStyling.Companion.light( @@ -114,6 +119,7 @@ public fun TipAlertStyling.Companion.light( textColor, ) +/** Creates an Int UI dark [TipAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun TipAlertStyling.Companion.dark( @@ -139,6 +145,7 @@ public fun TipAlertStyling.Companion.dark( textColor, ) +/** Creates an Int UI light [ImportantAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ImportantAlertStyling.Companion.light( @@ -164,6 +171,7 @@ public fun ImportantAlertStyling.Companion.light( textColor, ) +/** Creates an Int UI dark [ImportantAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun ImportantAlertStyling.Companion.dark( @@ -189,6 +197,7 @@ public fun ImportantAlertStyling.Companion.dark( textColor, ) +/** Creates an Int UI light [WarningAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun WarningAlertStyling.Companion.light( @@ -214,6 +223,7 @@ public fun WarningAlertStyling.Companion.light( textColor, ) +/** Creates an Int UI dark [WarningAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun WarningAlertStyling.Companion.dark( @@ -239,6 +249,7 @@ public fun WarningAlertStyling.Companion.dark( textColor, ) +/** Creates an Int UI light [CautionAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun CautionAlertStyling.Companion.light( @@ -264,6 +275,7 @@ public fun CautionAlertStyling.Companion.light( textColor, ) +/** Creates an Int UI dark [CautionAlertStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun CautionAlertStyling.Companion.dark( diff --git a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/tables/IntUiGitHubTableStyling.kt b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/tables/IntUiGitHubTableStyling.kt index da10faf3136b..894e40c4291b 100644 --- a/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/tables/IntUiGitHubTableStyling.kt +++ b/platform/jewel/markdown/int-ui-standalone-styling/src/main/kotlin/org/jetbrains/jewel/intui/markdown/standalone/styling/extensions/github/tables/IntUiGitHubTableStyling.kt @@ -13,6 +13,7 @@ import org.jetbrains.jewel.markdown.extensions.github.tables.GfmTableMetrics import org.jetbrains.jewel.markdown.extensions.github.tables.GfmTableStyling import org.jetbrains.jewel.markdown.extensions.github.tables.RowBackgroundStyle +/** Creates an Int UI light [GfmTableStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableStyling.Companion.light( @@ -21,6 +22,7 @@ public fun GfmTableStyling.Companion.light( headerBaseFontWeight: FontWeight = FontWeight.SemiBold, ): GfmTableStyling = GfmTableStyling(colors, metrics, headerBaseFontWeight) +/** Creates an Int UI dark [GfmTableStyling]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableStyling.Companion.dark( @@ -29,6 +31,7 @@ public fun GfmTableStyling.Companion.dark( headerBaseFontWeight: FontWeight = FontWeight.SemiBold, ): GfmTableStyling = GfmTableStyling(colors, metrics, headerBaseFontWeight) +/** Creates an Int UI light [GfmTableColors]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableColors.Companion.light( @@ -38,6 +41,7 @@ public fun GfmTableColors.Companion.light( rowBackgroundStyle: RowBackgroundStyle = RowBackgroundStyle.Striped, ): GfmTableColors = GfmTableColors(borderColor, rowBackgroundColor, alternateRowBackgroundColor, rowBackgroundStyle) +/** Creates an Int UI dark [GfmTableColors]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableColors.Companion.dark( @@ -47,6 +51,7 @@ public fun GfmTableColors.Companion.dark( rowBackgroundStyle: RowBackgroundStyle = RowBackgroundStyle.Striped, ): GfmTableColors = GfmTableColors(borderColor, rowBackgroundColor, alternateRowBackgroundColor, rowBackgroundStyle) +/** Creates an Int UI default [GfmTableMetrics]. */ @ApiStatus.Experimental @ExperimentalJewelApi public fun GfmTableMetrics.Companion.defaults( diff --git a/platform/jewel/markdown/testing/src/main/kotlin/org/jetbrains/jewel/markdown/testing/MarkdownTestTheme.kt b/platform/jewel/markdown/testing/src/main/kotlin/org/jetbrains/jewel/markdown/testing/MarkdownTestTheme.kt index 4b1a6cc19f60..a10f9298910a 100644 --- a/platform/jewel/markdown/testing/src/main/kotlin/org/jetbrains/jewel/markdown/testing/MarkdownTestTheme.kt +++ b/platform/jewel/markdown/testing/src/main/kotlin/org/jetbrains/jewel/markdown/testing/MarkdownTestTheme.kt @@ -45,6 +45,7 @@ import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle import org.jetbrains.jewel.ui.component.styling.ScrollbarVisibility import org.jetbrains.jewel.ui.component.styling.TrackClickBehavior +/** Applies a minimal test theme for Markdown rendering tests, providing stub styles and a [NoOpCodeHighlighter]. */ @Composable fun MarkdownTestTheme(content: @Composable () -> Unit) { CompositionLocalProvider( @@ -57,9 +58,11 @@ fun MarkdownTestTheme(content: @Composable () -> Unit) { } } +/** Creates a minimal [DividerStyle] with a 1dp black line for use in Markdown rendering tests. */ fun createMarkdownTestDividerStyle() = DividerStyle(color = Color.Black, metrics = DividerMetrics(thickness = 1.dp, startIndent = 0.dp)) +/** Creates a minimal [ScrollbarStyle] with stub colors and metrics for use in Markdown rendering tests. */ fun createMarkdownTestScrollbarStyle() = ScrollbarStyle( colors = @@ -91,6 +94,7 @@ fun createMarkdownTestScrollbarStyle() = ), ) +/** Creates a minimal [ThemeDefinition] with stub colors and metrics for use in Markdown rendering tests. */ fun createMarkdownTestThemeDefinition(): ThemeDefinition = ThemeDefinition( name = "Test", diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/ShowcaseIcons.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/ShowcaseIcons.kt index 784bcaef73f0..93cf40d8c6d6 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/ShowcaseIcons.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/ShowcaseIcons.kt @@ -3,27 +3,62 @@ package org.jetbrains.jewel.samples.showcase import org.jetbrains.jewel.ui.icon.PathIconKey +/** Icon keys used throughout the Jewel showcase application. */ public object ShowcaseIcons { + /** Icon for the components menu navigation item. */ public val componentsMenu: PathIconKey = PathIconKey("icons/structure.svg", ShowcaseIcons::class.java) + + /** The Jewel logo icon. */ public val jewelLogo: PathIconKey = PathIconKey("icons/jewel-logo.svg", ShowcaseIcons::class.java) + + /** The GitHub icon. */ public val gitHub: PathIconKey = PathIconKey("icons/github.svg", ShowcaseIcons::class.java) + + /** The Markdown icon. */ public val markdown: PathIconKey = PathIconKey("icons/markdown.svg", ShowcaseIcons::class.java) + + /** Icon representing the dark theme. */ public val themeDark: PathIconKey = PathIconKey("icons/darkTheme.svg", ShowcaseIcons::class.java) + + /** Icon representing the light theme. */ public val themeLight: PathIconKey = PathIconKey("icons/lightTheme.svg", ShowcaseIcons::class.java) + + /** Icon representing the light theme with a light header. */ public val themeLightWithLightHeader: PathIconKey = PathIconKey("icons/lightWithLightHeaderTheme.svg", ShowcaseIcons::class.java) + + /** Icon representing the system (auto) theme. */ public val themeSystem: PathIconKey = PathIconKey("icons/systemTheme.svg", ShowcaseIcons::class.java) + + /** Icon for the welcome screen. */ public val welcome: PathIconKey = PathIconKey("icons/meetNewUi.svg", ShowcaseIcons::class.java) + + /** The sunny icon. */ public val sunny: PathIconKey = PathIconKey("icons/sunny.svg", ShowcaseIcons::class.java) + /** Icon representing a terminal/console. */ public val terminal: PathIconKey = PathIconKey("icons/terminal.svg", ShowcaseIcons::class.java) + /** Icon keys for individual UI component sections in the showcase. */ public object Components { + /** Icon for the Badge component section. */ public val badge: PathIconKey = PathIconKey("icons/components/badge.svg", ShowcaseIcons::class.java) + + /** Icon for the Banners component section. */ public val banners: PathIconKey = PathIconKey("icons/components/banners.svg", ShowcaseIcons::class.java) + + /** Icon for the Borders component section. */ public val borders: PathIconKey = PathIconKey("icons/components/borders.svg", ShowcaseIcons::class.java) + + /** Icon for the Brush/paint component section. */ public val brush: PathIconKey = PathIconKey("icons/components/brush.svg", ShowcaseIcons::class.java) + + /** Icon for the Button component section. */ public val button: PathIconKey = PathIconKey("icons/components/button.svg", ShowcaseIcons::class.java) + + /** Icon for the Checkbox component section. */ public val checkbox: PathIconKey = PathIconKey("icons/components/checkBox.svg", ShowcaseIcons::class.java) + + /** Icon for the ComboBox component section. */ public val comboBox: PathIconKey = PathIconKey("icons/components/comboBox.svg", ShowcaseIcons::class.java) /** Icon for the GotIt component section. */ @@ -31,25 +66,57 @@ public object ShowcaseIcons { /** Icon for the Links component section. */ public val links: PathIconKey = PathIconKey("icons/components/links.svg", ShowcaseIcons::class.java) + + /** Icon for the Menu component section. */ public val menu: PathIconKey = PathIconKey("icons/components/menu.svg", ShowcaseIcons::class.java) + + /** Icon for the ProgressBar component section. */ public val progressBar: PathIconKey = PathIconKey("icons/components/progressbar.svg", ShowcaseIcons::class.java) + + /** Icon for the RadioButton component section. */ public val radioButton: PathIconKey = PathIconKey("icons/components/radioButton.svg", ShowcaseIcons::class.java) + + /** Icon for the Scrollbar component section. */ public val scrollbar: PathIconKey = PathIconKey("icons/components/scrollbar.svg", ShowcaseIcons::class.java) + + /** Icon for the SegmentedControls component section. */ public val segmentedControls: PathIconKey = PathIconKey("icons/components/segmentedControl.svg", ShowcaseIcons::class.java) + + /** Icon for the Slider component section. */ public val slider: PathIconKey = PathIconKey("icons/components/slider.svg", ShowcaseIcons::class.java) + + /** Icon for the SplitLayout component section. */ public val splitlayout: PathIconKey = PathIconKey("icons/components/splitLayout.svg", ShowcaseIcons::class.java) + + /** Icon for the Tabs component section. */ public val tabs: PathIconKey = PathIconKey("icons/components/tabs.svg", ShowcaseIcons::class.java) + + /** Icon for the TextArea component section. */ public val textArea: PathIconKey = PathIconKey("icons/components/textArea.svg", ShowcaseIcons::class.java) + + /** Icon for the TextField component section. */ public val textField: PathIconKey = PathIconKey("icons/components/textField.svg", ShowcaseIcons::class.java) + + /** Icon for the Toolbar component section. */ public val toolbar: PathIconKey = PathIconKey("icons/components/toolbar.svg", ShowcaseIcons::class.java) + + /** Icon for the Tooltip component section. */ public val tooltip: PathIconKey = PathIconKey("icons/components/tooltip.svg", ShowcaseIcons::class.java) + + /** Icon for the Tree component section. */ public val tree: PathIconKey = PathIconKey("icons/components/tree.svg", ShowcaseIcons::class.java) + + /** Icon for the Typography component section. */ public val typography: PathIconKey = PathIconKey("icons/components/typography.svg", ShowcaseIcons::class.java) + + /** Icon for the SpeedSearch component section. */ public val speedSearch: PathIconKey = PathIconKey("icons/components/speedSearch.svg", ShowcaseIcons::class.java) } + /** Icon keys for programming language representations used in the showcase. */ public object ProgrammingLanguages { + /** Icon representing the Kotlin programming language. */ public val Kotlin: PathIconKey = PathIconKey("icons/kotlin.svg", ShowcaseIcons::class.java) } } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Badges.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Badges.kt index 434fa6a2366b..ce8cceca2d0a 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Badges.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Badges.kt @@ -30,6 +30,7 @@ import org.jetbrains.jewel.ui.component.styling.BadgeColors import org.jetbrains.jewel.ui.component.styling.BadgeStyle import org.jetbrains.jewel.ui.theme.badgeStyle +/** Showcases the Badge component. */ @Composable public fun Badges(modifier: Modifier = Modifier) { VerticallyScrollableContainer(modifier.fillMaxSize()) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Banners.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Banners.kt index a4b977ec971e..d3e7e7dbe74f 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Banners.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Banners.kt @@ -50,6 +50,7 @@ private const val LONG_IPSUM = "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa " + "qui officia deserunt mollit anim id est laborum." +/** Showcases the Banner components. */ @Composable public fun Banners(modifier: Modifier = Modifier) { Column(modifier) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Borders.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Borders.kt index f65912859412..51659d8fd80a 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Borders.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Borders.kt @@ -41,6 +41,7 @@ import org.jetbrains.jewel.ui.outline import org.jetbrains.jewel.ui.theme.colorPalette import org.jetbrains.jewel.ui.typography +/** Showcases the Borders component. */ @Composable public fun Borders(modifier: Modifier = Modifier) { Column(modifier, verticalArrangement = Arrangement.spacedBy(16.dp)) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt index d5483dec80e2..281df782c1ef 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt @@ -71,6 +71,7 @@ import org.jetbrains.jewel.ui.theme.defaultSplitButtonStyle import org.jetbrains.jewel.ui.theme.outlinedSplitButtonStyle import org.jetbrains.jewel.ui.theme.transparentIconButtonStyle +/** Showcases the Button component. */ @Composable public fun Buttons(modifier: Modifier = Modifier) { VerticallyScrollableContainer(modifier.fillMaxSize()) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Checkboxes.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Checkboxes.kt index 0783741350d7..f9b51f465a0f 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Checkboxes.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Checkboxes.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.unit.dp import org.jetbrains.jewel.ui.Outline import org.jetbrains.jewel.ui.component.TriStateCheckboxRow +/** Showcases the Checkbox component. */ @Composable public fun Checkboxes(modifier: Modifier = Modifier) { Row(modifier, horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt index a40bd0c23136..4aaabb2b4e1d 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt @@ -52,6 +52,7 @@ import org.jetbrains.jewel.ui.component.search.highlightSpeedSearchMatches import org.jetbrains.jewel.ui.component.search.highlightTextSearch import org.jetbrains.jewel.ui.theme.colorPalette +/** Showcases the Chip, Tree, and SelectableLazyColumn components. */ @Composable public fun ChipsAndTrees(modifier: Modifier = Modifier) { Row(modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(16.dp)) { @@ -81,6 +82,7 @@ public fun ChipsAndTrees(modifier: Modifier = Modifier) { } } +/** Showcases the Chip component. */ @Composable public fun ChipsSample(modifier: Modifier = Modifier) { Column(modifier, verticalArrangement = Arrangement.spacedBy(8.dp)) { @@ -113,6 +115,7 @@ public fun ChipsSample(modifier: Modifier = Modifier) { } } +/** Showcases the Tree component. */ @Composable public fun TreeSample(modifier: Modifier = Modifier) { var isRandom by remember { mutableStateOf(false) } @@ -171,6 +174,7 @@ public fun TreeSample(modifier: Modifier = Modifier) { } } +/** Showcases the SelectableLazyColumn component. */ @Composable public fun SelectableLazyColumnSample(modifier: Modifier = Modifier) { var randomIndex by remember { mutableStateOf(-1) } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ComboBoxes.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ComboBoxes.kt index 1d2e5cb17afb..c297068db607 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ComboBoxes.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ComboBoxes.kt @@ -78,6 +78,7 @@ private val languageOptions = ProgrammingLanguage("Ruby", AllIconsKeys.Language.Ruby), ) +/** Showcases the ComboBox component. */ @Composable public fun ComboBoxes(modifier: Modifier = Modifier) { Column(modifier.verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(16.dp)) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Icons.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Icons.kt index 2ade1c531aef..dc275dd48343 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Icons.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Icons.kt @@ -45,6 +45,7 @@ import org.jetbrains.jewel.ui.painter.hints.Size import org.jetbrains.jewel.ui.painter.hints.Stroke import org.jetbrains.jewel.ui.theme.colorPalette +/** Showcases the [Icon] component. */ @Composable public fun Icons(modifier: Modifier = Modifier) { Column(modifier, verticalArrangement = Arrangement.spacedBy(16.dp)) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Links.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Links.kt index 81e87871bd7c..7ef9e3c3fe91 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Links.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Links.kt @@ -26,6 +26,7 @@ import org.jetbrains.jewel.ui.component.styling.LinkStyle import org.jetbrains.jewel.ui.component.styling.LinkUnderlineBehavior import org.jetbrains.jewel.ui.theme.linkStyle +/** Showcases the Link component. */ @Composable public fun Links(modifier: Modifier = Modifier) { val alwaysUnderline = JewelTheme.linkStyle.copy(underlineBehavior = LinkUnderlineBehavior.ShowAlways) diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Menus.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Menus.kt index f6c92e6eba03..cb60cbcf7be3 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Menus.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Menus.kt @@ -25,6 +25,7 @@ import org.jetbrains.jewel.ui.component.separator import org.jetbrains.jewel.ui.icons.AllIconsKeys import org.jetbrains.jewel.ui.typography +/** Showcases the [PopupMenu] component. */ @Composable public fun Menus(modifier: Modifier = Modifier) { VerticallyScrollableContainer(modifier.fillMaxSize()) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ProgressBar.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ProgressBar.kt index b248aa07e8f2..3bd1315a2139 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ProgressBar.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ProgressBar.kt @@ -24,6 +24,7 @@ import org.jetbrains.jewel.ui.component.HorizontalProgressBar import org.jetbrains.jewel.ui.component.IndeterminateHorizontalProgressBar import org.jetbrains.jewel.ui.component.Text +/** Showcases the ProgressBar component. */ @Composable public fun ProgressBar(modifier: Modifier = Modifier) { val transition = rememberInfiniteTransition() diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/RadioButtons.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/RadioButtons.kt index 89324d06ed8a..c67561daa715 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/RadioButtons.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/RadioButtons.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.unit.dp import org.jetbrains.jewel.ui.Outline import org.jetbrains.jewel.ui.component.RadioButtonRow +/** Showcases the [RadioButtonRow] component. */ @Composable public fun RadioButtons(modifier: Modifier = Modifier) { Row(modifier, horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Scrollbars.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Scrollbars.kt index 893d7cb1b4c9..c2407d2981e3 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Scrollbars.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Scrollbars.kt @@ -79,6 +79,7 @@ import org.jetbrains.jewel.ui.typography import org.jetbrains.skiko.OS import org.jetbrains.skiko.hostOs +/** Showcases the Scrollbar component. */ @Composable public fun Scrollbars( alwaysVisibleScrollbarVisibility: ScrollbarVisibility, diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SegmentedControls.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SegmentedControls.kt index 76e61530c5a3..8fcdf6598bb0 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SegmentedControls.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SegmentedControls.kt @@ -13,6 +13,7 @@ import org.jetbrains.jewel.ui.component.SegmentedControl import org.jetbrains.jewel.ui.component.SegmentedControlButtonData import org.jetbrains.jewel.ui.component.Text +/** Showcases the [SegmentedControl] component. */ @Composable public fun SegmentedControls(modifier: Modifier = Modifier) { var selectedButtonIndex by remember { mutableIntStateOf(0) } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Slider.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Slider.kt index 0141d73ccbcb..dd5f89c01c7b 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Slider.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Slider.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import org.jetbrains.jewel.ui.component.Slider +/** Showcases the [Slider][org.jetbrains.jewel.ui.component.Slider] component. */ @Composable public fun Sliders(modifier: Modifier = Modifier) { Column(modifier, verticalArrangement = Arrangement.spacedBy(16.dp)) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SplitLayouts.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SplitLayouts.kt index 7b1f5135a846..2702e4ca548e 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SplitLayouts.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/SplitLayouts.kt @@ -28,6 +28,7 @@ import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.TextField import org.jetbrains.jewel.ui.component.VerticalSplitLayout +/** Showcases the [HorizontalSplitLayout] and [VerticalSplitLayout] components. */ @Composable public fun SplitLayouts( outerSplitState: SplitLayoutState, diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tabs.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tabs.kt index b6920deff405..bfed56c68a5e 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tabs.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tabs.kt @@ -38,6 +38,7 @@ import org.jetbrains.jewel.ui.painter.rememberResourcePainterProvider import org.jetbrains.jewel.ui.theme.defaultTabStyle import org.jetbrains.jewel.ui.theme.editorTabStyle +/** Showcases the [TabStrip] component. */ @Composable public fun Tabs(modifier: Modifier = Modifier) { Column(modifier) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextAreas.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextAreas.kt index bffac0d31687..2cc18f200f1a 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextAreas.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextAreas.kt @@ -33,6 +33,7 @@ private const val LOREM_IPSUM = "Duis ultricies, mauris in aliquam interdum, orci nulla finibus massa, a tristique urna sapien vel quam. \n" + "Sed nec sapien nec dui rhoncus bibendum. Sed blandit bibendum libero." +/** Showcases the [TextArea] component. */ @Composable public fun TextAreas(modifier: Modifier = Modifier) { VerticallyScrollableContainer(modifier.fillMaxSize()) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextFields.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextFields.kt index 9120cb096223..436809927bd8 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextFields.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/TextFields.kt @@ -37,6 +37,7 @@ import org.jetbrains.jewel.ui.icons.AllIconsKeys import org.jetbrains.jewel.ui.painter.hints.Stateful import org.jetbrains.jewel.ui.theme.textFieldStyle +/** Showcases the [TextField] component. */ @Composable public fun TextFields(modifier: Modifier = Modifier) { VerticallyScrollableContainer(modifier.fillMaxSize()) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tooltips.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tooltips.kt index 6fe61b7afe9f..9ce500af10e3 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tooltips.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Tooltips.kt @@ -29,6 +29,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalTooltipStyle import org.jetbrains.jewel.ui.component.styling.TooltipAutoHideBehavior import org.jetbrains.jewel.ui.component.styling.TooltipStyle +/** Showcases the [Tooltip] component. */ @Composable public fun Tooltips(modifier: Modifier = Modifier) { var enabled by remember { mutableStateOf(true) } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Typography.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Typography.kt index ce5b2b55c82d..e2c653992a14 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Typography.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Typography.kt @@ -35,6 +35,7 @@ private const val LONG_TEXT = "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." +/** Showcases the Typography component. */ @Composable public fun TypographyShowcase(modifier: Modifier = Modifier) { Column(modifier) { diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt index 12a885d54faf..0b58447bbc0b 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt @@ -38,6 +38,10 @@ import org.jetbrains.jewel.ui.painter.hints.Size import org.jetbrains.jewel.ui.theme.iconButtonStyle import org.jetbrains.jewel.ui.typography +/** + * Showcases the components view, combining a toolbar for navigation and a content panel that renders the currently + * selected component demo. + */ @ExperimentalLayoutApi @Composable public fun ComponentsView( @@ -61,6 +65,10 @@ public fun ComponentsView( } } +/** + * Renders the vertical icon toolbar used to navigate between component demo views, showing a selectable icon button for + * each available [ViewInfo]. + */ @ExperimentalLayoutApi @Composable public fun ComponentsToolBar( diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsViewModel.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsViewModel.kt index d965bf2b2c6d..99f0ca0365c8 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsViewModel.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsViewModel.kt @@ -35,6 +35,7 @@ import org.jetbrains.jewel.samples.showcase.components.TypographyShowcase import org.jetbrains.jewel.ui.component.SplitLayoutState import org.jetbrains.jewel.ui.component.styling.ScrollbarVisibility +/** ViewModel that holds the list of component showcase views and tracks which view is currently selected. */ public class ComponentsViewModel( alwaysVisibleScrollbarVisibility: ScrollbarVisibility.AlwaysVisible, whenScrollingScrollbarVisibility: ScrollbarVisibility.WhenScrolling, @@ -43,6 +44,7 @@ public class ComponentsViewModel( private var verticalSplitState by mutableStateOf(SplitLayoutState(0.5f)) private var innerSplitState by mutableStateOf(SplitLayoutState(0.5f)) + /** Returns the list of all available component showcase views. */ public fun getViews(): SnapshotStateList = views private val views: SnapshotStateList = @@ -119,8 +121,10 @@ public class ComponentsViewModel( private var _currentView: ViewInfo by mutableStateOf(views.first()) + /** Returns the currently selected component showcase view. */ public fun getCurrentView(): ViewInfo = _currentView + /** Sets [view] as the currently selected component showcase view. */ public fun setCurrentView(view: ViewInfo) { _currentView = view } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ViewInfo.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ViewInfo.kt index 638dc36aadfb..0f2a7dd744fe 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ViewInfo.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ViewInfo.kt @@ -7,10 +7,14 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.skiko.hostOs +/** Represents a platform-specific keyboard shortcut, with separate key sets for macOS, Windows, and Linux. */ @GenerateDataFunctions public class KeyBinding( + /** The key set for macOS. */ public val macOs: Set = emptySet(), + /** The key set for Windows. */ public val windows: Set = emptySet(), + /** The key set for Linux. */ public val linux: Set = emptySet(), ) { override fun equals(other: Any?): Boolean { @@ -35,9 +39,11 @@ public class KeyBinding( override fun toString(): String = "KeyBinding(macOs=$macOs, windows=$windows, linux=$linux)" + /** Companion object for [KeyBinding]. */ public companion object } +/** Returns the key set from this [KeyBinding] that corresponds to the current operating system. */ public fun KeyBinding.forCurrentOs(): Set = when { hostOs.isMacOS -> macOs @@ -45,11 +51,19 @@ public fun KeyBinding.forCurrentOs(): Set = else -> windows } +/** + * Holds the metadata and composable content for a single showcase view entry, including its title, icon, optional + * keyboard shortcut, and the composable that renders the view. + */ @GenerateDataFunctions public class ViewInfo( + /** The display title of the view. */ public val title: String, + /** The icon key used to identify the view's icon. */ public val iconKey: IconKey, + /** The optional keyboard shortcut associated with this view. */ public val keyboardShortcut: KeyBinding? = null, + /** The composable that renders the view content. */ public val content: @Composable () -> Unit, ) { override fun equals(other: Any?): Boolean { @@ -83,5 +97,6 @@ public class ViewInfo( ")" } + /** Companion object for [ViewInfo]. */ public companion object } diff --git a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt index 7da03ca7a802..6d8a56cfe2c7 100644 --- a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt +++ b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/IntUiThemes.kt @@ -3,17 +3,29 @@ package org.jetbrains.jewel.samples.standalone import org.jetbrains.skiko.SystemTheme import org.jetbrains.skiko.currentSystemTheme +/** The available Int UI themes for the standalone sample application. */ public enum class IntUiThemes { + /** The standard light theme. */ Light, + + /** The light theme with a light-colored title bar header. */ LightWithLightHeader, + + /** The dark theme. */ Dark, + + /** Follows the operating system theme setting. */ System; + /** Returns `true` if this theme resolves to the dark variant (including when [System] maps to dark). */ public fun isDark(): Boolean = (if (this == System) fromSystemTheme(currentSystemTheme) else this) == Dark + /** Returns `true` if this theme uses the light-header title bar variant. */ public fun isLightHeader(): Boolean = this == LightWithLightHeader + /** Provides [fromSystemTheme] for mapping the OS theme to a concrete [IntUiThemes] value. */ public companion object { + /** Returns [Light] or [Dark] based on the current [systemTheme] reported by Skiko. */ public fun fromSystemTheme(systemTheme: SystemTheme): IntUiThemes = if (systemTheme == SystemTheme.LIGHT) Light else Dark } diff --git a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt index 0317ff16abca..a365c9297a52 100644 --- a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt +++ b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/Main.kt @@ -32,6 +32,7 @@ import org.jetbrains.jewel.ui.ComponentStyling import org.jetbrains.jewel.window.DecoratedWindow import org.jetbrains.jewel.window.styling.TitleBarStyle +/** Entry point for the Jewel standalone sample application. */ @ExperimentalLayoutApi public fun main() { JewelLogger.getInstance("StandaloneSample").info("Starting Jewel Standalone sample") diff --git a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt index 7e88d60bb8e8..40943a22c47a 100644 --- a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt +++ b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt @@ -26,7 +26,9 @@ import org.jetbrains.jewel.samples.standalone.viewmodel.MainViewModel.components import org.jetbrains.jewel.ui.component.styling.IconButtonMetrics import org.jetbrains.jewel.ui.component.styling.ScrollbarVisibility +/** Singleton view model holding navigation state, theme, and component view models for the standalone sample. */ public object MainViewModel { + /** The view model managing the state of the Components showcase view. */ public val componentsViewModel: ComponentsViewModel init { @@ -39,16 +41,21 @@ public object MainViewModel { ) } + /** Navigates to the view whose title matches [destination]. */ public fun onNavigateTo(destination: String) { currentView = views.first { viewInfo: ViewInfo -> viewInfo.title == destination } } + /** The currently active UI theme. */ public var theme: IntUiThemes by mutableStateOf(IntUiThemes.Light) + /** Whether Swing compatibility mode is enabled. */ public var swingCompat: Boolean by mutableStateOf(false) + /** Whether the custom popup renderer is enabled. */ public var useCustomPopupRenderer: Boolean by mutableStateOf(JewelFlags.useCustomPopupRenderer) + /** The project stripe color derived from the current theme. */ public val projectColor: Color get() = if (theme.isLightHeader()) { @@ -57,8 +64,10 @@ public object MainViewModel { Color(0xFF654B40) } + /** The list of top-level navigation views available in the sample. */ public val views: SnapshotStateList = mainMenuItems + /** The currently selected navigation view. */ public var currentView: ViewInfo by mutableStateOf(views.first()) } diff --git a/platform/jewel/scripts/annotate-detekt.main.kts b/platform/jewel/scripts/annotate-detekt.main.kts new file mode 100644 index 000000000000..f3c9bcbd79de --- /dev/null +++ b/platform/jewel/scripts/annotate-detekt.main.kts @@ -0,0 +1,94 @@ +#!/usr/bin/env kotlin +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +import java.io.File +import javax.xml.parsers.DocumentBuilderFactory +import org.w3c.dom.Element + +// Emits GitHub Actions annotations for detekt findings by reading the checkstyle reports produced by +// detektMain (main.xml) and detektTest (test.xml) under the current directory (the Jewel root). This is +// independent of GitHub code scanning and mirrors annotate-api-dump-changes.main.kts: it prints +// ::error / ::warning / ::notice workflow commands and writes a short GITHUB_STEP_SUMMARY. +// +// detekt writes checkstyle paths relative to the Gradle root (platform/jewel), while GitHub annotations +// need repo-root-relative paths, so we prefix them accordingly. The failing detekt task is the actual gate — these +// annotations are purely for visibility on the PR's "Files changed" tab. + +val scanRoot = File(".").canonicalFile +val workspace = + System.getenv("GITHUB_WORKSPACE")?.let { File(it).canonicalFile } ?: scanRoot.parentFile?.parentFile ?: scanRoot +val pathPrefix = scanRoot.relativeToOrNull(workspace)?.path?.takeIf { it.isNotBlank() } + +fun repoRelative(rawPath: String): String { + val file = File(rawPath) + return when { + file.isAbsolute -> file.canonicalFile.relativeToOrNull(workspace)?.path ?: rawPath + pathPrefix != null -> "$pathPrefix/$rawPath" + else -> rawPath + } +} + +fun ghLevel(severity: String) = + when (severity.lowercase()) { + "error" -> "error" + "warning" -> "warning" + else -> "notice" + } + +fun escapeData(text: String) = text.replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A") + +fun escapeProperty(text: String) = escapeData(text).replace(":", "%3A").replace(",", "%2C") + +val reports = + scanRoot + .walkTopDown() + .filter { it.isFile && (it.name == "main.xml" || it.name == "test.xml") } + .filter { it.parentFile?.name == "detekt" && it.parentFile?.parentFile?.name == "reports" } + .toList() + +val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder() + +var errors = 0 +var warnings = 0 +var notices = 0 + +for (report in reports) { + val document = builder.parse(report) + val fileNodes = document.getElementsByTagName("file") + for (i in 0 until fileNodes.length) { + val fileElement = fileNodes.item(i) as Element + val path = repoRelative(fileElement.getAttribute("name")) + val errorNodes = fileElement.getElementsByTagName("error") + for (j in 0 until errorNodes.length) { + val error = errorNodes.item(j) as Element + val level = ghLevel(error.getAttribute("severity")) + when (level) { + "error" -> errors++ + "warning" -> warnings++ + else -> notices++ + } + val line = error.getAttribute("line").toIntOrNull() ?: 1 + val column = error.getAttribute("column").toIntOrNull() + val rule = error.getAttribute("source").removePrefix("detekt.") + val message = error.getAttribute("message") + val columnPart = column?.let { ",col=$it" } ?: "" + println( + "::$level file=${escapeProperty(path)},line=$line$columnPart," + + "title=${escapeProperty("detekt: $rule")}::${escapeData(message)}" + ) + } + } +} + +val total = errors + warnings + notices +val summary = buildString { + appendLine("## Detekt results") + appendLine() + if (total == 0) { + appendLine("✅ No Detekt findings.") + } else { + appendLine("❌ $total Detekt finding(s): $errors error, $warnings warning, $notices notice.") + } +} +System.getenv("GITHUB_STEP_SUMMARY")?.takeIf { it.isNotBlank() }?.let { File(it).appendText(summary) } +println("Emitted annotations for $total Detekt finding(s)") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/ComponentStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/ComponentStyling.kt index bb484ad8033f..d4fabc992f3d 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/ComponentStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/ComponentStyling.kt @@ -3,25 +3,38 @@ package org.jetbrains.jewel.ui import androidx.compose.runtime.Composable import androidx.compose.runtime.ProvidedValue +/** + * Defines a composable styling contract that provides [ProvidedValue] entries for Jewel components, and can be combined + * or layered with other instances. + */ public interface ComponentStyling { + /** Returns a new [ComponentStyling] that appends the given static [values] to this styling's provided values. */ public fun provide(vararg values: ProvidedValue<*>): ComponentStyling { if (values.isEmpty()) return this return with(StaticComponentStyling(values = values)) } + /** Returns a new [ComponentStyling] that appends values produced lazily by [provider] at composition time. */ public fun provide(provider: @Composable () -> Array>): ComponentStyling = with(LazyComponentStyling(provider)) + /** Returns a new [ComponentStyling] that combines this styling with [styling], applying [styling] last. */ public fun with(styling: ComponentStyling): ComponentStyling { if (styling is Companion) return this return CombinedComponentStyling(this, styling) } + /** + * Returns a new [ComponentStyling] that combines this styling with the [ComponentStyling] produced lazily by + * [styling] at composition time. + */ public fun with(styling: @Composable () -> ComponentStyling): ComponentStyling = with(LazyComponentStyling { styling().styles() }) + /** Returns the array of [ProvidedValue] entries that this styling contributes to the composition. */ @Composable public fun styles(): Array> + /** Companion object for [ComponentStyling]. */ public companion object : ComponentStyling { override fun with(styling: ComponentStyling): ComponentStyling = styling diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt index fec5a77834e4..e4f367c1f135 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt @@ -91,48 +91,88 @@ import org.jetbrains.jewel.ui.component.styling.fallbackPopupAdStyle import org.jetbrains.jewel.ui.component.styling.fallbackSearchMatchStyle import org.jetbrains.jewel.ui.component.styling.fallbackSpeedSearchStyle +/** Default implementation of [ComponentStyling] that aggregates style objects for all built-in Jewel components. */ @Stable @GenerateDataFunctions @Suppress("LargeClass") public class DefaultComponentStyling( + /** The style for checkboxes. */ public val checkboxStyle: CheckboxStyle, + /** The style for chips. */ public val chipStyle: ChipStyle, + /** The style for circular progress indicators. */ public val circularProgressStyle: CircularProgressStyle, + /** The styles for default (block-level) banners. */ public val defaultBannerStyle: DefaultBannerStyles, + /** The style for combo boxes. */ public val comboBoxStyle: ComboBoxStyle, + /** The style for default (filled) buttons. */ public val defaultButtonStyle: ButtonStyle, + /** The style for default dropdowns. */ public val defaultDropdownStyle: DropdownStyle, + /** The style for default split buttons. */ public val defaultSplitButtonStyle: SplitButtonStyle, + /** The style for default tabs. */ public val defaultTabStyle: TabStyle, + /** The style for dividers. */ public val dividerStyle: DividerStyle, + /** The style for editor tabs. */ public val editorTabStyle: TabStyle, + /** The style for group headers. */ public val groupHeaderStyle: GroupHeaderStyle, + /** The style for horizontal progress bars. */ public val horizontalProgressBarStyle: HorizontalProgressBarStyle, + /** The style for icon buttons. */ public val iconButtonStyle: IconButtonStyle, + /** The style for transparent icon buttons. */ public val transparentIconButtonStyle: IconButtonStyle, + /** The styles for inline banners. */ public val inlineBannerStyle: InlineBannerStyles, + /** The style for lazy tree components. */ public val lazyTreeStyle: LazyTreeStyle, + /** The style for links. */ public val linkStyle: LinkStyle, + /** The style for menus. */ public val menuStyle: MenuStyle, + /** The style for outlined buttons. */ public val outlinedButtonStyle: ButtonStyle, + /** The style for popup containers. */ public val popupContainerStyle: PopupContainerStyle, + /** The style for outlined split buttons. */ public val outlinedSplitButtonStyle: SplitButtonStyle, + /** The style for radio buttons. */ public val radioButtonStyle: RadioButtonStyle, + /** The style for scrollbars. */ public val scrollbarStyle: ScrollbarStyle, + /** The style for segmented control buttons. */ public val segmentedControlButtonStyle: SegmentedControlButtonStyle, + /** The style for segmented controls. */ public val segmentedControlStyle: SegmentedControlStyle, + /** The style for selectable lazy columns. */ public val selectableLazyColumnStyle: SelectableLazyColumnStyle, + /** The style for simple list items. */ public val simpleListItemStyle: SimpleListItemStyle, + /** The style for sliders. */ public val sliderStyle: SliderStyle, + /** The style for text areas. */ public val textAreaStyle: TextAreaStyle, + /** The style for text fields. */ public val textFieldStyle: TextFieldStyle, + /** The style for tooltips. */ public val tooltipStyle: TooltipStyle, + /** The style for undecorated dropdowns. */ public val undecoratedDropdownStyle: DropdownStyle, + /** The style for speed search overlays. */ public val speedSearchStyle: SpeedSearchStyle, + /** The style for search match highlights. */ public val searchMatchStyle: SearchMatchStyle, + /** The style for popup ads. */ public val popupAdStyle: PopupAdStyle, + /** The style for default slim buttons. */ public val defaultSlimButtonStyle: ButtonStyle, + /** The style for outlined slim buttons. */ public val outlinedSlimButtonStyle: ButtonStyle, + /** The styles for badges. */ public val badgeStyle: BadgeStyles, /** The style for Got It tooltips. */ public val gotItTooltipStyle: GotItTooltipStyle, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutHintProvider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutHintProvider.kt index 6d2735e3fa8d..eb4ee2494d07 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutHintProvider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutHintProvider.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf import org.jetbrains.jewel.ui.component.ContextMenuItemOptionAction +/** Provides formatted shortcut hint strings for [ContextMenuItemOptionAction] entries shown in menus. */ public interface MenuItemShortcutHintProvider { /** * Gets the formatted shortcut string for the given action identifier. @@ -16,6 +17,7 @@ public interface MenuItemShortcutHintProvider { public fun getShortcutHint(actionType: ContextMenuItemOptionAction): String } +/** Composition local providing the [MenuItemShortcutHintProvider] for the current theme. */ public val LocalMenuItemShortcutHintProvider: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalMenuItemShortcutHintProvider provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutProvider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutProvider.kt index 22baa2cd5e45..f08e55006ac0 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutProvider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/MenuItemShortcutProvider.kt @@ -18,6 +18,7 @@ public interface MenuItemShortcutProvider { public fun getShortcutKeyStroke(actionType: ContextMenuItemOptionAction): KeyStroke? } +/** Composition local that provides the [MenuItemShortcutProvider] for the current theme. */ public val LocalMenuItemShortcutProvider: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalMenuItemShortcutProvider provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Outline.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Outline.kt index 69a2fa54017a..7a006aebce02 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Outline.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Outline.kt @@ -25,6 +25,7 @@ public enum class Outline { /** An error outline will be drawn. */ Error; + /** Provides the [of] factory for constructing an [Outline] from boolean warning/error flags. */ public companion object { /** * Creates an [Outline] based on the provided boolean flags. @@ -91,10 +92,10 @@ public fun Modifier.focusOutline( * component is focused. * * @param outline The [Outline] state to use. + * @param focused Whether the component is focused. * @param outlineShape The [Shape] to use for the outline. * @param alignment The [Stroke.Alignment] to use for the outline. * @param outlineWidth The width of the outline [Dp]. - * @param focused Whether the component is focused. */ @Composable public fun Modifier.outline( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Typography.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Typography.kt index 3599977d30f1..9c34f44b0f0e 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Typography.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/Typography.kt @@ -149,9 +149,11 @@ private fun TextUnit.scaledFrom(baseFontSize: TextUnit, requestedFontSize: TextU else -> this } +/** CompositionLocal that provides the current [Typography] instance. */ public val LocalTypography: ProvidableCompositionLocal = staticCompositionLocalOf { error("No Typography provided. Have you forgotten the theme?") } +/** The current [Typography] provided by the active Jewel theme. */ public val JewelTheme.Companion.typography: Typography @Composable get() = LocalTypography.current diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ActionButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ActionButton.kt index 1c22571ec00b..e647604f3417 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ActionButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ActionButton.kt @@ -31,6 +31,7 @@ import org.jetbrains.jewel.ui.component.styling.TooltipStyle import org.jetbrains.jewel.ui.theme.iconButtonStyle import org.jetbrains.jewel.ui.theme.tooltipStyle +/** Renders an action button that wraps [IconButton] and applies horizontal content padding around [content]. */ @Composable public fun ActionButton( onClick: () -> Unit, @@ -47,6 +48,10 @@ public fun ActionButton( } } +/** + * Renders an action button with an associated [tooltip] that wraps [IconButton] and applies horizontal content padding + * around [content]. + */ @Composable public fun ActionButton( onClick: () -> Unit, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Badge.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Badge.kt index 2156a5842a04..e87e0adeabab 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Badge.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Badge.kt @@ -180,6 +180,7 @@ public value class BadgeState(public val state: ULong) : FocusableComponentState override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [BadgeState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -192,7 +193,9 @@ public value class BadgeState(public val state: ULong) : FocusableComponentState "BadgeState(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [BadgeState]. */ public companion object { + /** Constructs a [BadgeState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt index a0d8f881f558..83d8011c618c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt @@ -458,6 +458,7 @@ public fun OutlinedSplitButton( * [`JBOptionButton`](https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/platform-api/src/com/intellij/ui/components/JBOptionButton.kt) * * @param onClick Will be called when the user clicks the main button area + * @param popupContainer A generic container for the popup content * @param modifier Modifier to be applied to the button * @param popupModifier Modifier to be applied to the dropdown menu container * @param maxPopupHeight The maximum height of the popup @@ -468,9 +469,8 @@ public fun OutlinedSplitButton( * @param style The visual styling configuration for the split button including colors, metrics and layout parameters * @param textStyle The typography style to be applied to the button's text content * @param menuStyle The visual styling configuration for the dropdown menu - * @param content The content to be displayed in the main button area * @param secondaryOnClick Will be called when the user clicks the dropdown/chevron section - * @param popupContainer A generic container for the popup content + * @param content The content to be displayed in the main button area * @see com.intellij.ui.components.JBOptionButton */ @Composable @@ -1139,9 +1139,13 @@ private fun ButtonImpl( } } +/** Encodes the enabled, focused, hovered, pressed, and active states of a button as a bit mask. */ @Immutable @JvmInline -public value class ButtonState(public val state: ULong) : FocusableComponentState { +public value class ButtonState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -1157,6 +1161,7 @@ public value class ButtonState(public val state: ULong) : FocusableComponentStat override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [ButtonState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -1169,7 +1174,9 @@ public value class ButtonState(public val state: ULong) : FocusableComponentStat "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [ButtonState]. */ public companion object { + /** Constructs a [ButtonState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt index d8d565113acd..acbf0527c7f1 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Checkbox.kt @@ -681,6 +681,10 @@ private fun CheckBoxImage(checkboxPainter: Painter, modifier: Modifier = Modifie Box(modifier.paint(checkboxPainter, alignment = Alignment.TopStart)) } +/** + * Encodes the toggleable (on/off/indeterminate), enabled, focused, hovered, pressed, and active states of a checkbox as + * a bit mask. + */ @Immutable @JvmInline public value class CheckboxState(private val state: ULong) : ToggleableComponentState, FocusableComponentState { @@ -702,6 +706,7 @@ public value class CheckboxState(private val state: ULong) : ToggleableComponent override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [CheckboxState] with the given fields replaced by their new values. */ public fun copy( toggleableState: ToggleableState = this.toggleableState, enabled: Boolean = isEnabled, @@ -723,7 +728,9 @@ public value class CheckboxState(private val state: ULong) : ToggleableComponent "${javaClass.simpleName}(toggleableState=$toggleableState, isEnabled=$isEnabled, isFocused=$isFocused, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [CheckboxState]. */ public companion object { + /** Constructs a [CheckboxState] from individual flags. */ public fun of( toggleableState: ToggleableState, enabled: Boolean = true, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Chip.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Chip.kt index 5c14b3c2551f..e922b98c633e 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Chip.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Chip.kt @@ -313,9 +313,13 @@ private fun ChipImpl( } } +/** Encodes the enabled, focused, selected, hovered, pressed, and active states of a chip as a bit mask. */ @Immutable @JvmInline -public value class ChipState(public val state: ULong) : FocusableComponentState, SelectableComponentState { +public value class ChipState( + /** The raw bit mask encoding all interaction states. */ + public val state: ULong +) : FocusableComponentState, SelectableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -334,6 +338,7 @@ public value class ChipState(public val state: ULong) : FocusableComponentState, override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [ChipState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -355,7 +360,9 @@ public value class ChipState(public val state: ULong) : FocusableComponentState, "ChipState(isEnabled=$isEnabled, isFocused=$isFocused, isSelected=$isSelected, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [ChipState]. */ public companion object { + /** Constructs a [ChipState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/CircularProgressIndicator.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/CircularProgressIndicator.kt index 0fd3b248f6be..e5f1aa601201 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/CircularProgressIndicator.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/CircularProgressIndicator.kt @@ -26,6 +26,10 @@ import org.jetbrains.jewel.foundation.util.JewelLogger import org.jetbrains.jewel.ui.component.styling.CircularProgressStyle import org.jetbrains.jewel.ui.theme.circularProgressStyle +/** + * Renders a small (16x16dp) animated circular progress indicator that spins indefinitely, indicating an ongoing + * operation with no known completion time. + */ @Composable public fun CircularProgressIndicator( modifier: Modifier = Modifier, @@ -40,6 +44,10 @@ public fun CircularProgressIndicator( ) } +/** + * Renders a large (32x32dp) animated circular progress indicator that spins indefinitely, indicating an ongoing + * operation with no known completion time. + */ @Composable public fun CircularProgressIndicatorBig( modifier: Modifier = Modifier, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ComboBox.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ComboBox.kt index 467effee2dcb..5fef8ca8e355 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ComboBox.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ComboBox.kt @@ -490,6 +490,7 @@ internal fun ComboBoxLabelText(text: String, style: TextStyle, comboBoxStyle: Co * * @param style The visual styling configuration for the combo box * @param enabled Whether the combo box is enabled, affects the icon color + * @param modifier The [Modifier] to apply to the chevron. */ @Composable private fun Chevron(style: ComboBoxStyle, enabled: Boolean, modifier: Modifier = Modifier) { diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Divider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Divider.kt index 42609dcb7451..f903af597540 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Divider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Divider.kt @@ -19,6 +19,10 @@ import org.jetbrains.jewel.ui.Orientation import org.jetbrains.jewel.ui.component.styling.DividerStyle import org.jetbrains.jewel.ui.theme.dividerStyle +/** + * Renders a thin decorative line that visually separates content, drawn either horizontally or vertically according to + * [orientation]. + */ @Composable public fun Divider( orientation: Orientation, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Dropdown.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Dropdown.kt index da0953c1cc48..e5bc4b6bde74 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Dropdown.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Dropdown.kt @@ -198,7 +198,10 @@ public fun Dropdown( @ApiStatus.Experimental @Immutable @JvmInline -public value class DropdownState(public val state: ULong) : FocusableComponentState { +public value class DropdownState( + /** The raw bit mask encoding all active state flags. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -214,6 +217,7 @@ public value class DropdownState(public val state: ULong) : FocusableComponentSt override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [DropdownState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -226,7 +230,9 @@ public value class DropdownState(public val state: ULong) : FocusableComponentSt "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [DropdownState]. */ public companion object { + /** Constructs a [DropdownState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/EditableComboBox.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/EditableComboBox.kt index 44c14153c4c9..d3ab5196b1dd 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/EditableComboBox.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/EditableComboBox.kt @@ -75,6 +75,10 @@ import org.jetbrains.jewel.ui.focusOutline import org.jetbrains.jewel.ui.outline import org.jetbrains.jewel.ui.theme.comboBoxStyle +/** + * Renders an editable combo box composed of a text field and a chevron button that toggles a popup containing + * [popupContent]. + */ @Suppress("UnavailableSymbol") // TODO(JEWEL-983) Address Metalava suppressions @Composable public fun EditableComboBox( @@ -209,6 +213,10 @@ public fun EditableComboBox( } } +/** + * Renders an editable combo box composed of a text field and a chevron button that toggles a popup containing + * [popupContent]. + */ @Suppress("UnavailableSymbol") // TODO(JEWEL-983) Address Metalava suppressions @Composable @Deprecated( @@ -366,24 +374,34 @@ private fun Chevron( } } +/** Represents the UI state of a [EditableComboBox], encoding enabled, focused, hovered, pressed, and active bits. */ @Immutable @JvmInline -public value class ComboBoxState(public val state: ULong) : FocusableComponentState { +public value class ComboBoxState( + /** The raw bit mask encoding all active state flags. */ + public val state: ULong +) : FocusableComponentState { + /** Whether the combo box is in the active (window-focused) state. */ override val isActive: Boolean get() = state and Active != 0UL + /** Whether the combo box is enabled. */ override val isEnabled: Boolean get() = state and Enabled != 0UL + /** Whether the combo box has keyboard focus. */ override val isFocused: Boolean get() = state and Focused != 0UL + /** Whether the combo box is hovered. */ override val isHovered: Boolean get() = state and Hovered != 0UL + /** Whether the combo box is pressed. */ override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [ComboBoxState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -396,7 +414,9 @@ public value class ComboBoxState(public val state: ULong) : FocusableComponentSt "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [ComboBoxState]. */ public companion object { + /** Constructs a [ComboBoxState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, @@ -414,6 +434,10 @@ public value class ComboBoxState(public val state: ULong) : FocusableComponentSt } } +/** + * Detects a press-and-cancel gesture within a [PointerInputScope], invoking [onPress] when a pointer is first pressed + * down and [onCancel] if the gesture is cancelled before the pointer is released. + */ @InternalJewelApi @ApiStatus.Internal public suspend fun PointerInputScope.detectPressAndCancel(onPress: () -> Unit, onCancel: () -> Unit) { diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/GroupHeader.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/GroupHeader.kt index 63b473da1e32..d8133e5a5aef 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/GroupHeader.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/GroupHeader.kt @@ -32,6 +32,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalGroupHeaderStyle * @param startComponent The component to display on the left side of the header. * @param endComponent The component to display on the right side of the header. * @param style The style to apply to the header. + * @param textStyle The text style to apply to the header text. Defaults to [JewelTheme.defaultTextStyle]. * @see com.intellij.ui.TitledSeparator */ @Composable diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Icon.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Icon.kt index e62b0b14d3c1..6b28dba7495f 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Icon.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Icon.kt @@ -83,8 +83,8 @@ public fun Icon( * @param contentDescription text used by accessibility services to describe what this icon represents. This should * always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action * that a user can take. - * @param scale Scale multiplier for the icon. * @param modifier optional [Modifier] for this Icon. + * @param scale Scale multiplier for the icon. * @param iconDesigner lambda that builds an [Icon] instance using [IconDesigner]. */ @Composable @@ -104,8 +104,8 @@ public fun Icon( * @param contentDescription text used by accessibility services to describe what this icon represents. This should * always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action * that a user can take. - * @param scale Scale multiplier for the icon. * @param modifier optional [Modifier] for this Icon. + * @param scale Scale multiplier for the icon. */ @Composable public fun Icon(icon: Icon, contentDescription: String?, modifier: Modifier = Modifier, scale: IconScale? = null) { @@ -142,6 +142,18 @@ public fun Icon(icon: Icon, contentDescription: String?, modifier: Modifier = Mo ) } +/** + * Icon component that draws an icon from an [IconKey] using a single [hint]. + * + * @param key The [IconKey] to resolve the icon from. + * @param contentDescription text used by accessibility services to describe what this icon represents. This should + * always be provided unless this icon is used for decorative purposes, and does not represent a meaningful action + * that a user can take. + * @param modifier optional [Modifier] for this Icon. + * @param iconClass The class to use for resolving the icon resource. Defaults to `key.iconClass`. + * @param tint tint to be applied to the icon. If [Color.Unspecified] is provided, then no tint is applied. + * @param hint [PainterHint] to be passed to the painter. + */ @Suppress("ComposableParamOrder") @Composable public fun Icon( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconActionButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconActionButton.kt index 09f0aad63e89..acac4ca0bf09 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconActionButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconActionButton.kt @@ -32,6 +32,11 @@ import org.jetbrains.jewel.ui.painter.PainterHint import org.jetbrains.jewel.ui.theme.iconButtonStyle import org.jetbrains.jewel.ui.theme.tooltipStyle +/** + * An icon-only action button that renders the icon identified by [key]. + * + * This overload accepts an optional single [PainterHint] to influence how the icon is painted. + */ @Composable public fun IconActionButton( key: IconKey, @@ -63,6 +68,12 @@ public fun IconActionButton( ) } +/** + * An icon-only action button that renders the icon identified by [key] with a tooltip. + * + * This overload accepts an optional single [PainterHint] to influence how the icon is painted, and wraps the button in + * a [Tooltip] composable using the provided [tooltip] content. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-924 @Composable public fun IconActionButton( @@ -102,6 +113,11 @@ public fun IconActionButton( } } +/** + * An icon-only action button that renders the icon identified by [key]. + * + * This overload accepts an array of [PainterHint]s to influence how the icon is painted. + */ @Composable public fun IconActionButton( key: IconKey, @@ -133,6 +149,12 @@ public fun IconActionButton( ) } +/** + * An icon-only action button that renders the icon identified by [key] with a tooltip. + * + * This overload accepts an array of [PainterHint]s to influence how the icon is painted, and wraps the button in a + * [Tooltip] composable using the provided [tooltip] content. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-924 @Composable public fun IconActionButton( @@ -274,6 +296,7 @@ private fun CoreIconActionButton( } } +/** An icon-only action button that renders the icon from the given [painter]. */ @Composable public fun IconActionButton( painter: Painter, @@ -299,6 +322,11 @@ public fun IconActionButton( ) } +/** + * An icon-only action button that renders the icon from the given [painter] with a tooltip. + * + * Wraps the button in a [Tooltip] composable using the provided [tooltip] content. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-924 @Composable public fun IconActionButton( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconButton.kt index 3f74b52edf37..6712367ad547 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/IconButton.kt @@ -44,6 +44,10 @@ import org.jetbrains.jewel.ui.component.styling.IconButtonStyle import org.jetbrains.jewel.ui.disabledAppearance import org.jetbrains.jewel.ui.theme.iconButtonStyle +/** + * Renders a clickable icon button that applies the given [style] and exposes its current [IconButtonState] to + * [content]. + */ @Composable public fun IconButton( onClick: () -> Unit, @@ -98,6 +102,10 @@ public fun IconButton( ) } +/** + * Renders a selectable icon button that applies the given [style] and exposes its current [SelectableIconButtonState] + * to [content]. + */ @Composable public fun SelectableIconButton( selected: Boolean, @@ -155,6 +163,10 @@ public fun SelectableIconButton( ) } +/** + * Renders a toggleable icon button that applies the given [style] and exposes its current [ToggleableIconButtonState] + * to [content]. + */ @Composable public fun ToggleableIconButton( value: Boolean, @@ -214,9 +226,13 @@ public fun ToggleableIconButton( ) } +/** Encodes the enabled, focused, hovered, pressed, and active states of an [IconButton] as a bit mask. */ @Immutable @JvmInline -public value class IconButtonState(public val state: ULong) : FocusableComponentState { +public value class IconButtonState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -232,6 +248,7 @@ public value class IconButtonState(public val state: ULong) : FocusableComponent override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [IconButtonState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -244,7 +261,9 @@ public value class IconButtonState(public val state: ULong) : FocusableComponent "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [IconButtonState]. */ public companion object { + /** Constructs an [IconButtonState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, @@ -262,10 +281,16 @@ public value class IconButtonState(public val state: ULong) : FocusableComponent } } +/** + * Encodes the enabled, focused, hovered, pressed, active, and toggleable states of a [ToggleableIconButton] as a bit + * mask. + */ @Immutable @JvmInline -public value class ToggleableIconButtonState(public val state: ULong) : - FocusableComponentState, ToggleableComponentState { +public value class ToggleableIconButtonState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState, ToggleableComponentState { override val toggleableState: ToggleableState get() = state.readToggleableState() @@ -284,6 +309,7 @@ public value class ToggleableIconButtonState(public val state: ULong) : override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [ToggleableIconButtonState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, toggleableState: ToggleableState = this.toggleableState, @@ -305,7 +331,9 @@ public value class ToggleableIconButtonState(public val state: ULong) : "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive, toggleableState=$toggleableState)" + /** Companion object for [ToggleableIconButtonState]. */ public companion object { + /** Constructs a [ToggleableIconButtonState] from individual flags. */ public fun of( enabled: Boolean = true, toggleableState: ToggleableState = ToggleableState.Off, @@ -326,10 +354,16 @@ public value class ToggleableIconButtonState(public val state: ULong) : } } +/** + * Encodes the enabled, focused, hovered, pressed, active, and selected states of a [SelectableIconButton] as a bit + * mask. + */ @Immutable @JvmInline -public value class SelectableIconButtonState(public val state: ULong) : - FocusableComponentState, SelectableComponentState { +public value class SelectableIconButtonState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState, SelectableComponentState { override val isSelected: Boolean get() = state and Selected != 0UL @@ -348,6 +382,7 @@ public value class SelectableIconButtonState(public val state: ULong) : override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [SelectableIconButtonState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, selected: Boolean = isSelected, @@ -370,7 +405,9 @@ public value class SelectableIconButtonState(public val state: ULong) : "isFocused=$isFocused, isHovered=$isHovered, isPressed=$isPressed, " + "isActive=$isActive)" + /** Companion object for [SelectableIconButtonState]. */ public companion object { + /** Constructs a [SelectableIconButtonState] from individual flags. */ public fun of( enabled: Boolean = true, selected: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InlineBanner.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InlineBanner.kt index ecaf58cdd35b..740f887d4b9e 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InlineBanner.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InlineBanner.kt @@ -577,8 +577,6 @@ public fun SuccessInlineBanner( * @param title An optional title, rendered in bold, that appears above the [content]. * @param icon Slot for an optional icon displayed on the left of the [content] or [title]. If null, there is no icon. * By default, it is the [AllIconsKeys.Status.Success] icon. - * @param actions Slot for optional primary actions (usually links) to show at the bottom of the banner, below the - * [content]. * @param linkActions A block within the [BannerLinkActionScope] to define optional action items for the banner. If not * provided, no actions will be rendered. Please note that this block will automatically fold the actions into a * "More" dropdown menu if there are more than 3 actions or there is not enough space to fit the actions. diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt index 6364f42ab6a8..db717ba345f7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt @@ -259,9 +259,15 @@ private fun Modifier.hideCursor( false // returning false so the text field can handle the key event properly } +/** + * Represents the state of an input field, encoding enabled, focused, hovered, pressed, and active flags in a bit mask. + */ @Immutable @JvmInline -public value class InputFieldState(public val state: ULong) : FocusableComponentState { +public value class InputFieldState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -277,6 +283,7 @@ public value class InputFieldState(public val state: ULong) : FocusableComponent override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [InputFieldState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -289,7 +296,9 @@ public value class InputFieldState(public val state: ULong) : FocusableComponent "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [InputFieldState]. */ public companion object { + /** Constructs an [InputFieldState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/LazyTree.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/LazyTree.kt index 47b6fb550406..650ab6711565 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/LazyTree.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/LazyTree.kt @@ -22,6 +22,20 @@ import org.jetbrains.jewel.ui.component.styling.LazyTreeStyle import org.jetbrains.jewel.ui.component.styling.contentFor import org.jetbrains.jewel.ui.theme.treeStyle +/** + * Renders a lazily-loaded, selectable tree of [Tree.Element] nodes. + * + * @param T The type of data held by each tree element. + * @param tree The [Tree] data structure to display. + * @param modifier Modifier to apply to the tree layout. + * @param onElementClick Called when a tree element is clicked. + * @param treeState The [TreeState] controlling expansion and selection. + * @param onElementDoubleClick Called when a tree element is double-clicked. + * @param onSelectionChange Called when the set of selected elements changes. + * @param keyActions The [KeyActions] handling keyboard navigation. + * @param style The [LazyTreeStyle] controlling the visual appearance. + * @param nodeContent The composable content rendered for each tree element. + */ @ApiStatus.Experimental @ExperimentalJewelApi @Composable @@ -51,6 +65,21 @@ public fun LazyTree( ) } +/** + * Renders a lazily-loaded, selectable tree of [Tree.Element] nodes. + * + * @param T The type of data held by each tree element. + * @param tree The [Tree] data structure to display. + * @param modifier Modifier to apply to the tree layout. + * @param onElementClick Called when a tree element is clicked. + * @param treeState The [TreeState] controlling expansion and selection. + * @param onElementDoubleClick Called when a tree element is double-clicked. + * @param onSelectionChange Called when the set of selected elements changes. + * @param keyActions The [KeyActions] handling keyboard navigation. + * @param style The [LazyTreeStyle] controlling the visual appearance. + * @param interactionSource The [MutableInteractionSource] tracking user interactions with the tree. + * @param nodeContent The composable content rendered for each tree element. + */ @ApiStatus.Experimental @ExperimentalJewelApi @Composable diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Link.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Link.kt index 058c5ccfacc2..710e051ed07c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Link.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Link.kt @@ -439,9 +439,13 @@ private fun LinkImpl( } } +/** Encodes the enabled, focused, hovered, pressed, active, and visited interaction states of a link as a bit mask. */ @Immutable @JvmInline -public value class LinkState(public val state: ULong) : FocusableComponentState { +public value class LinkState( + /** The raw bit mask encoding all interaction states. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -451,6 +455,7 @@ public value class LinkState(public val state: ULong) : FocusableComponentState override val isFocused: Boolean get() = state and Focused != 0UL + /** Whether the link has been visited. */ public val isVisited: Boolean get() = state and Visited != 0UL @@ -464,6 +469,7 @@ public value class LinkState(public val state: ULong) : FocusableComponentState "${javaClass.simpleName}(enabled=$isEnabled, focused=$isFocused, visited=$isVisited, " + "pressed=$isPressed, hovered=$isHovered, isActive=$isActive)" + /** Returns a copy of this [LinkState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -481,6 +487,12 @@ public value class LinkState(public val state: ULong) : FocusableComponentState active = active, ) + /** + * Selects and returns a value based on the current interaction state, including the visited state. + * + * Evaluates the current state in priority order — disabled, pressed, hovered, focused, visited, active — and + * returns the corresponding value, falling back to [normal] when none of the special states apply. + */ @Composable public fun chooseValueWithVisited( normal: T, @@ -501,11 +513,13 @@ public value class LinkState(public val state: ULong) : FocusableComponentState else -> normal } + /** Companion object for [LinkState]. */ public companion object { private const val VISITED_BIT_OFFSET = CommonStateBitMask.FIRST_AVAILABLE_OFFSET private val Visited = 1UL shl VISITED_BIT_OFFSET + /** Constructs a [LinkState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ListComboBox.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ListComboBox.kt index a16be8235336..b9b34e177b0c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ListComboBox.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ListComboBox.kt @@ -76,6 +76,7 @@ import org.jetbrains.jewel.ui.theme.popupContainerStyle * **Swing equivalent:** * [`ComboBox`](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java) * + * @param T the type of items in the list. * @param items The list of items to display in the dropdown * @param selectedIndex The index of the currently selected item * @param onSelectedItemChange Called when an item is selected, with the new index @@ -168,6 +169,7 @@ public fun ListComboBox( * **Swing equivalent:** * [`ComboBox`](https://github.com/JetBrains/intellij-community/blob/master/platform/platform-api/src/com/intellij/openapi/ui/ComboBox.java) * + * @param T the type of items in the list. * @param items The list of items to display in the dropdown * @param selectedIndex The index of the currently selected item * @param onSelectedItemChange Called when an item is selected, with the new index @@ -418,6 +420,7 @@ public fun ListComboBox( * @param selectedIndex The index of the currently selected item * @param onSelectedItemChange Called when the selected item changes, with the new index and item * @param modifier Modifier to be applied to the combo box + * @param popupModifier Modifier to be applied to the popup of the combo box * @param enabled Controls whether the combo box can be interacted with * @param outline The outline style to be applied to the combo box * @param maxPopupHeight The maximum height of the popup list. If unspecified, the height is automatically calculated diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt index 550d8d20d6c3..a3467060bdbe 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt @@ -579,6 +579,14 @@ public fun MenuScope.separator() { passiveItem { MenuSeparator(JewelTheme.menuStyle.colors.itemColors, JewelTheme.menuStyle.metrics.itemMetrics) } } +/** + * Adds [count] selectable items to the menu, using index-based selection and click callbacks. + * + * @param count The number of items to add + * @param isSelected Returns whether the item at the given index is currently selected + * @param onItemClick Called with the index of the item when it is clicked + * @param content The composable content for the item at the given index + */ public fun MenuScope.items( count: Int, isSelected: (Int) -> Boolean, @@ -588,6 +596,15 @@ public fun MenuScope.items( repeat(count) { selectableItem(isSelected(it), onClick = { onItemClick(it) }) { content(it) } } } +/** + * Adds a selectable item for each element in [items], using element-based selection and click callbacks. + * + * @param T The type of items in the list. + * @param items The list of items to render. + * @param isSelected Returns whether the given item is currently selected. + * @param onItemClick Called with the item when it is clicked. + * @param content The composable content for the given item. + */ public fun MenuScope.items( items: List, isSelected: (T) -> Boolean, @@ -667,12 +684,19 @@ private interface MenuItem { @VisibleForTesting @GenerateDataFunctions public class MenuSelectableItem( + /** Whether this item is currently selected. */ public val isSelected: Boolean, + /** Whether this item is enabled and can be interacted with. */ public val isEnabled: Boolean, + /** Optional icon key for displaying an icon before the item content. */ public val iconKey: IconKey?, + /** Optional action type used to resolve and handle the shortcut hint. */ public val itemOptionAction: ContextMenuItemOptionAction? = null, + /** Optional set of keybinding strings to display alongside the item. */ public val keybinding: Set? = emptySet(), + /** Called when the item is clicked. */ public val onClick: () -> Unit = {}, + /** The composable content displayed inside this menu item. */ override val content: @Composable () -> Unit, ) : MenuItem { override fun equals(other: Any?): Boolean { @@ -906,6 +930,13 @@ public fun MenuSubmenuItem( } } +/** + * Low-level submenu menu item implementation, exposed for testing. + * + * Renders a menu item that opens a nested [submenu] popup when selected. Unlike the public overload, this function + * accepts explicit [showIcon] and [selected] arguments and provides the [MenuItemState] to [content], allowing tests to + * drive the item's state directly. + */ @VisibleForTesting @ApiStatus.Internal @InternalJewelApi @@ -1127,7 +1158,10 @@ internal fun Submenu( @Deprecated("This is being made private") @Immutable @JvmInline -public value class MenuItemState(public val state: ULong) : SelectableComponentState, FocusableComponentState { +public value class MenuItemState( + /** The raw bit-masked state value encoding all interaction flags. */ + public val state: ULong +) : SelectableComponentState, FocusableComponentState { override val isActive: Boolean get() = state and Selected != 0UL @@ -1146,6 +1180,7 @@ public value class MenuItemState(public val state: ULong) : SelectableComponentS override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [MenuItemState] with the given fields replaced by their new values. */ @Suppress("DEPRECATION") public fun copy( selected: Boolean = isSelected, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/MenuController.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/MenuController.kt index a451d1254876..8a88c09e32d6 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/MenuController.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/MenuController.kt @@ -8,28 +8,56 @@ import javax.swing.KeyStroke import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.InternalJewelApi +/** + * Controls the lifecycle and hierarchy of a menu, including open/close behaviour, hover state, and keyboard shortcut + * dispatch. + */ public interface MenuController { + /** Callback invoked when the menu is requested to be dismissed for a given [InputMode]. */ public val onDismissRequest: (InputMode) -> Boolean + /** Called when the hovered state of the menu changes. */ public fun onHoveredChange(hovered: Boolean) + /** Closes this menu and all ancestor menus in the hierarchy. */ public fun closeAll(mode: InputMode, force: Boolean) + /** Closes this menu and returns whether the dismissal was accepted. */ public fun close(mode: InputMode): Boolean + /** Returns `true` if this menu has no parent, i.e. it is the root of the menu hierarchy. */ public fun isRootMenu(): Boolean + /** Returns `true` if this menu is nested inside another menu. */ public fun isSubmenu(): Boolean + /** + * Creates a child [MenuController] for a submenu, linking it to this controller as its parent. + * + * @param onDismissRequest callback invoked when the submenu is requested to be dismissed. + */ public fun submenuController(onDismissRequest: (InputMode) -> Boolean): MenuController + /** + * Registers a keyboard shortcut action for this menu level. + * + * @param keyStroke the key stroke that triggers the action. + * @param action the action to invoke when the key stroke is detected. + */ public fun registerShortcutAction(keyStroke: KeyStroke, action: () -> Unit) + /** Removes all registered shortcut actions from this menu level. */ public fun clearShortcutActions() + /** + * Searches for a registered shortcut matching [keyStroke] and executes it if found. + * + * @return `true` if a matching shortcut was found and executed, or `null` if no match was found. + */ public fun findAndExecuteShortcut(keyStroke: KeyStroke?): Boolean? } +/** Default [MenuController] implementation that supports nested submenus via an optional [parentMenuController]. */ @ApiStatus.Internal @InternalJewelApi public class DefaultMenuController( @@ -64,23 +92,43 @@ public class DefaultMenuController( } } + /** Closes this menu by invoking [onDismissRequest] and returns whether the dismissal was accepted. */ override fun close(mode: InputMode): Boolean = onDismissRequest(mode) + /** Returns `true` if this menu has no parent, i.e. it is the root of the menu hierarchy. */ override fun isRootMenu(): Boolean = parentMenuController == null + /** Returns `true` if this menu is nested inside another menu. */ override fun isSubmenu(): Boolean = parentMenuController != null + /** + * Creates a child [DefaultMenuController] for a submenu, linking it to this controller as its parent. + * + * @param onDismissRequest callback invoked when the submenu is requested to be dismissed. + */ override fun submenuController(onDismissRequest: (InputMode) -> Boolean): DefaultMenuController = DefaultMenuController(onDismissRequest = onDismissRequest, parentMenuController = this) + /** + * Registers a keyboard shortcut action for this menu level. + * + * @param keyStroke the key stroke that triggers the action. + * @param action the action to invoke when the key stroke is detected. + */ override fun registerShortcutAction(keyStroke: KeyStroke, action: () -> Unit) { currentMenuShortcutActions.add(MenuShortcutAction(keyStroke, action)) } + /** Removes all registered shortcut actions from this menu level. */ override fun clearShortcutActions() { currentMenuShortcutActions.clear() } + /** + * Searches for a registered shortcut matching [keyStroke] and executes it if found. + * + * @return `true` if a matching shortcut was found and executed, or `null` if no match was found. + */ override fun findAndExecuteShortcut(keyStroke: KeyStroke?): Boolean? { val actionToExecute = currentMenuShortcutActions.firstOrNull { it.keyStroke == keyStroke } if (actionToExecute != null) { @@ -91,6 +139,7 @@ public class DefaultMenuController( } } +/** CompositionLocal that provides the nearest [MenuController] in the composition. */ public val LocalMenuController: ProvidableCompositionLocal = staticCompositionLocalOf { error("No MenuController provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupContainer.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupContainer.kt index bfdd4c624b1c..0a85c82669d2 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupContainer.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupContainer.kt @@ -95,6 +95,17 @@ public fun PopupContainer( } } +/** + * A reusable popup container that provides standard visual styling for floating content. + * + * @param onDismissRequest Called when the popup should be dismissed (e.g., clicking outside or pressing Esc) + * @param horizontalAlignment The horizontal alignment of the popup relative to its anchor point + * @param modifier Modifier to be applied to the container + * @param style The visual styling configuration for the popup container + * @param popupProperties Properties controlling the popup window behavior + * @param popupPositionProvider Determines the position of the popup on the screen + * @param content The main content to display inside the popup container + */ @Composable @Deprecated(message = "Deprecated in favor of the method with 'adContent' parameter", level = DeprecationLevel.HIDDEN) public fun PopupContainer( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupManager.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupManager.kt index 4cf31105389b..239e238b57b9 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupManager.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/PopupManager.kt @@ -11,8 +11,8 @@ import androidx.compose.runtime.mutableStateOf * * They have the same [name] * * The [isPopupVisible] value is the same * - * @param name An optional name given to the instance. * @param onPopupVisibleChange A lambda to call when the popup visibility changes. + * @param name An optional name given to the instance. */ public class PopupManager(public val onPopupVisibleChange: (Boolean) -> Unit = {}, public val name: String? = null) { private val _isPopupVisible: MutableState = mutableStateOf(false) diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/RadioButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/RadioButton.kt index 963269cf84b9..d555b18df0f8 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/RadioButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/RadioButton.kt @@ -384,9 +384,13 @@ private fun RadioButtonImage(radioButtonPainter: Painter, modifier: Modifier = M Box(modifier.paint(radioButtonPainter, alignment = Alignment.TopStart)) } +/** Encodes the selected, enabled, focused, hovered, pressed, and active states of a radio button as a bit mask. */ @Immutable @JvmInline -public value class RadioButtonState(public val state: ULong) : SelectableComponentState, FocusableComponentState { +public value class RadioButtonState( + /** The raw bit mask encoding all state flags for this radio button. */ + public val state: ULong +) : SelectableComponentState, FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -405,6 +409,7 @@ public value class RadioButtonState(public val state: ULong) : SelectableCompone override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [RadioButtonState] with the given fields replaced by their new values. */ public fun copy( selected: Boolean = isSelected, enabled: Boolean = isEnabled, @@ -426,7 +431,9 @@ public value class RadioButtonState(public val state: ULong) : SelectableCompone "${javaClass.simpleName}(isSelected=$isSelected, isEnabled=$isEnabled, isFocused=$isFocused, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [RadioButtonState]. */ public companion object { + /** Constructs a [RadioButtonState] from individual flags. */ public fun of( selected: Boolean, enabled: Boolean = true, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ScrollableContainer.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ScrollableContainer.kt index 2a75dcebf9df..55061328d637 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ScrollableContainer.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ScrollableContainer.kt @@ -233,6 +233,9 @@ public fun VerticallyScrollableContainer( * @param userScrollEnabled Whether scrolling is enabled or not * @param scrollbarEnabled Whether the scrollbar is enabled or not; usually matches [userScrollEnabled] * @param scrollbarInteractionSource The interaction source used for the scrollbar + * @param adapter The [ScrollbarAdapter] used by the scrollbar to compute the thumb position and size. When null, a + * default adapter is derived from [scrollState]. See [VerticalScrollbar] for the full contract, including the + * supported [scrollState] types and remembering requirements. * @param content The main content of the scrollable container * @see com.intellij.ui.components.JBScrollBar */ diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControl.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControl.kt index 094c722c18f6..522c45d9ccb7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControl.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControl.kt @@ -138,13 +138,20 @@ public fun SegmentedControl( } } +/** + * Holds the data for a single segment in a [SegmentedControl], including its selection state, content composable, and + * selection callback. + */ @Immutable @GenerateDataFunctions public class SegmentedControlButtonData( + /** Whether this segment is currently selected. */ public val selected: Boolean, + /** The composable content rendered inside this segment button. */ public val content: @Composable SegmentedControlButtonScope.(segmentedControlButtonState: SegmentedControlButtonState) -> Unit, + /** Callback invoked when this segment is selected by the user. */ public val onSelect: () -> Unit, ) { override fun equals(other: Any?): Boolean { @@ -176,24 +183,34 @@ public class SegmentedControlButtonData( } } +/** Encodes the enabled, focused, hovered, pressed, and active states of a [SegmentedControl] as a bit mask. */ @Immutable @JvmInline -public value class SegmentedControlState(public val state: ULong) : FocusableComponentState { +public value class SegmentedControlState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : FocusableComponentState { + /** Whether the control's host window is currently active. */ override val isActive: Boolean get() = state and CommonStateBitMask.Active != 0UL + /** Whether the control is enabled and can receive input. */ override val isEnabled: Boolean get() = state and CommonStateBitMask.Enabled != 0UL + /** Whether the control is currently focused. */ override val isFocused: Boolean get() = state and CommonStateBitMask.Focused != 0UL + /** Whether the pointer is currently hovering over the control. */ override val isHovered: Boolean get() = state and CommonStateBitMask.Hovered != 0UL + /** Whether the control is currently being pressed. */ override val isPressed: Boolean get() = state and CommonStateBitMask.Pressed != 0UL + /** Returns a copy of this [SegmentedControlState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -207,7 +224,9 @@ public value class SegmentedControlState(public val state: ULong) : FocusableCom "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [SegmentedControlState]. */ public companion object { + /** Constructs a [SegmentedControlState] from individual flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControlButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControlButton.kt index e5d10bef18a6..011aede5223e 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControlButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SegmentedControlButton.kt @@ -37,6 +37,7 @@ import org.jetbrains.jewel.foundation.theme.LocalContentColor import org.jetbrains.jewel.foundation.theme.LocalTextStyle import org.jetbrains.jewel.ui.component.styling.SegmentedControlButtonStyle +/** Scope for content composables placed inside a segmented control button. */ public interface SegmentedControlButtonScope internal class SegmentedControlButtonScopeContainer : SegmentedControlButtonScope @@ -118,9 +119,13 @@ internal fun SegmentedControlButton( } } +/** Encodes the selected, enabled, pressed, hovered, and active states of a segmented control button as a bit mask. */ @Immutable @JvmInline -public value class SegmentedControlButtonState(public val state: ULong) : SelectableComponentState { +public value class SegmentedControlButtonState( + /** The raw bit mask encoding all state flags. */ + public val state: ULong +) : SelectableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -137,6 +142,7 @@ public value class SegmentedControlButtonState(public val state: ULong) : Select override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [SegmentedControlButtonState] with the given fields replaced by their new values. */ public fun copy( selected: Boolean = isSelected, enabled: Boolean = isEnabled, @@ -150,8 +156,10 @@ public value class SegmentedControlButtonState(public val state: ULong) : Select "${javaClass.simpleName}(isSelected=$isSelected, isEnabled=$isEnabled, " + "isHovered=$isHovered, isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [SegmentedControlButtonState]. */ public companion object { + /** Constructs a [SegmentedControlButtonState] from individual flags. */ public fun of( selected: Boolean, enabled: Boolean = true, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SelectableIconActionButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SelectableIconActionButton.kt index 33a869ee72d1..aa1cd910a2c6 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SelectableIconActionButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SelectableIconActionButton.kt @@ -18,6 +18,10 @@ import org.jetbrains.jewel.ui.painter.hints.Stroke import org.jetbrains.jewel.ui.theme.iconButtonStyle import org.jetbrains.jewel.ui.theme.tooltipStyle +/** + * Renders a selectable icon action button that displays an icon resolved from [key], with an optional [extraHint] + * applied to the painter. + */ @Composable public fun SelectableIconActionButton( key: IconKey, @@ -51,6 +55,10 @@ public fun SelectableIconActionButton( ) } +/** + * Renders a selectable icon action button that displays an icon resolved from [key], with an optional [extraHint] + * applied to the painter. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-930 @Composable public fun SelectableIconActionButton( @@ -92,6 +100,10 @@ public fun SelectableIconActionButton( } } +/** + * Renders a selectable icon action button that displays an icon resolved from [key], with an optional [extraHint] + * applied to the painter. + */ @Composable public fun SelectableIconActionButton( key: IconKey, @@ -125,6 +137,10 @@ public fun SelectableIconActionButton( ) } +/** + * Renders a selectable icon action button that displays an icon resolved from [key], with [extraHints] applied to the + * painter, and shows a [tooltip] on hover. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-930 @Composable public fun SelectableIconActionButton( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt index d41c0c1d1af3..1863bc21f6e5 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt @@ -100,6 +100,7 @@ public fun SimpleListItem( * Jewel theme. * @param height The height of the list item; default is based on the Jewel theme's global metrics. * @param colorFilter Optional [ColorFilter] to apply to the icon, if any. + * @param onTextLayout Callback for when text layout is computed. * @param painterHints Optional [PainterHint]s to apply to the icon, if any. */ @Composable @@ -199,15 +200,16 @@ public fun SimpleListItem( * * @param text The text displayed in the list item. * @param selected Indicates whether the list item is selected. - * @param active Indicates whether the list item is active or disabled; default is active. * @param modifier Optional [Modifier] to apply to the entire list item. * @param textModifier Optional [Modifier] to apply to specifically to the text. * @param iconModifier Optional [Modifier] to apply to specifically to the icon. + * @param active Indicates whether the list item is active or disabled; default is active. * @param icon Optional [IconKey] representing the icon displayed on the start side of the list item. * @param iconContentDescription Optional content description [String] for the icon for accessibility purposes. * @param style The [SimpleListItemStyle] defining the appearance of the list item; default is based on the Jewel theme. * @param height The height of the list item; default is based on the Jewel theme's global metrics. * @param colorFilter Optional [ColorFilter] to apply to the icon, if any. + * @param onTextLayout Callback for when text layout is computed. * @param painterHints Optional [PainterHint]s to apply to the icon, if any. */ @Composable @@ -474,8 +476,14 @@ public fun SimpleListItem( } } +/** Holds the selection and activity state for a simple list item. */ @GenerateDataFunctions -public class ListItemState(public val isSelected: Boolean, public val isActive: Boolean = true) { +public class ListItemState( + /** Whether the list item is currently selected. */ + public val isSelected: Boolean, + /** Whether the list item is active (enabled and interactive). */ + public val isActive: Boolean = true, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Slider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Slider.kt index b74faa8b99b2..31f75158e6b2 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Slider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Slider.kt @@ -701,9 +701,15 @@ internal val KeyEvent.isPgDn: Boolean internal fun lerp(start: Float, stop: Float, fraction: Float): Float = (1 - fraction) * start + fraction * stop +/** + * Represents the UI state of a [Slider], encoding enabled, focused, hovered, pressed, and active states as a bit mask. + */ @Immutable @JvmInline -public value class SliderState(public val state: ULong) : FocusableComponentState { +public value class SliderState( + /** The raw bit mask encoding all active state flags. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -719,6 +725,7 @@ public value class SliderState(public val state: ULong) : FocusableComponentStat override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [SliderState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -731,7 +738,9 @@ public value class SliderState(public val state: ULong) : FocusableComponentStat "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [SliderState]. */ public companion object { + /** Constructs a [SliderState] from individual state flags. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SpeedSearchArea.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SpeedSearchArea.kt index 36d9744f91f3..c374f1354b41 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SpeedSearchArea.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SpeedSearchArea.kt @@ -73,6 +73,20 @@ import org.jetbrains.jewel.ui.theme.speedSearchStyle import org.jetbrains.jewel.ui.theme.textFieldStyle import org.jetbrains.skiko.hostOs +/** + * Creates a speed search area that provides keyboard-driven search functionality for its content. + * + * @param modifier The modifier to be applied to the container. + * @param matcherBuilder A function that creates a [SpeedSearchMatcher] from the search text. Defaults to + * [SpeedSearchMatcher.patternMatcher]. + * @param styling The visual styling for the speed search input overlay. + * @param textFieldStyle The styling for the text field within the search overlay. + * @param textStyle The text style for the search input text. + * @param searchMatchStyle The styling for highlighting matched text in search results. + * @param interactionSource The interaction source for tracking focus state. If null, a new one will be created. + * @param content The content to be displayed within the speed search area. Use [SpeedSearchScope] to access search + * state and process key events. + */ @Composable @ExperimentalJewelApi @ApiStatus.Experimental diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SplitLayout.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SplitLayout.kt index 47cc17726a5c..f734a74f75c6 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SplitLayout.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SplitLayout.kt @@ -52,11 +52,11 @@ import org.jetbrains.jewel.ui.theme.dividerStyle * @param second The Composable function representing the second component, that will be placed on the other side of the * divider, typically on the right or below. * @param modifier The modifier to be applied to the layout. + * @param dividerStyle The divider style to be applied to the layout. * @param draggableWidth The width of the draggable area around the divider. This is a invisible, wider area around the * divider that can be dragged by the user to resize the panes. * @param firstPaneMinWidth The minimum size of the first component. * @param secondPaneMinWidth The minimum size of the second component. - * @param dividerStyle The divider style to be applied to the layout. * @param state The [SplitLayoutState] object that will be used to store the split state. */ @Composable @@ -92,11 +92,11 @@ public fun HorizontalSplitLayout( * @param second The Composable function representing the second component, that will be placed on the other side of the * divider, typically on the right or below. * @param modifier The modifier to be applied to the layout. + * @param dividerStyle The divider style to be applied to the layout. * @param draggableWidth The width of the draggable area around the divider. This is a invisible, wider area around the * divider that can be dragged by the user to resize the panes. * @param firstPaneMinWidth The minimum size of the first component. * @param secondPaneMinWidth The minimum size of the second component. - * @param dividerStyle The divider style to be applied to the layout. * @param state The [SplitLayoutState] object that will be used to store the split state. */ @Composable diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt index b026bac2277a..d0974c213135 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt @@ -205,13 +205,23 @@ public fun TabStrip(tabs: List, style: TabStyle, modifier: Modifier = M TabStrip(tabs, style, modifier, enabled, remember { MutableInteractionSource() }) } +/** Sealed base class representing the data and callbacks for a single tab in a [TabStrip]. */ @Suppress("AbstractClassCanBeInterface") // Binary compatibility: sealed class cannot be changed to interface @Immutable public sealed class TabData { + /** Whether this tab is currently selected. */ public abstract val selected: Boolean + + /** The composable content to be displayed within the tab. */ public abstract val content: @Composable TabContentScope.(tabState: TabState) -> Unit + + /** Whether this tab can be closed by the user. */ public abstract val closable: Boolean + + /** Called when the user attempts to close the tab. */ public abstract val onClose: () -> Unit + + /** Called when the user clicks the tab. */ public abstract val onClick: () -> Unit /** @@ -339,7 +349,10 @@ public sealed class TabData { */ @Immutable @JvmInline -public value class TabStripState(public val state: ULong) : FocusableComponentState { +public value class TabStripState( + /** The raw bit-masked state value. */ + public val state: ULong +) : FocusableComponentState { override val isActive: Boolean get() = state and CommonStateBitMask.Active != 0UL @@ -355,6 +368,7 @@ public value class TabStripState(public val state: ULong) : FocusableComponentSt override val isPressed: Boolean get() = state and CommonStateBitMask.Pressed != 0UL + /** Returns a copy of this [TabStripState] with the given fields replaced by their new values. */ public fun copy( enabled: Boolean = isEnabled, focused: Boolean = isFocused, @@ -367,7 +381,9 @@ public value class TabStripState(public val state: ULong) : FocusableComponentSt "${javaClass.simpleName}(isEnabled=$isEnabled, isFocused=$isFocused, isHovered=$isHovered, " + "isPressed=$isPressed, isActive=$isActive)" + /** Companion object for [TabStripState]. */ public companion object { + /** Constructs a [TabStripState] from individual flags/parameters. */ public fun of( enabled: Boolean = true, focused: Boolean = false, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Tabs.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Tabs.kt index 82ce3a2039a2..fb0bcefb0a8c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Tabs.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Tabs.kt @@ -56,7 +56,13 @@ import org.jetbrains.jewel.ui.painter.hints.Stateful import org.jetbrains.jewel.ui.theme.defaultTabStyle import org.jetbrains.jewel.ui.theme.editorTabStyle +/** Scope provided to tab content composables, offering modifier extensions such as [tabContentAlpha]. */ public interface TabContentScope { + /** + * Applies the tab content alpha from the current editor tab style to this [Modifier], based on [state]. + * + * @param state The current [TabState] of the tab. + */ @Composable public fun Modifier.tabContentAlpha(state: TabState): Modifier = alpha(JewelTheme.editorTabStyle.contentAlpha.contentFor(state).value) @@ -64,6 +70,7 @@ public interface TabContentScope { internal class TabContentScopeContainer : TabContentScope +/** Renders a simple tab content row with an optional [icon] painter and a text [label]. */ @Composable public fun TabContentScope.SimpleTabContent( @Nls label: String, @@ -79,6 +86,7 @@ public fun TabContentScope.SimpleTabContent( ) } +/** Renders a simple tab content row with an optional icon loaded from [iconKey] and a text [label]. */ @Suppress("ComposableParamOrder") // It dislikes the vararg @Composable public fun TabContentScope.SimpleTabContent( @@ -96,6 +104,7 @@ public fun TabContentScope.SimpleTabContent( ) } +/** Renders a simple tab content row with an optional composable [icon] slot and a composable [label] slot. */ @Composable public fun TabContentScope.SimpleTabContent( state: TabState, @@ -230,9 +239,13 @@ internal fun TabImpl( } } +/** Encodes the visual state of a tab as a bit mask, including selected, enabled, hovered, pressed, and active flags. */ @Immutable @JvmInline -public value class TabState(public val state: ULong) : SelectableComponentState { +public value class TabState( + /** The raw bit mask encoding all state flags for this tab. */ + public val state: ULong +) : SelectableComponentState { override val isActive: Boolean get() = state and Active != 0UL @@ -248,6 +261,7 @@ public value class TabState(public val state: ULong) : SelectableComponentState override val isPressed: Boolean get() = state and Pressed != 0UL + /** Returns a copy of this [TabState] with the given fields replaced by their new values. */ public fun copy( selected: Boolean = isSelected, enabled: Boolean = isEnabled, @@ -260,7 +274,9 @@ public value class TabState(public val state: ULong) : SelectableComponentState "${javaClass.simpleName}(isSelected=$isSelected, isEnabled=$isEnabled, " + "isHovered=$isHovered, isPressed=$isPressed isActive=$isActive)" + /** Companion object for [TabState]. */ public companion object { + /** Constructs a [TabState] from individual flags. */ public fun of( selected: Boolean, enabled: Boolean = true, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ToggleableIconActionButton.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ToggleableIconActionButton.kt index 1c47845380a4..8c5cd3db389a 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ToggleableIconActionButton.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/ToggleableIconActionButton.kt @@ -18,6 +18,12 @@ import org.jetbrains.jewel.ui.painter.hints.Stroke import org.jetbrains.jewel.ui.theme.iconButtonStyle import org.jetbrains.jewel.ui.theme.tooltipStyle +/** + * Renders a toggleable icon action button using the given [key] to resolve the icon. + * + * The button visually reflects its toggled [value] and notifies [onValueChange] when the user clicks it. An optional + * [extraHint] may be supplied to further customise how the icon is painted. + */ @Composable public fun ToggleableIconActionButton( key: IconKey, @@ -51,6 +57,13 @@ public fun ToggleableIconActionButton( ) } +/** + * Renders a toggleable icon action button using the given [key] to resolve the icon, with a tooltip shown on hover. + * + * The button visually reflects its toggled [value] and notifies [onValueChange] when the user clicks it. The [tooltip] + * composable is displayed according to [tooltipPlacement]. An optional [extraHint] may be supplied to further customise + * how the icon is painted. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-932 @Composable public fun ToggleableIconActionButton( @@ -92,6 +105,12 @@ public fun ToggleableIconActionButton( } } +/** + * Renders a toggleable icon action button using the given [key] to resolve the icon. + * + * The button visually reflects its toggled [value] and notifies [onValueChange] when the user clicks it. The + * [extraHints] array is forwarded to the icon painter to further customise rendering. + */ @Composable public fun ToggleableIconActionButton( key: IconKey, @@ -125,6 +144,13 @@ public fun ToggleableIconActionButton( ) } +/** + * Renders a toggleable icon action button using the given [key] to resolve the icon, with a tooltip shown on hover. + * + * The button visually reflects its toggled [value] and notifies [onValueChange] when the user clicks it. The + * [extraHints] array is forwarded to the icon painter to further customise rendering. The [tooltip] composable is + * displayed according to [tooltipPlacement]. + */ @Suppress("ComposableParamOrder") // To fix in JEWEL-932 @Composable public fun ToggleableIconActionButton( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Typography.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Typography.kt index 4d76f65a475a..49712c8b8a9f 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Typography.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Typography.kt @@ -243,6 +243,7 @@ public fun TextStyle.copyWithSize( textMotion, ) +/** Returns the sum of this [TextUnit] and [other], provided they share the same unit type. */ public operator fun TextUnit.plus(other: TextUnit): TextUnit = when { isSp && other.isSp -> TextUnit(value + other.value, TextUnitType.Sp) @@ -251,6 +252,7 @@ public operator fun TextUnit.plus(other: TextUnit): TextUnit = else -> error("Can't add together different TextUnits. Got $type and ${other.type}") } +/** Returns the difference between this [TextUnit] and [other], provided they share the same unit type. */ public operator fun TextUnit.minus(other: TextUnit): TextUnit = when { isSp && other.isSp -> TextUnit(value - other.value, TextUnitType.Sp) diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/Highlight.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/Highlight.kt index 5ecfdf4d9714..715ce385b96c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/Highlight.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/Highlight.kt @@ -16,6 +16,12 @@ import org.jetbrains.jewel.foundation.search.SpeedSearchMatcher import org.jetbrains.jewel.ui.component.LocalNodeSearchMatchState import org.jetbrains.jewel.ui.component.NodeSearchMatchState +/** + * Returns an [AnnotatedString] built from this [CharSequence] with the matched character ranges styled according to the + * current search highlight style. + * + * If [matchState] contains no active match, the text is returned unstyled. + */ @Composable @ExperimentalJewelApi @ApiStatus.Experimental @@ -33,6 +39,14 @@ public fun CharSequence.highlightTextSearch( } } +/** + * Draws rounded-rectangle highlight backgrounds behind each matched character range reported by [matchState], using the + * bounding boxes from [textLayoutResult]. + * + * Ranges that span multiple lines are split per line, and adjacent bounding boxes on the same line are merged into a + * single rectangle before drawing. If [matchState] contains no active match or [textLayoutResult] is `null`, the + * modifier is a no-op. + */ @Composable @ExperimentalJewelApi @ApiStatus.Experimental diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableComboBox.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableComboBox.kt index a3234d62eb70..f08e44193342 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableComboBox.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableComboBox.kt @@ -176,6 +176,7 @@ public fun SpeedSearchScope.SpeedSearchableComboBox( * } * ``` * + * @param T the type of items in the list. * @param items The list of items to display in the combo box popup. * @param selectedIndex The index of the currently selected item. * @param onSelectedItemChange Called with the new index when the user selects a different item. diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableLazyColumn.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableLazyColumn.kt index 4ff2d25f0cb2..730b62731b3f 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableLazyColumn.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableLazyColumn.kt @@ -211,9 +211,25 @@ internal class SpeedSearchableLazyColumnKeyActions( } } +/** + * Defines the DSL scope for adding items to a [SpeedSearchableLazyColumn], associating each entry with its searchable + * text content. + */ @ExperimentalJewelApi @ApiStatus.Experimental public interface SpeedSearchableLazyColumnScope { + /** + * Adds a list of items to the column, associating each item with its searchable text content. + * + * @param T The type of items in the list. + * @param items The list of items to display. + * @param textContent A function that returns the searchable text for a given item, or `null` if the item should not + * be matched. + * @param key A function that returns a stable, unique key for a given item. + * @param contentType A function that returns the content type for a given item, used for composition reuse. + * @param selectable A function that returns whether a given item is selectable. + * @param itemContent The composable content for each item. + */ public fun items( items: List, textContent: (item: T) -> String?, @@ -223,6 +239,16 @@ public interface SpeedSearchableLazyColumnScope { itemContent: @Composable SelectableLazyItemScope.(item: T) -> Unit, ) + /** + * Adds a single item to the column, associating it with its searchable text content. + * + * @param key A stable, unique key for this item. + * @param textContent A function that returns the searchable text for this item, or `null` if the item should not be + * matched. + * @param contentType The content type for this item, used for composition reuse. + * @param selectable Whether this item is selectable. + * @param content The composable content for this item. + */ public fun item( key: Any, textContent: () -> String?, @@ -231,6 +257,16 @@ public interface SpeedSearchableLazyColumnScope { content: @Composable (SelectableLazyItemScope.() -> Unit), ) + /** + * Adds a sticky header item to the column, associating it with its searchable text content. + * + * @param key A stable, unique key for this header. + * @param textContent A function that returns the searchable text for this header, or `null` if the header should + * not be matched. + * @param contentType The content type for this header, used for composition reuse. + * @param selectable Whether this header is selectable. + * @param content The composable content for this header. + */ public fun stickyHeader( key: Any, textContent: () -> String?, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableTree.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableTree.kt index 97f1e1574e47..948418f63805 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableTree.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/search/SpeedSearchableTree.kt @@ -62,6 +62,7 @@ import org.jetbrains.jewel.ui.theme.treeStyle * } * ``` * + * @param T the type of data held by each tree element. * @param tree The tree structure to be rendered. * @param nodeText A function that extracts searchable text from a tree element, or `null` if the node should not be * matched. diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BadgeStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BadgeStyling.kt index b024326cf57a..506c2715eebe 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BadgeStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BadgeStyling.kt @@ -74,6 +74,7 @@ public class BadgeStyles( "graySecondary=$graySecondary" + ")" + /** Companion object for [BadgeStyles]. */ public companion object } @@ -106,6 +107,7 @@ public class BadgeStyle(public val colors: BadgeColors, public val metrics: Badg override fun toString(): String = "BadgeStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [BadgeStyle]. */ public companion object } @@ -236,6 +238,7 @@ public class BadgeColors( "contentHovered=$contentHovered" + ")" + /** Companion object for [BadgeColors]. */ public companion object } @@ -275,9 +278,11 @@ public class BadgeMetrics( override fun toString(): String = "BadgeMetrics(cornerSize=$cornerSize, padding=$padding, minHeight=$minHeight)" + /** Companion object for [BadgeMetrics]. */ public companion object } +/** CompositionLocal providing the current [BadgeStyles] for badge components. */ public val LocalBadgeStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No BadgeStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BannerStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BannerStyling.kt index 73bbb76ae7b3..52a5cce3d543 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BannerStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/BannerStyling.kt @@ -11,12 +11,19 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** + * Combines styling for all severity variants (information, success, warning, error) of the default banner component. + */ @Stable @GenerateDataFunctions public class DefaultBannerStyles( + /** The style for the information severity variant. */ public val information: DefaultBannerStyle, + /** The style for the success severity variant. */ public val success: DefaultBannerStyle, + /** The style for the warning severity variant. */ public val warning: DefaultBannerStyle, + /** The style for the error severity variant. */ public val error: DefaultBannerStyle, ) { override fun equals(other: Any?): Boolean { @@ -50,12 +57,19 @@ public class DefaultBannerStyles( ")" } + /** Companion object for [DefaultBannerStyles]. */ public companion object } +/** Combines the colors and metrics that style a single-severity default banner component. */ @Stable @GenerateDataFunctions -public class DefaultBannerStyle(public val colors: BannerColors, public val metrics: BannerMetrics) { +public class DefaultBannerStyle( + /** The color tokens for the banner. */ + public val colors: BannerColors, + /** The geometric and spacing properties for the banner. */ + public val metrics: BannerMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -76,15 +90,21 @@ public class DefaultBannerStyle(public val colors: BannerColors, public val metr override fun toString(): String = "DefaultBannerStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [DefaultBannerStyle]. */ public companion object } +/** Combines styling for all severity variants (information, success, warning, error) of the inline banner component. */ @Stable @GenerateDataFunctions public class InlineBannerStyles( + /** The style for the information severity variant. */ public val information: InlineBannerStyle, + /** The style for the success severity variant. */ public val success: InlineBannerStyle, + /** The style for the warning severity variant. */ public val warning: InlineBannerStyle, + /** The style for the error severity variant. */ public val error: InlineBannerStyle, ) { override fun equals(other: Any?): Boolean { @@ -118,12 +138,19 @@ public class InlineBannerStyles( ")" } + /** Companion object for [InlineBannerStyles]. */ public companion object } +/** Combines the colors and metrics that style a single-severity inline banner component. */ @Stable @GenerateDataFunctions -public class InlineBannerStyle(public val colors: BannerColors, public val metrics: BannerMetrics) { +public class InlineBannerStyle( + /** The color tokens for the banner. */ + public val colors: BannerColors, + /** The geometric and spacing properties for the banner. */ + public val metrics: BannerMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -144,12 +171,19 @@ public class InlineBannerStyle(public val colors: BannerColors, public val metri override fun toString(): String = "InlineBannerStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [InlineBannerStyle]. */ public companion object } +/** Holds color tokens for the banner component, covering background and border colors. */ @Immutable @GenerateDataFunctions -public class BannerColors(public val background: Color, public val border: Color) { +public class BannerColors( + /** The background color. */ + public val background: Color, + /** The border color. */ + public val border: Color, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -170,6 +204,7 @@ public class BannerColors(public val background: Color, public val border: Color override fun toString(): String = "BannerColors(background=$background, border=$border)" + /** Companion object for [BannerColors]. */ public companion object } @@ -183,8 +218,11 @@ public class BannerColors(public val background: Color, public val border: Color @Stable @GenerateDataFunctions public class BannerMetrics( + /** The width of the banner's border stroke. */ public val borderWidth: Dp, + /** The corner radius applied to the banner's shape. */ public val cornerSize: CornerSize, + /** The internal padding applied to the banner's content area. */ public val padding: PaddingValues, ) { @Deprecated( @@ -216,13 +254,16 @@ public class BannerMetrics( override fun toString(): String = "BannerMetrics(" + "borderWidth=$borderWidth, " + "cornerSize=$cornerSize, " + "padding=$padding" + ")" + /** Companion object for [BannerMetrics]. */ public companion object } +/** CompositionLocal providing the [DefaultBannerStyles] for the current theme. */ public val LocalDefaultBannerStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DefaultBannerStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the [InlineBannerStyles] for the current theme. */ public val LocalInlineBannerStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No InlineBannerStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt index 2bffc9b92fd4..190cf2f63e12 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt @@ -19,13 +19,18 @@ import org.jetbrains.jewel.foundation.Stroke import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.component.ButtonState +/** Combines [ButtonColors] and [ButtonMetrics] styling sub-objects for a button component. */ @Stable @GenerateDataFunctions public class ButtonStyle( + /** The color tokens for the button in its various interaction states. */ public val colors: ButtonColors, + /** The size and spacing metrics for the button. */ public val metrics: ButtonMetrics, + /** The alignment of the focus outline stroke relative to the button border. */ public val focusOutlineAlignment: Stroke.Alignment, ) { + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -54,28 +59,46 @@ public class ButtonStyle( ")" } + /** Companion object for [ButtonStyle]. */ public companion object } +/** Holds color tokens for the button component in its various interaction states. */ @Immutable @GenerateDataFunctions public class ButtonColors( + /** The background brush in the normal state. */ public val background: Brush, + /** The background brush when the button is disabled. */ public val backgroundDisabled: Brush, + /** The background brush when the button is focused. */ public val backgroundFocused: Brush, + /** The background brush when the button is pressed. */ public val backgroundPressed: Brush, + /** The background brush when the button is hovered. */ public val backgroundHovered: Brush, + /** The content (foreground) color in the normal state. */ public val content: Color, + /** The content color when the button is disabled. */ public val contentDisabled: Color, + /** The content color when the button is focused. */ public val contentFocused: Color, + /** The content color when the button is pressed. */ public val contentPressed: Color, + /** The content color when the button is hovered. */ public val contentHovered: Color, + /** The border brush in the normal state. */ public val border: Brush, + /** The border brush when the button is disabled. */ public val borderDisabled: Brush, + /** The border brush when the button is focused. */ public val borderFocused: Brush, + /** The border brush when the button is pressed. */ public val borderPressed: Brush, + /** The border brush when the button is hovered. */ public val borderHovered: Brush, ) { + /** Returns a [State] holding the background brush appropriate for the given [state]. */ @Composable public fun backgroundFor(state: ButtonState): State = rememberUpdatedState( @@ -89,6 +112,7 @@ public class ButtonColors( ) ) + /** Returns a [State] holding the content color appropriate for the given [state]. */ @Composable public fun contentFor(state: ButtonState): State = rememberUpdatedState( @@ -102,6 +126,10 @@ public class ButtonColors( ) ) + /** + * Returns a [State] holding the border brush appropriate for the given [state], taking Swing compatibility mode + * into account. + */ @Composable public fun borderFor(state: ButtonState): State = rememberUpdatedState( @@ -189,16 +217,23 @@ public class ButtonColors( ")" } + /** Companion object for [ButtonColors]. */ public companion object } +/** Holds size and spacing metrics for the button component. */ @Stable @GenerateDataFunctions public class ButtonMetrics( + /** The corner radius of the button. */ public val cornerSize: CornerSize, + /** The inner padding of the button content. */ public val padding: PaddingValues, + /** The minimum width and height of the button. */ public val minSize: DpSize, + /** The width of the button border stroke. */ public val borderWidth: Dp, + /** The amount by which the focus outline expands beyond the button border. */ public val focusOutlineExpand: Dp, ) { override fun equals(other: Any?): Boolean { @@ -235,21 +270,26 @@ public class ButtonMetrics( ")" } + /** Companion object for [ButtonMetrics]. */ public companion object } +/** CompositionLocal providing the [ButtonStyle] for default (filled) buttons. */ public val LocalDefaultButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No default ButtonStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the [ButtonStyle] for outlined buttons. */ public val LocalOutlinedButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No outlined ButtonStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the [ButtonStyle] for default (filled) slim buttons. */ public val LocalDefaultSlimButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No default slim ButtonStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the [ButtonStyle] for outlined slim buttons. */ public val LocalOutlinedSlimButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No outlined slim ButtonStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt index 678f7a6bfd70..6136a0ce4e12 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CheckboxStyling.kt @@ -15,11 +15,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.CheckboxState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines the colors, metrics, and icons that define the visual style of a checkbox component. */ @Immutable @GenerateDataFunctions public class CheckboxStyle( + /** The color tokens for the checkbox. */ public val colors: CheckboxColors, + /** The size and spacing metrics for the checkbox. */ public val metrics: CheckboxMetrics, + /** The icon keys for the checkbox. */ public val icons: CheckboxIcons, ) { override fun equals(other: Any?): Boolean { @@ -44,16 +48,25 @@ public class CheckboxStyle( override fun toString(): String = "CheckboxStyle(colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [CheckboxStyle]. */ public companion object } +/** Holds color tokens for the checkbox component in its various states (default, disabled, selected). */ @Immutable @GenerateDataFunctions public class CheckboxColors( + /** The content (label) color. */ public val content: Color, + /** The content color when the checkbox is disabled. */ public val contentDisabled: Color, + /** The content color when the checkbox is selected. */ public val contentSelected: Color, ) { + /** + * Returns a [State] holding the content color appropriate for the given [state], reflecting disabled and selected + * variants. + */ @Composable public fun contentFor(state: CheckboxState): State = rememberUpdatedState( @@ -92,23 +105,45 @@ public class CheckboxColors( ")" } + /** Companion object for [CheckboxColors]. */ public companion object } +/** + * Holds size and spacing metrics for the checkbox component, including checkbox size, outline sizes, corner sizes, and + * content gap. + */ @Immutable @GenerateDataFunctions public class CheckboxMetrics( + /** The size of the checkbox indicator box. */ public val checkboxSize: DpSize, + /** The corner size of the error/warning outline in the default (unfocused, unselected) state. */ public val outlineCornerSize: CornerSize, + /** The corner size of the outline when the checkbox is focused (and not selected). */ public val outlineFocusedCornerSize: CornerSize, + /** The corner size of the outline when the checkbox is selected or indeterminate (and not focused). */ public val outlineSelectedCornerSize: CornerSize, + /** The corner size of the outline when the checkbox is focused and either selected or indeterminate. */ public val outlineSelectedFocusedCornerSize: CornerSize, + /** The size of the outline box in the default state, when the checkbox is neither focused nor selected. */ public val outlineSize: DpSize, + /** The size of the focus outline when the checkbox is focused. */ public val outlineFocusedSize: DpSize, + /** + * The size of the outline box when the checkbox is selected or indeterminate and not focused. This box carries the + * validation (Error/Warning) outline. + */ public val outlineSelectedSize: DpSize, + /** The size of the outline box when the checkbox is both selected (or indeterminate) and focused. */ public val outlineSelectedFocusedSize: DpSize, + /** The gap between the checkbox icon and its label. */ public val iconContentGap: Dp, ) { + /** + * Returns a [State] holding the outline corner size appropriate for the given [state], varying by focus and + * selection. + */ @Composable public fun outlineCornerSizeFor(state: CheckboxState): State = rememberUpdatedState( @@ -120,6 +155,7 @@ public class CheckboxMetrics( } ) + /** Returns a [State] holding the outline size appropriate for the given [state], varying by focus and selection. */ @Composable public fun outlineSizeFor(state: CheckboxState): State = rememberUpdatedState( @@ -180,12 +216,17 @@ public class CheckboxMetrics( ")" } + /** Companion object for [CheckboxMetrics]. */ public companion object } +/** Holds the icon key for the checkbox component. */ @Immutable @GenerateDataFunctions -public class CheckboxIcons(public val checkbox: IconKey) { +public class CheckboxIcons( + /** The icon key for the checkbox indicator. */ + public val checkbox: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -199,9 +240,11 @@ public class CheckboxIcons(public val checkbox: IconKey) { override fun toString(): String = "CheckboxIcons(checkbox=$checkbox)" + /** Companion object for [CheckboxIcons]. */ public companion object } +/** CompositionLocal used to provide the [CheckboxStyle] to checkbox components. */ public val LocalCheckboxStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No CheckboxStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ChipStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ChipStyling.kt index 357fcaa1f229..913dc3eee87d 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ChipStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ChipStyling.kt @@ -17,9 +17,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.component.ChipState +/** Defines the styling for a Chip component, combining [ChipColors] and [ChipMetrics]. */ @Stable @GenerateDataFunctions -public class ChipStyle(public val colors: ChipColors, public val metrics: ChipMetrics) { +public class ChipStyle( + /** The color tokens used to paint the chip in its various states. */ + public val colors: ChipColors, + /** The size and spacing metrics used to lay out the chip. */ + public val metrics: ChipMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -40,43 +46,82 @@ public class ChipStyle(public val colors: ChipColors, public val metrics: ChipMe override fun toString(): String = "ChipStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [ChipStyle]. */ public companion object } +/** + * Holds color tokens for the Chip component in its various states, including selected, focused, pressed, hovered, and + * disabled. + */ @Immutable @GenerateDataFunctions public class ChipColors( + /** The background brush in the default state. */ public val background: Brush, + /** The background brush when the chip is disabled. */ public val backgroundDisabled: Brush, + /** The background brush when the chip is focused. */ public val backgroundFocused: Brush, + /** The background brush when the chip is pressed. */ public val backgroundPressed: Brush, + /** The background brush when the chip is hovered. */ public val backgroundHovered: Brush, + /** The background brush when the chip is selected. */ public val backgroundSelected: Brush, + /** The background brush when the chip is selected and disabled. */ public val backgroundSelectedDisabled: Brush, + /** The background brush when the chip is selected and pressed. */ public val backgroundSelectedPressed: Brush, + /** The background brush when the chip is selected and focused. */ public val backgroundSelectedFocused: Brush, + /** The background brush when the chip is selected and hovered. */ public val backgroundSelectedHovered: Brush, + /** The content color in the default state. */ public val content: Color, + /** The content color when the chip is disabled. */ public val contentDisabled: Color, + /** The content color when the chip is focused. */ public val contentFocused: Color, + /** The content color when the chip is pressed. */ public val contentPressed: Color, + /** The content color when the chip is hovered. */ public val contentHovered: Color, + /** The content color when the chip is selected. */ public val contentSelected: Color, + /** The content color when the chip is selected and disabled. */ public val contentSelectedDisabled: Color, + /** The content color when the chip is selected and pressed. */ public val contentSelectedPressed: Color, + /** The content color when the chip is selected and focused. */ public val contentSelectedFocused: Color, + /** The content color when the chip is selected and hovered. */ public val contentSelectedHovered: Color, + /** The border color in the default state. */ public val border: Color, + /** The border color when the chip is disabled. */ public val borderDisabled: Color, + /** The border color when the chip is focused. */ public val borderFocused: Color, + /** The border color when the chip is pressed. */ public val borderPressed: Color, + /** The border color when the chip is hovered. */ public val borderHovered: Color, + /** The border color when the chip is selected. */ public val borderSelected: Color, + /** The border color when the chip is selected and disabled. */ public val borderSelectedDisabled: Color, + /** The border color when the chip is selected and pressed. */ public val borderSelectedPressed: Color, + /** The border color when the chip is selected and focused. */ public val borderSelectedFocused: Color, + /** The border color when the chip is selected and hovered. */ public val borderSelectedHovered: Color, ) { + /** + * Returns a [State] holding the background [Brush] appropriate for the given [state], accounting for selection, + * enabled, pressed, focused, and hovered conditions. + */ @Composable public fun backgroundFor(state: ChipState): State = rememberUpdatedState( @@ -99,6 +144,10 @@ public class ChipColors( } ) + /** + * Returns a [State] holding the content [Color] appropriate for the given [state], accounting for selection, + * enabled, pressed, focused, and hovered conditions. + */ @Composable public fun contentFor(state: ChipState): State = rememberUpdatedState( @@ -121,6 +170,10 @@ public class ChipColors( } ) + /** + * Returns a [State] holding the border [Color] appropriate for the given [state], accounting for selection, + * enabled, pressed, focused, and hovered conditions. + */ @Composable public fun borderFor(state: ChipState): State = rememberUpdatedState( @@ -252,16 +305,26 @@ public class ChipColors( ")" } + /** Companion object for [ChipColors]. */ public companion object } +/** + * Holds size and spacing metrics for the Chip component, including corner size, padding, border widths, and minimum + * size. + */ @Stable @GenerateDataFunctions public class ChipMetrics( + /** The corner radius of the chip. */ public val cornerSize: CornerSize, + /** The inner padding applied to the chip content. */ public val padding: PaddingValues, + /** The width of the chip border in the default state. */ public val borderWidth: Dp, + /** The width of the chip border when selected. */ public val borderWidthSelected: Dp, + /** The minimum size of the chip. */ public val minSize: DpSize, ) { @Deprecated("Use the version with 'minSize' instead") @@ -306,9 +369,11 @@ public class ChipMetrics( ")" } + /** Companion object for [ChipMetrics]. */ public companion object } +/** CompositionLocal providing the current [ChipStyle]. */ public val LocalChipStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No ChipStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CircularProgressStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CircularProgressStyle.kt index 6f6d9caa13f0..f49050ed93da 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CircularProgressStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/CircularProgressStyle.kt @@ -6,11 +6,19 @@ import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.graphics.Color import kotlin.time.Duration +/** Holds styling properties for the circular progress indicator, including frame duration and color. */ @Immutable -public class CircularProgressStyle(public val frameTime: Duration, public val color: Color) { +public class CircularProgressStyle( + /** The duration of each animation frame. */ + public val frameTime: Duration, + /** The color of the progress indicator. */ + public val color: Color, +) { + /** Companion object for [CircularProgressStyle]. */ public companion object } +/** CompositionLocal providing the current [CircularProgressStyle]. */ public val LocalCircularProgressStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No CircularProgressStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ComboBoxStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ComboBoxStyling.kt index 96c07ad50f94..73001d20e99b 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ComboBoxStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ComboBoxStyling.kt @@ -16,11 +16,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.ComboBoxState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines [ComboBoxColors], [ComboBoxMetrics], and [ComboBoxIcons] to fully style a ComboBox component. */ @Stable @GenerateDataFunctions public class ComboBoxStyle( + /** The color tokens for the combo box. */ public val colors: ComboBoxColors, + /** The size and spacing metrics for the combo box. */ public val metrics: ComboBoxMetrics, + /** The icon keys for the combo box. */ public val icons: ComboBoxIcons, ) { override fun equals(other: Any?): Boolean { @@ -45,29 +49,56 @@ public class ComboBoxStyle( override fun toString(): String = "ComboBoxStyle(colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [ComboBoxStyle]. */ public companion object } +/** + * Holds color tokens for the ComboBox component in its various states (normal, disabled, focused, pressed, hovered). + */ @Immutable @GenerateDataFunctions public class ComboBoxColors( + /** The background color in the normal state. */ public val background: Color, + /** The background color when the combo box is not editable. */ public val nonEditableBackground: Color, + /** The background color in the disabled state. */ public val backgroundDisabled: Color, + /** The background color in the focused state. */ public val backgroundFocused: Color, + /** The background color in the pressed state. */ public val backgroundPressed: Color, + /** The background color in the hovered state. */ public val backgroundHovered: Color, + /** The content (text/icon) color in the normal state. */ public val content: Color, + /** The content color in the disabled state. */ public val contentDisabled: Color, + /** The content color in the focused state. */ public val contentFocused: Color, + /** The content color in the pressed state. */ public val contentPressed: Color, + /** The content color in the hovered state. */ public val contentHovered: Color, + /** The border color in the normal state. */ public val border: Color, + /** The border color in the disabled state. */ public val borderDisabled: Color, + /** The border color in the focused state. */ public val borderFocused: Color, + /** The border color in the pressed state. */ public val borderPressed: Color, + /** The border color in the hovered state. */ public val borderHovered: Color, ) { + /** + * Returns a [State] holding the background color appropriate for the given [state], taking editability into + * account. + * + * @param state the current interaction state of the combo box. + * @param isEditable whether the combo box allows text input. + */ @Composable public fun backgroundFor(state: ComboBoxState, isEditable: Boolean): State = rememberUpdatedState( @@ -84,6 +115,7 @@ public class ComboBoxColors( } ) + /** Returns a [State] holding the content (text/icon) color appropriate for the given [state]. */ @Composable public fun contentFor(state: ComboBoxState): State = rememberUpdatedState( @@ -97,6 +129,7 @@ public class ComboBoxColors( ) ) + /** Returns a [State] holding the border color appropriate for the given [state]. */ @Composable public fun borderFor(state: ComboBoxState): State = rememberUpdatedState( @@ -177,19 +210,32 @@ public class ComboBoxColors( ")" } + /** Companion object for [ComboBoxColors]. */ public companion object } +/** + * Holds size and spacing metrics for the ComboBox component, including arrow area, corner, padding, border, and popup + * dimensions. + */ @Stable @GenerateDataFunctions public class ComboBoxMetrics( + /** The size of the arrow (chevron) area on the trailing side. */ public val arrowAreaSize: DpSize, + /** The minimum size of the combo box. */ public val minSize: DpSize, + /** The corner radius of the combo box. */ public val cornerSize: CornerSize, + /** The padding applied to the combo box content. */ public val contentPadding: PaddingValues, + /** The padding applied to the popup content. */ public val popupContentPadding: PaddingValues, + /** The width of the combo box border. */ public val borderWidth: Dp, + /** The maximum height of the popup dropdown. */ public val maxPopupHeight: Dp, + /** The maximum number of visible rows in the popup dropdown. */ public val maxPopupRowCount: Int, ) { init { @@ -249,12 +295,17 @@ public class ComboBoxMetrics( ")" } + /** Companion object for [ComboBoxMetrics]. */ public companion object } +/** Holds icon keys for the ComboBox component, providing the chevron-down arrow icon. */ @Immutable @GenerateDataFunctions -public class ComboBoxIcons(public val chevronDown: IconKey) { +public class ComboBoxIcons( + /** The icon key for the chevron-down arrow. */ + public val chevronDown: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -268,13 +319,16 @@ public class ComboBoxIcons(public val chevronDown: IconKey) { override fun toString(): String = "ComboBoxIcons(chevronDown=$chevronDown)" + /** Companion object for [ComboBoxIcons]. */ public companion object } +/** CompositionLocal providing the default (bordered) [ComboBoxStyle] for the current theme. */ public val LocalDefaultComboBoxStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DefaultComboBoxStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the undecorated (borderless) [ComboBoxStyle] for the current theme. */ public val LocalUndecoratedComboBoxStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No UndecoratedComboBoxStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DividerStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DividerStyling.kt index 960af885bbf3..285a1eb92e5f 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DividerStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DividerStyling.kt @@ -8,9 +8,15 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines the color and metrics styling for a divider component. */ @Immutable @GenerateDataFunctions -public class DividerStyle(public val color: Color, public val metrics: DividerMetrics) { +public class DividerStyle( + /** The color of the divider line. */ + public val color: Color, + /** The size and spacing metrics for the divider. */ + public val metrics: DividerMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -31,12 +37,19 @@ public class DividerStyle(public val color: Color, public val metrics: DividerMe override fun toString(): String = "DividerStyle(color=$color, metrics=$metrics)" + /** Companion object for [DividerStyle]. */ public companion object } +/** Holds size and spacing metrics for the divider component. */ @Immutable @GenerateDataFunctions -public class DividerMetrics(public val thickness: Dp, public val startIndent: Dp) { +public class DividerMetrics( + /** The thickness of the divider line. */ + public val thickness: Dp, + /** The indent applied at the start of the divider. */ + public val startIndent: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -57,12 +70,15 @@ public class DividerMetrics(public val thickness: Dp, public val startIndent: Dp override fun toString(): String = "DividerMetrics(thickness=$thickness, startIndent=$startIndent)" + /** Companion object for [DividerMetrics]. */ public companion object { + /** Returns a [DividerMetrics] instance with default thickness and start indent values. */ public fun defaults(thickness: Dp = 1.dp, startIndent: Dp = 0.dp): DividerMetrics = DividerMetrics(thickness, startIndent) } } +/** CompositionLocal used to provide the current [DividerStyle] down the composition tree. */ public val LocalDividerStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DividerStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DropdownStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DropdownStyling.kt index 31b1a747547f..6d14bc7b9a6a 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DropdownStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/DropdownStyling.kt @@ -18,12 +18,17 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.DropdownState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines the colors, metrics, icons, and menu style that define the appearance of a Dropdown component. */ @Stable @GenerateDataFunctions public class DropdownStyle( + /** The color tokens for the dropdown in its various states. */ public val colors: DropdownColors, + /** The size and spacing metrics for the dropdown. */ public val metrics: DropdownMetrics, + /** The icon keys used by the dropdown. */ public val icons: DropdownIcons, + /** The style applied to the dropdown's popup menu. */ public val menuStyle: MenuStyle, ) { override fun equals(other: Any?): Boolean { @@ -57,33 +62,56 @@ public class DropdownStyle( ")" } + /** Companion object for [DropdownStyle]. */ public companion object } +/** Holds color tokens for the Dropdown component in its various interaction states. */ @Immutable @GenerateDataFunctions public class DropdownColors( + /** The background color in the normal state. */ public val background: Color, + /** The background color when the dropdown is disabled. */ public val backgroundDisabled: Color, + /** The background color when the dropdown is focused. */ public val backgroundFocused: Color, + /** The background color when the dropdown is pressed. */ public val backgroundPressed: Color, + /** The background color when the dropdown is hovered. */ public val backgroundHovered: Color, + /** The content (text) color in the normal state. */ public val content: Color, + /** The content color when the dropdown is disabled. */ public val contentDisabled: Color, + /** The content color when the dropdown is focused. */ public val contentFocused: Color, + /** The content color when the dropdown is pressed. */ public val contentPressed: Color, + /** The content color when the dropdown is hovered. */ public val contentHovered: Color, + /** The border color in the normal state. */ public val border: Color, + /** The border color when the dropdown is disabled. */ public val borderDisabled: Color, + /** The border color when the dropdown is focused. */ public val borderFocused: Color, + /** The border color when the dropdown is pressed. */ public val borderPressed: Color, + /** The border color when the dropdown is hovered. */ public val borderHovered: Color, + /** The chevron icon tint color in the normal state. */ public val iconTint: Color, + /** The chevron icon tint color when the dropdown is disabled. */ public val iconTintDisabled: Color, + /** The chevron icon tint color when the dropdown is focused. */ public val iconTintFocused: Color, + /** The chevron icon tint color when the dropdown is pressed. */ public val iconTintPressed: Color, + /** The chevron icon tint color when the dropdown is hovered. */ public val iconTintHovered: Color, ) { + /** Returns a [State] holding the background color appropriate for the given [state]. */ @Composable public fun backgroundFor(state: DropdownState): State = rememberUpdatedState( @@ -97,6 +125,7 @@ public class DropdownColors( } ) + /** Returns a [State] holding the content color appropriate for the given [state]. */ @Composable public fun contentFor(state: DropdownState): State = rememberUpdatedState( @@ -110,6 +139,7 @@ public class DropdownColors( ) ) + /** Returns a [State] holding the border color appropriate for the given [state]. */ @Composable public fun borderFor(state: DropdownState): State = rememberUpdatedState( @@ -123,6 +153,7 @@ public class DropdownColors( ) ) + /** Returns a [State] holding the icon tint color appropriate for the given [state]. */ @Composable public fun iconTintFor(state: DropdownState): State = rememberUpdatedState( @@ -215,16 +246,23 @@ public class DropdownColors( ")" } + /** Companion object for [DropdownColors]. */ public companion object } +/** Holds size and spacing metrics for the Dropdown component. */ @Stable @GenerateDataFunctions public class DropdownMetrics( + /** The minimum size of the chevron arrow area. */ public val arrowMinSize: DpSize, + /** The minimum size of the dropdown control. */ public val minSize: DpSize, + /** The corner radius of the dropdown border. */ public val cornerSize: CornerSize, + /** The padding applied to the dropdown's content area. */ public val contentPadding: PaddingValues, + /** The width of the dropdown border. */ public val borderWidth: Dp, ) { override fun equals(other: Any?): Boolean { @@ -261,12 +299,17 @@ public class DropdownMetrics( ")" } + /** Companion object for [DropdownMetrics]. */ public companion object } +/** Holds icon keys for the Dropdown component. */ @Immutable @GenerateDataFunctions -public class DropdownIcons(public val chevronDown: IconKey) { +public class DropdownIcons( + /** The icon key for the chevron-down arrow shown in the dropdown. */ + public val chevronDown: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -280,13 +323,16 @@ public class DropdownIcons(public val chevronDown: IconKey) { override fun toString(): String = "DropdownIcons(chevronDown=$chevronDown)" + /** Companion object for [DropdownIcons]. */ public companion object } +/** CompositionLocal providing the default [DropdownStyle] for themed dropdown components. */ public val LocalDefaultDropdownStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No DefaultDropdownStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the undecorated [DropdownStyle] for borderless dropdown components. */ public val LocalUndecoratedDropdownStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No UndecoratedDropdownStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/GroupHeaderStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/GroupHeaderStyling.kt index 5c975bdc76de..2763c0eb77a1 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/GroupHeaderStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/GroupHeaderStyling.kt @@ -7,9 +7,15 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines [GroupHeaderColors] and [GroupHeaderMetrics] to style the GroupHeader component. */ @Immutable @GenerateDataFunctions -public class GroupHeaderStyle(public val colors: GroupHeaderColors, public val metrics: GroupHeaderMetrics) { +public class GroupHeaderStyle( + /** The color tokens for the GroupHeader component. */ + public val colors: GroupHeaderColors, + /** The size and spacing metrics for the GroupHeader component. */ + public val metrics: GroupHeaderMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -30,12 +36,17 @@ public class GroupHeaderStyle(public val colors: GroupHeaderColors, public val m override fun toString(): String = "GroupHeaderStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [GroupHeaderStyle]. */ public companion object } +/** Holds color tokens for the GroupHeader component, including the divider color. */ @Immutable @GenerateDataFunctions -public class GroupHeaderColors(public val divider: Color) { +public class GroupHeaderColors( + /** The color of the divider line. */ + public val divider: Color +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -49,12 +60,19 @@ public class GroupHeaderColors(public val divider: Color) { override fun toString(): String = "GroupHeaderColors(divider=$divider)" + /** Companion object for [GroupHeaderColors]. */ public companion object } +/** Holds size and spacing metrics for the GroupHeader component, such as divider thickness and indent. */ @Immutable @GenerateDataFunctions -public class GroupHeaderMetrics(public val dividerThickness: Dp, public val indent: Dp) { +public class GroupHeaderMetrics( + /** The thickness of the divider line. */ + public val dividerThickness: Dp, + /** The horizontal indent of the header content. */ + public val indent: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -75,9 +93,11 @@ public class GroupHeaderMetrics(public val dividerThickness: Dp, public val inde override fun toString(): String = "GroupHeaderMetrics(dividerThickness=$dividerThickness, indent=$indent)" + /** Companion object for [GroupHeaderMetrics]. */ public companion object } +/** CompositionLocal providing the current [GroupHeaderStyle]. */ public val LocalGroupHeaderStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No GroupHeaderStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyling.kt index 6b3e3fb985b5..aa5595a0faab 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/HorizontalProgressBarStyling.kt @@ -9,11 +9,15 @@ import androidx.compose.ui.unit.Dp import kotlin.time.Duration import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines colors, metrics, and indeterminate cycle duration for styling a horizontal progress bar. */ @Immutable @GenerateDataFunctions public class HorizontalProgressBarStyle( + /** The color tokens for the progress bar. */ public val colors: HorizontalProgressBarColors, + /** The size and spacing metrics for the progress bar. */ public val metrics: HorizontalProgressBarMetrics, + /** The duration of one full indeterminate animation cycle. */ public val indeterminateCycleDuration: Duration, ) { override fun equals(other: Any?): Boolean { @@ -44,15 +48,24 @@ public class HorizontalProgressBarStyle( ")" } + /** Companion object for [HorizontalProgressBarStyle]. */ public companion object } +/** + * Holds color tokens for the horizontal progress bar component in its various states, including indeterminate + * animation. + */ @Immutable @GenerateDataFunctions public class HorizontalProgressBarColors( + /** The color of the track (unfilled portion) of the progress bar. */ public val track: Color, + /** The color of the filled progress indicator. */ public val progress: Color, + /** The base color used during indeterminate animation. */ public val indeterminateBase: Color, + /** The highlight color used during indeterminate animation. */ public val indeterminateHighlight: Color, ) { override fun equals(other: Any?): Boolean { @@ -86,14 +99,22 @@ public class HorizontalProgressBarColors( ")" } + /** Companion object for [HorizontalProgressBarColors]. */ public companion object } +/** + * Holds size and spacing metrics for the horizontal progress bar component, including corner size and indeterminate + * highlight width. + */ @Immutable @GenerateDataFunctions public class HorizontalProgressBarMetrics( + /** The corner radius of the progress bar track and indicator. */ public val cornerSize: CornerSize, + /** The minimum height of the progress bar. */ public val minHeight: Dp, + /** The width of the moving highlight segment during indeterminate animation. */ public val indeterminateHighlightWidth: Dp, ) { override fun equals(other: Any?): Boolean { @@ -124,9 +145,11 @@ public class HorizontalProgressBarMetrics( ")" } + /** Companion object for [HorizontalProgressBarMetrics]. */ public companion object } +/** CompositionLocal providing the current [HorizontalProgressBarStyle]. */ public val LocalHorizontalProgressBarStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No HorizontalProgressBarStyle provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/IconButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/IconButtonStyling.kt index 699467a2bc03..f375bae926a3 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/IconButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/IconButtonStyling.kt @@ -20,9 +20,15 @@ import org.jetbrains.jewel.ui.component.IconButtonState import org.jetbrains.jewel.ui.component.SelectableIconButtonState import org.jetbrains.jewel.ui.component.ToggleableIconButtonState +/** Defines the styling for an icon button, combining its color tokens and size/spacing metrics. */ @Stable @GenerateDataFunctions -public class IconButtonStyle(public val colors: IconButtonColors, public val metrics: IconButtonMetrics) { +public class IconButtonStyle( + /** The color tokens for each interaction state. */ + public val colors: IconButtonColors, + /** The size and spacing metrics. */ + public val metrics: IconButtonMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -43,28 +49,46 @@ public class IconButtonStyle(public val colors: IconButtonColors, public val met override fun toString(): String = "IconButtonStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [IconButtonStyle]. */ public companion object } +/** Holds color tokens for an icon button's background, border, and foreground in each interaction state. */ @Immutable @GenerateDataFunctions public class IconButtonColors( + /** The foreground color when the button is both selected and the window is active. */ public val foregroundSelectedActivated: Color, + /** The default background color. */ public val background: Color, + /** The background color when the button is disabled. */ public val backgroundDisabled: Color, + /** The background color when the button is selected. */ public val backgroundSelected: Color, + /** The background color when the button is selected and the window is active. */ public val backgroundSelectedActivated: Color, + /** The background color when the button is focused. */ public val backgroundFocused: Color, + /** The background color when the button is pressed. */ public val backgroundPressed: Color, + /** The background color when the button is hovered. */ public val backgroundHovered: Color, + /** The default border color. */ public val border: Color, + /** The border color when the button is disabled. */ public val borderDisabled: Color, + /** The border color when the button is selected. */ public val borderSelected: Color, + /** The border color when the button is selected and the window is active. */ public val borderSelectedActivated: Color, + /** The border color when the button is focused. */ public val borderFocused: Color, + /** The border color when the button is pressed. */ public val borderPressed: Color, + /** The border color when the button is hovered. */ public val borderHovered: Color, ) { + /** Returns a [State] holding the background color appropriate for the given [state]. */ @Composable public fun backgroundFor(state: IconButtonState): State = rememberUpdatedState( @@ -77,6 +101,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the background color appropriate for the given selectable [state], accounting for + * selection and activation. + */ @Composable public fun selectableBackgroundFor(state: SelectableIconButtonState): State = rememberUpdatedState( @@ -91,6 +119,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the background color appropriate for the given toggleable [state], accounting for + * toggle state and activation. + */ @Composable public fun toggleableBackgroundFor(state: ToggleableIconButtonState): State = rememberUpdatedState( @@ -105,6 +137,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the foreground color appropriate for the given selectable [state], using the + * activated-selection color when both active and selected. + */ @Composable public fun selectableForegroundFor(state: SelectableIconButtonState): State = rememberUpdatedState( @@ -114,6 +150,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the foreground color appropriate for the given toggleable [state], using the + * activated-selection color when active and toggled on. + */ @Composable public fun toggleableForegroundFor(state: ToggleableIconButtonState): State = rememberUpdatedState( @@ -123,6 +163,7 @@ public class IconButtonColors( } ) + /** Returns a [State] holding the border color appropriate for the given [state]. */ @Composable public fun borderFor(state: IconButtonState): State = rememberUpdatedState( @@ -135,6 +176,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the border color appropriate for the given selectable [state], accounting for selection + * and activation. + */ @Composable public fun selectableBorderFor(state: SelectableIconButtonState): State = rememberUpdatedState( @@ -149,6 +194,10 @@ public class IconButtonColors( } ) + /** + * Returns a [State] holding the border color appropriate for the given toggleable [state], accounting for toggle + * state and activation. + */ @Composable public fun toggleableBorderFor(state: ToggleableIconButtonState): State = rememberUpdatedState( @@ -227,15 +276,23 @@ public class IconButtonColors( ")" } + /** Companion object for [IconButtonColors]. */ public companion object } +/** + * Holds size and spacing metrics for an icon button, including corner size, border width, padding, and minimum size. + */ @Stable @GenerateDataFunctions public class IconButtonMetrics( + /** The corner radius of the button. */ public val cornerSize: CornerSize, + /** The width of the button border. */ public val borderWidth: Dp, + /** The inner padding of the button. */ public val padding: PaddingValues, + /** The minimum size of the button. */ public val minSize: DpSize, ) { override fun equals(other: Any?): Boolean { @@ -269,13 +326,16 @@ public class IconButtonMetrics( ")" } + /** Companion object for [IconButtonMetrics]. */ public companion object } +/** CompositionLocal providing the current [IconButtonStyle]. */ public val LocalIconButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No IconButtonStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the current transparent [IconButtonStyle]. */ @ApiStatus.Experimental @ExperimentalJewelApi public val LocalTransparentIconButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/InputFieldStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/InputFieldStyling.kt index 5287eb03fc58..170d7fe66161 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/InputFieldStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/InputFieldStyling.kt @@ -12,20 +12,35 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import org.jetbrains.jewel.ui.component.InputFieldState +/** Defines the overall style for an input field, combining colors and metrics. */ @Stable public interface InputFieldStyle { + /** The color tokens for this input field. */ public val colors: InputFieldColors + + /** The size and spacing metrics for this input field. */ public val metrics: InputFieldMetrics } +/** Holds color tokens for an input field component in its various interaction states. */ @Immutable public interface InputFieldColors { + /** The background color in the normal state. */ public val background: Color + + /** The background color when the input field is disabled. */ public val backgroundDisabled: Color + + /** The background color when the input field is focused. */ public val backgroundFocused: Color + + /** The background color when the input field is pressed. */ public val backgroundPressed: Color + + /** The background color when the input field is hovered. */ public val backgroundHovered: Color + /** Returns a [State] holding the background color appropriate for the given [state]. */ @Composable public fun backgroundFor(state: InputFieldState): State = rememberUpdatedState( @@ -39,12 +54,22 @@ public interface InputFieldColors { ) ) + /** The content (text) color in the normal state. */ public val content: Color + + /** The content (text) color when the input field is disabled. */ public val contentDisabled: Color + + /** The content (text) color when the input field is focused. */ public val contentFocused: Color + + /** The content (text) color when the input field is pressed. */ public val contentPressed: Color + + /** The content (text) color when the input field is hovered. */ public val contentHovered: Color + /** Returns a [State] holding the content (text) color appropriate for the given [state]. */ @Composable public fun contentFor(state: InputFieldState): State = rememberUpdatedState( @@ -58,12 +83,22 @@ public interface InputFieldColors { ) ) + /** The border color in the normal state. */ public val border: Color + + /** The border color when the input field is disabled. */ public val borderDisabled: Color + + /** The border color when the input field is focused. */ public val borderFocused: Color + + /** The border color when the input field is pressed. */ public val borderPressed: Color + + /** The border color when the input field is hovered. */ public val borderHovered: Color + /** Returns a [State] holding the border color appropriate for the given [state]. */ @Composable public fun borderFor(state: InputFieldState): State = rememberUpdatedState( @@ -77,12 +112,22 @@ public interface InputFieldColors { ) ) + /** The caret color in the normal state. */ public val caret: Color + + /** The caret color when the input field is disabled. */ public val caretDisabled: Color + + /** The caret color when the input field is focused. */ public val caretFocused: Color + + /** The caret color when the input field is pressed. */ public val caretPressed: Color + + /** The caret color when the input field is hovered. */ public val caretHovered: Color + /** Returns a [State] holding the caret color appropriate for the given [state]. */ @Composable public fun caretFor(state: InputFieldState): State = rememberUpdatedState( @@ -97,10 +142,18 @@ public interface InputFieldColors { ) } +/** Holds size and spacing metrics for an input field component. */ @Stable public interface InputFieldMetrics { + /** The corner radius of the input field. */ public val cornerSize: CornerSize + + /** The padding applied around the content inside the input field. */ public val contentPadding: PaddingValues + + /** The minimum size of the input field. */ public val minSize: DpSize + + /** The width of the input field border. */ public val borderWidth: Dp } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LazyTreeStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LazyTreeStyling.kt index dafbe1c32b45..5040f05b7c17 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LazyTreeStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LazyTreeStyling.kt @@ -14,11 +14,15 @@ import org.jetbrains.jewel.foundation.lazy.tree.TreeElementState import org.jetbrains.jewel.ui.icon.IconKey // TODO: Composition with SimpleItemStyle +/** Combines the colors, metrics, and icons that style a lazy tree component. */ @Stable @GenerateDataFunctions public class LazyTreeStyle( + /** The colors used to render list items in the tree. */ public val colors: SimpleListItemColors, + /** The size and spacing metrics for the tree. */ public val metrics: LazyTreeMetrics, + /** The icons used for the tree chevrons. */ public val icons: LazyTreeIcons, ) { override fun equals(other: Any?): Boolean { @@ -43,9 +47,11 @@ public class LazyTreeStyle( override fun toString(): String = "LazyTreeStyle(colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [LazyTreeStyle]. */ public companion object } +/** Returns a [State] holding the content color appropriate for the given [state]. */ @Composable public fun SimpleListItemColors.contentFor(state: TreeElementState): State = rememberUpdatedState( @@ -57,12 +63,17 @@ public fun SimpleListItemColors.contentFor(state: TreeElementState): State = staticCompositionLocalOf { error("No LazyTreeStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LinkStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LinkStyling.kt index f47f126b5b6f..edb87a321988 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LinkStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/LinkStyling.kt @@ -14,12 +14,17 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.LinkState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines [LinkColors], [LinkMetrics], [LinkIcons], and underline behavior for styling a Link component. */ @Immutable @GenerateDataFunctions public class LinkStyle( + /** The color tokens for the link. */ public val colors: LinkColors, + /** The size and spacing metrics for the link. */ public val metrics: LinkMetrics, + /** The icon keys for the link. */ public val icons: LinkIcons, + /** The underline behavior for the link. */ public val underlineBehavior: LinkUnderlineBehavior, ) { override fun equals(other: Any?): Boolean { @@ -53,19 +58,31 @@ public class LinkStyle( ")" } + /** Companion object for [LinkStyle]. */ public companion object } +/** Holds color tokens for the Link component in its various states, including visited and disabled. */ @Immutable @GenerateDataFunctions public class LinkColors( + /** The content color in the normal state. */ public val content: Color, + /** The content color when the link is disabled. */ public val contentDisabled: Color, + /** The content color when the link is focused. */ public val contentFocused: Color, + /** The content color when the link is pressed. */ public val contentPressed: Color, + /** The content color when the link is hovered. */ public val contentHovered: Color, + /** The content color when the link has been visited. */ public val contentVisited: Color, ) { + /** + * Returns a [State] holding the content color appropriate for the given [state], including visited and disabled + * variants. + */ @Composable public fun contentFor(state: LinkState): State = rememberUpdatedState( @@ -117,14 +134,22 @@ public class LinkColors( ")" } + /** Companion object for [LinkColors]. */ public companion object } +/** + * Holds size and spacing metrics for the Link component, including focus halo corner size, text-icon gap, and icon + * size. + */ @Immutable @GenerateDataFunctions public class LinkMetrics( + /** The corner size of the focus halo. */ public val focusHaloCornerSize: CornerSize, + /** The gap between the link text and its icon. */ public val textIconGap: Dp, + /** The size of the link icon. */ public val iconSize: DpSize, ) { override fun equals(other: Any?): Boolean { @@ -155,12 +180,19 @@ public class LinkMetrics( ")" } + /** Companion object for [LinkMetrics]. */ public companion object } +/** Holds icon keys for the Link component, providing the dropdown chevron and external link icons. */ @Immutable @GenerateDataFunctions -public class LinkIcons(public val dropdownChevron: IconKey, public val externalLink: IconKey) { +public class LinkIcons( + /** The icon key for the dropdown chevron. */ + public val dropdownChevron: IconKey, + /** The icon key for external link indicators. */ + public val externalLink: IconKey, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -181,14 +213,20 @@ public class LinkIcons(public val dropdownChevron: IconKey, public val externalL override fun toString(): String = "LinkIcons(dropdownChevron=$dropdownChevron, externalLink=$externalLink)" + /** Companion object for [LinkIcons]. */ public companion object } +/** CompositionLocal used to provide the [LinkStyle] to link components. */ public val LocalLinkStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LinkStyle provided. Have you forgotten the theme?") } +/** Controls when the underline decoration is shown on a Link component. */ public enum class LinkUnderlineBehavior { + /** The underline is always visible. */ ShowAlways, + + /** The underline is only visible when the link is hovered. */ ShowOnHover, } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/MenuStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/MenuStyling.kt index 116fc7077604..9c5eddb41b42 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/MenuStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/MenuStyling.kt @@ -18,12 +18,17 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.MenuItemState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines colors, metrics, and icons that define the appearance of a menu component. */ @Stable @GenerateDataFunctions public class MenuStyle( + /** Whether the menu is rendered in dark mode. */ public val isDark: Boolean, + /** The color tokens for the menu. */ public val colors: MenuColors, + /** The size and spacing metrics for the menu. */ public val metrics: MenuMetrics, + /** The icon keys for the menu. */ public val icons: MenuIcons, ) { override fun equals(other: Any?): Boolean { @@ -50,15 +55,21 @@ public class MenuStyle( override fun toString(): String = "MenuStyle(isDark=$isDark, colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [MenuStyle]. */ public companion object } +/** Holds color tokens for the menu component, including background, border, shadow, and per-item colors. */ @Immutable @GenerateDataFunctions public class MenuColors( + /** The background color of the menu. */ public val background: Color, + /** The border color of the menu. */ public val border: Color, + /** The shadow color of the menu. */ public val shadow: Color, + /** The color tokens for menu items. */ public val itemColors: MenuItemColors, ) { override fun equals(other: Any?): Boolean { @@ -92,34 +103,58 @@ public class MenuColors( ")" } + /** Companion object for [MenuColors]. */ public companion object } +/** Holds color tokens for a menu item in its various states (normal, disabled, focused, pressed, hovered). */ @Immutable @GenerateDataFunctions public class MenuItemColors( + /** The background color of a menu item in its normal state. */ public val background: Color, + /** The background color of a menu item in its disabled state. */ public val backgroundDisabled: Color, + /** The background color of a menu item in its focused state. */ public val backgroundFocused: Color, + /** The background color of a menu item in its pressed state. */ public val backgroundPressed: Color, + /** The background color of a menu item in its hovered state. */ public val backgroundHovered: Color, + /** The content (text) color of a menu item in its normal state. */ public val content: Color, + /** The content (text) color of a menu item in its disabled state. */ public val contentDisabled: Color, + /** The content (text) color of a menu item in its focused state. */ public val contentFocused: Color, + /** The content (text) color of a menu item in its pressed state. */ public val contentPressed: Color, + /** The content (text) color of a menu item in its hovered state. */ public val contentHovered: Color, + /** The icon tint color of a menu item in its normal state. */ public val iconTint: Color, + /** The icon tint color of a menu item in its disabled state. */ public val iconTintDisabled: Color, + /** The icon tint color of a menu item in its focused state. */ public val iconTintFocused: Color, + /** The icon tint color of a menu item in its pressed state. */ public val iconTintPressed: Color, + /** The icon tint color of a menu item in its hovered state. */ public val iconTintHovered: Color, + /** The keybinding hint tint color of a menu item in its normal state. */ public val keybindingTint: Color, + /** The keybinding hint tint color of a menu item in its disabled state. */ public val keybindingTintDisabled: Color, + /** The keybinding hint tint color of a menu item in its focused state. */ public val keybindingTintFocused: Color, + /** The keybinding hint tint color of a menu item in its pressed state. */ public val keybindingTintPressed: Color, + /** The keybinding hint tint color of a menu item in its hovered state. */ public val keybindingTintHovered: Color, + /** The color of the separator line between menu items. */ public val separator: Color, ) { + /** Returns a [State] holding the background color appropriate for the given [state]. */ @Deprecated("This is being made private") @Composable public fun backgroundFor(state: MenuItemState): State = @@ -134,6 +169,7 @@ public class MenuItemColors( ) ) + /** Returns a [State] holding the content (text) color appropriate for the given [state]. */ @Deprecated("This is being made private") @Composable public fun contentFor(state: MenuItemState): State = @@ -148,6 +184,7 @@ public class MenuItemColors( ) ) + /** Returns a [State] holding the icon tint color appropriate for the given [state]. */ @Deprecated("This is being made private") @Composable public fun iconTintFor(state: MenuItemState): State = @@ -162,6 +199,7 @@ public class MenuItemColors( ) ) + /** Returns a [State] holding the keybinding tint color appropriate for the given [state]. */ @Deprecated("This is being made private") @Composable public fun keybindingTintFor(state: MenuItemState): State = @@ -258,19 +296,32 @@ public class MenuItemColors( ")" } + /** Companion object for [MenuItemColors]. */ public companion object } +/** + * Holds size and spacing metrics for the menu component, including corner size, padding, offset, shadow, and per-item + * metrics. + */ @Stable @GenerateDataFunctions public class MenuMetrics( + /** The corner radius of the menu popup. */ public val cornerSize: CornerSize, + /** The outer margin around the menu popup. */ public val menuMargin: PaddingValues, + /** The inner content padding of the menu popup. */ public val contentPadding: PaddingValues, + /** The display offset of the menu popup relative to its anchor. */ public val offset: DpOffset, + /** The size of the drop shadow behind the menu popup. */ public val shadowSize: Dp, + /** The width of the menu popup border. */ public val borderWidth: Dp, + /** The size and spacing metrics for menu items. */ public val itemMetrics: MenuItemMetrics, + /** The size and spacing metrics for submenus. */ public val submenuMetrics: SubmenuMetrics, ) { override fun equals(other: Any?): Boolean { @@ -316,20 +367,34 @@ public class MenuMetrics( ")" } + /** Companion object for [MenuMetrics]. */ public companion object } +/** + * Holds size and spacing metrics for a menu item, including padding, separator dimensions, icon size, and minimum + * height. + */ @Stable @GenerateDataFunctions public class MenuItemMetrics( + /** The corner radius of the selection highlight for a menu item. */ public val selectionCornerSize: CornerSize, + /** The outer padding around the menu item row. */ public val outerPadding: PaddingValues, + /** The inner content padding within the menu item row. */ public val contentPadding: PaddingValues, + /** The padding around the separator line. */ public val separatorPadding: PaddingValues, + /** The padding around the keybinding hint text. */ public val keybindingsPadding: PaddingValues, + /** The thickness of the separator line. */ public val separatorThickness: Dp, + /** The total height of the separator row. */ public val separatorHeight: Dp, + /** The size of the leading icon in a menu item. */ public val iconSize: Dp, + /** The minimum height of a menu item row. */ public val minHeight: Dp, ) { override fun equals(other: Any?): Boolean { @@ -378,12 +443,17 @@ public class MenuItemMetrics( ")" } + /** Companion object for [MenuItemMetrics]. */ public companion object } +/** Holds size and spacing metrics for a submenu, specifically the display offset relative to its parent item. */ @Stable @GenerateDataFunctions -public class SubmenuMetrics(public val offset: DpOffset) { +public class SubmenuMetrics( + /** The display offset of a submenu popup relative to its parent item. */ + public val offset: DpOffset +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -397,12 +467,17 @@ public class SubmenuMetrics(public val offset: DpOffset) { override fun toString(): String = "SubmenuMetrics(offset=$offset)" + /** Companion object for [SubmenuMetrics]. */ public companion object } +/** Holds icon keys for the menu component, including the submenu chevron indicator. */ @Immutable @GenerateDataFunctions -public class MenuIcons(public val submenuChevron: IconKey) { +public class MenuIcons( + /** The icon key for the submenu chevron indicator. */ + public val submenuChevron: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -416,9 +491,11 @@ public class MenuIcons(public val submenuChevron: IconKey) { override fun toString(): String = "MenuIcons(submenuChevron=$submenuChevron)" + /** Companion object for [MenuIcons]. */ public companion object } +/** CompositionLocal used to provide the [MenuStyle] to menu components in the hierarchy. */ public val LocalMenuStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No MenuStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupAdStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupAdStyle.kt index 7b0d419196ce..0cb08cc61c7c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupAdStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupAdStyle.kt @@ -11,9 +11,15 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines [PopupAdColors] and [PopupAdMetrics] to define the full styling for a popup ad component. */ @Stable @GenerateDataFunctions -public class PopupAdStyle(public val colors: PopupAdColors, public val metrics: PopupAdMetrics) { +public class PopupAdStyle( + /** The color tokens for the popup ad component. */ + public val colors: PopupAdColors, + /** The size and spacing metrics for the popup ad component. */ + public val metrics: PopupAdMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -34,12 +40,17 @@ public class PopupAdStyle(public val colors: PopupAdColors, public val metrics: override fun toString(): String = "PopupAdStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [PopupAdStyle]. */ public companion object } +/** Holds the color tokens for the popup ad component, namely its background color. */ @Immutable @GenerateDataFunctions -public class PopupAdColors(public val background: Color) { +public class PopupAdColors( + /** The background color of the popup ad. */ + public val background: Color +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -55,12 +66,19 @@ public class PopupAdColors(public val background: Color) { override fun toString(): String = "PopupAdColors(background=$background)" + /** Companion object for [PopupAdColors]. */ public companion object } +/** Holds size and spacing metrics for the popup ad component, including padding and minimum height. */ @Stable @GenerateDataFunctions -public class PopupAdMetrics(public val padding: PaddingValues, public val minHeight: Dp) { +public class PopupAdMetrics( + /** The padding applied around the popup ad content. */ + public val padding: PaddingValues, + /** The minimum height of the popup ad. */ + public val minHeight: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -81,9 +99,11 @@ public class PopupAdMetrics(public val padding: PaddingValues, public val minHei override fun toString(): String = "PopupAdMetrics(padding=$padding, minHeight=$minHeight)" + /** Companion object for [PopupAdMetrics]. */ public companion object } +/** CompositionLocal providing the current [PopupAdStyle]. */ public val LocalPopupAdStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No PopupAdStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupContainerStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupContainerStyle.kt index 9be82e193ffb..3ea72ad14661 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupContainerStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/PopupContainerStyle.kt @@ -11,11 +11,15 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpOffset import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines color and size/spacing metrics for styling the popup container component. */ @Stable @GenerateDataFunctions public class PopupContainerStyle( + /** Whether the popup container is using a dark color scheme. */ public val isDark: Boolean, + /** The color tokens for the popup container. */ public val colors: PopupContainerColors, + /** The size and spacing metrics for the popup container. */ public val metrics: PopupContainerMetrics, ) { override fun equals(other: Any?): Boolean { @@ -40,12 +44,21 @@ public class PopupContainerStyle( override fun toString(): String = "PopupContainerStyle(isDark=$isDark, colors=$colors, metrics=$metrics)" + /** Companion object for [PopupContainerStyle]. */ public companion object } +/** Holds color tokens for the popup container component, covering its background, border, and shadow. */ @Immutable @GenerateDataFunctions -public class PopupContainerColors(public val background: Color, public val border: Color, public val shadow: Color) { +public class PopupContainerColors( + /** The background color. */ + public val background: Color, + /** The border color. */ + public val border: Color, + /** The shadow color. */ + public val shadow: Color, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -68,17 +81,28 @@ public class PopupContainerColors(public val background: Color, public val borde override fun toString(): String = "PopupContainerColors(background=$background, border=$border, shadow=$shadow)" + /** Companion object for [PopupContainerColors]. */ public companion object } +/** + * Holds size and spacing metrics for the popup container component, including corner size, margins, padding, offset, + * shadow size, and border width. + */ @Stable @GenerateDataFunctions public class PopupContainerMetrics( + /** The corner radius of the popup container. */ public val cornerSize: CornerSize, + /** The outer margin around the popup menu. */ public val menuMargin: PaddingValues, + /** The inner content padding of the popup container. */ public val contentPadding: PaddingValues, + /** The positional offset applied to the popup. */ public val offset: DpOffset, + /** The size of the drop shadow around the popup container. */ public val shadowSize: Dp, + /** The width of the popup container border. */ public val borderWidth: Dp, ) { override fun equals(other: Any?): Boolean { @@ -118,9 +142,11 @@ public class PopupContainerMetrics( ")" } + /** Companion object for [PopupContainerMetrics]. */ public companion object } +/** CompositionLocal providing the current [PopupContainerStyle]. */ public val LocalPopupContainerStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No PopupContainerStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/RadioButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/RadioButtonStyling.kt index f7e88f5aa785..ae4054f9969b 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/RadioButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/RadioButtonStyling.kt @@ -13,11 +13,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.RadioButtonState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines colors, metrics, and icons to fully style a [org.jetbrains.jewel.ui.component.RadioButton]. */ @Immutable @GenerateDataFunctions public class RadioButtonStyle( + /** The color tokens for the radio button. */ public val colors: RadioButtonColors, + /** The size and spacing metrics for the radio button. */ public val metrics: RadioButtonMetrics, + /** The icon keys for the radio button. */ public val icons: RadioButtonIcons, ) { override fun equals(other: Any?): Boolean { @@ -42,19 +46,28 @@ public class RadioButtonStyle( override fun toString(): String = "RadioButtonStyle(colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [RadioButtonStyle]. */ public companion object } +/** Holds color tokens for a [org.jetbrains.jewel.ui.component.RadioButton] in its various states. */ @Immutable @GenerateDataFunctions public class RadioButtonColors( + /** The content (label) color in the default state. */ public val content: Color, + /** The content color when the radio button is hovered. */ public val contentHovered: Color, + /** The content color when the radio button is disabled. */ public val contentDisabled: Color, + /** The content color when the radio button is selected. */ public val contentSelected: Color, + /** The content color when the radio button is selected and hovered. */ public val contentSelectedHovered: Color, + /** The content color when the radio button is selected and disabled. */ public val contentSelectedDisabled: Color, ) { + /** Returns a [State] holding the content color appropriate for the given [state]. */ @Composable public fun contentFor(state: RadioButtonState): State = rememberUpdatedState( @@ -105,19 +118,28 @@ public class RadioButtonColors( ")" } + /** Companion object for [RadioButtonColors]. */ public companion object } +/** Holds size and spacing metrics for a [org.jetbrains.jewel.ui.component.RadioButton]. */ @Immutable @GenerateDataFunctions public class RadioButtonMetrics( + /** The size of the radio button indicator. */ public val radioButtonSize: DpSize, + /** The size of the focus outline in the default state. */ public val outlineSize: DpSize, + /** The size of the focus outline when the radio button is focused. */ public val outlineFocusedSize: DpSize, + /** The size of the focus outline when the radio button is selected. */ public val outlineSelectedSize: DpSize, + /** The size of the focus outline when the radio button is selected and focused. */ public val outlineSelectedFocusedSize: DpSize, + /** The gap between the radio button indicator and the label. */ public val iconContentGap: Dp, ) { + /** Returns a [State] holding the outline size appropriate for the given [state]. */ @Composable public fun outlineSizeFor(state: RadioButtonState): State = rememberUpdatedState( @@ -166,12 +188,17 @@ public class RadioButtonMetrics( ")" } + /** Companion object for [RadioButtonMetrics]. */ public companion object } +/** Holds icon keys for a [org.jetbrains.jewel.ui.component.RadioButton]. */ @Immutable @GenerateDataFunctions -public class RadioButtonIcons(public val radioButton: IconKey) { +public class RadioButtonIcons( + /** The icon key for the radio button indicator image. */ + public val radioButton: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -185,9 +212,11 @@ public class RadioButtonIcons(public val radioButton: IconKey) { override fun toString(): String = "RadioButtonIcons(radioButton=$radioButton)" + /** Companion object for [RadioButtonIcons]. */ public companion object } +/** CompositionLocal providing the current [RadioButtonStyle]. */ public val LocalRadioButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No RadioButtonStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ScrollbarStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ScrollbarStyling.kt index 2ed7003f2c69..02b8198cf2c7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ScrollbarStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ScrollbarStyling.kt @@ -62,6 +62,7 @@ public class ScrollbarStyle( ")" } + /** Companion object for [ScrollbarStyle]. */ public companion object } @@ -151,6 +152,7 @@ public class ScrollbarColors( "trackOpaqueBackgroundHovered=$trackOpaqueBackgroundHovered" + ")" + /** Companion object for [ScrollbarColors]. */ public companion object } @@ -184,6 +186,7 @@ public class ScrollbarMetrics(public val thumbCornerSize: CornerSize, public val override fun toString(): String = "ScrollbarMetrics(thumbCornerSize=$thumbCornerSize, minThumbLength=$minThumbLength)" + /** Companion object for [ScrollbarMetrics]. */ public companion object } @@ -221,6 +224,7 @@ public sealed interface ScrollbarVisibility { */ public val lingerDuration: Duration + /** Companion object for [ScrollbarVisibility]. */ public companion object /** @@ -244,6 +248,10 @@ public sealed interface ScrollbarVisibility { * @param trackColorAnimationDuration The duration for the track color animation. * @param scrollbarBackgroundColorLight The background color in light theme. * @param scrollbarBackgroundColorDark The background color in dark theme. + * @param trackThicknessExpanded The thickness of the track when expanded. Defaults to [trackThickness]. + * @param trackPaddingExpanded The padding around the track when expanded. Defaults to [trackPadding]. + * @param expandAnimationDuration The duration of the expand animation. Defaults to 0ms (no animation). + * @param lingerDuration How long the scrollbar lingers after scrolling stops. Defaults to 0ms. */ @GenerateDataFunctions public class AlwaysVisible( @@ -334,6 +342,7 @@ public sealed interface ScrollbarVisibility { ")" } + /** Companion object for [AlwaysVisible]. */ public companion object } @@ -412,6 +421,7 @@ public sealed interface ScrollbarVisibility { ")" } + /** Companion object for [WhenScrolling]. */ public companion object } } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SearchMatchStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SearchMatchStyle.kt index 4a3c765c7754..bbac08c7bf11 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SearchMatchStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SearchMatchStyle.kt @@ -9,8 +9,14 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines colors and metrics styling for the search match highlight component. */ @GenerateDataFunctions -public class SearchMatchStyle(public val colors: SearchMatchColors, public val metrics: SearchMatchMetrics) { +public class SearchMatchStyle( + /** The color tokens for the search match highlight. */ + public val colors: SearchMatchColors, + /** The size and spacing metrics for the search match highlight. */ + public val metrics: SearchMatchMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -31,13 +37,18 @@ public class SearchMatchStyle(public val colors: SearchMatchColors, public val m override fun toString(): String = "SearchMatchStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [SearchMatchStyle]. */ public companion object } +/** Holds color tokens for the search match highlight component, including gradient background and foreground colors. */ @GenerateDataFunctions public class SearchMatchColors( + /** The start color of the background gradient. */ public val startBackground: Color, + /** The end color of the background gradient. */ public val endBackground: Color, + /** The foreground (text) color. */ public val foreground: Color, ) { override fun equals(other: Any?): Boolean { @@ -63,11 +74,18 @@ public class SearchMatchColors( override fun toString(): String = "SearchMatchColors(startBackground=$startBackground, endBackground=$endBackground, foreground=$foreground)" + /** Companion object for [SearchMatchColors]. */ public companion object } +/** Holds size and spacing metrics for the search match highlight component, including corner size and padding. */ @GenerateDataFunctions -public class SearchMatchMetrics(public val cornerSize: CornerSize, public val padding: PaddingValues) { +public class SearchMatchMetrics( + /** The corner radius of the highlight shape. */ + public val cornerSize: CornerSize, + /** The padding applied inside the highlight. */ + public val padding: PaddingValues, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -88,9 +106,11 @@ public class SearchMatchMetrics(public val cornerSize: CornerSize, public val pa override fun toString(): String = "SearchMatchMetrics(cornerSize=$cornerSize, verticalPadding=$padding)" + /** Companion object for [SearchMatchMetrics]. */ public companion object } +/** CompositionLocal providing the current [SearchMatchStyle]. */ public val LocalSearchMatchStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No SearchMatchStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlButtonStyling.kt index 4024ac088be8..59db42021412 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlButtonStyling.kt @@ -16,10 +16,13 @@ import androidx.compose.ui.unit.DpSize import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.SegmentedControlButtonState +/** Combines [SegmentedControlButtonColors] and [SegmentedControlButtonMetrics] to style a segmented control button. */ @Stable @GenerateDataFunctions public class SegmentedControlButtonStyle( + /** The color tokens for the segmented control button. */ public val colors: SegmentedControlButtonColors, + /** The size and spacing metrics for the segmented control button. */ public val metrics: SegmentedControlButtonMetrics, ) { override fun equals(other: Any?): Boolean { @@ -42,25 +45,43 @@ public class SegmentedControlButtonStyle( override fun toString(): String = "SegmentedControlButtonStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [SegmentedControlButtonStyle]. */ public companion object } +/** Holds color tokens for a segmented control button in its various states. */ @Immutable @GenerateDataFunctions public class SegmentedControlButtonColors( + /** The background brush in the default state. */ public val background: Brush, + /** The background brush when the button is pressed. */ public val backgroundPressed: Brush, + /** The background brush when the button is hovered. */ public val backgroundHovered: Brush, + /** The background brush when the button is selected. */ public val backgroundSelected: Brush, + /** The background brush when the button is selected and focused. */ public val backgroundSelectedFocused: Brush, + /** The content (foreground) color in the default state. */ public val content: Color, + /** The content (foreground) color when the button is disabled. */ public val contentDisabled: Color, + /** The border brush in the default state. */ public val border: Brush, + /** The border brush when the button is selected. */ public val borderSelected: Brush, + /** The border brush when the button is selected and disabled. */ public val borderSelectedDisabled: Brush, + /** The border brush when the button is selected and focused. */ public val borderSelectedFocused: Brush, ) { + /** + * Returns a [State] holding the content color appropriate for the given [state]. + * + * @param state The current [SegmentedControlButtonState]. + */ @Composable public fun contentFor(state: SegmentedControlButtonState): State = rememberUpdatedState( @@ -70,6 +91,13 @@ public class SegmentedControlButtonColors( } ) + /** + * Returns a [State] holding the background brush appropriate for the given [state] and focus status. + * + * @param state The current [SegmentedControlButtonState]. + * @param isFocused Whether the button (via its containing segmented control) currently has focus, which further + * differentiates the selected appearance. + */ @Composable public fun backgroundFor(state: SegmentedControlButtonState, isFocused: Boolean): State = rememberUpdatedState( @@ -83,6 +111,13 @@ public class SegmentedControlButtonColors( } ) + /** + * Returns a [State] holding the border brush appropriate for the given [state] and focus status. + * + * @param state The current [SegmentedControlButtonState]. + * @param isFocused Whether the button (via its containing segmented control) currently has focus, which further + * differentiates the selected border appearance. + */ @Composable public fun borderFor(state: SegmentedControlButtonState, isFocused: Boolean): State = rememberUpdatedState( @@ -146,15 +181,21 @@ public class SegmentedControlButtonColors( ")" } + /** Companion object for [SegmentedControlButtonColors]. */ public companion object } +/** Holds size and spacing metrics for a segmented control button. */ @Stable @GenerateDataFunctions public class SegmentedControlButtonMetrics( + /** The corner radius of the segmented control button. */ public val cornerSize: CornerSize, + /** The inner padding of the segmented control button. */ public val segmentedButtonPadding: PaddingValues, + /** The minimum size of the segmented control button. */ public val minSize: DpSize, + /** The width of the button border. */ public val borderWidth: Dp, ) { override fun equals(other: Any?): Boolean { @@ -188,6 +229,7 @@ public class SegmentedControlButtonMetrics( ")" } + /** Companion object for [SegmentedControlButtonMetrics]. */ public companion object } @@ -207,6 +249,7 @@ private fun SegmentedControlButtonState.chooseValueIgnoreCompat( else -> normal } +/** CompositionLocal providing the current [SegmentedControlButtonStyle]. */ public val LocalSegmentedControlButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalSegmentedControlButtonStyle provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlStyling.kt index 401fbebd9156..0186199819a4 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SegmentedControlStyling.kt @@ -13,24 +13,35 @@ import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.SegmentedControlState +/** Combines the [colors] and [metrics] that style a segmented control component. */ public class SegmentedControlStyle( + /** The color tokens for the segmented control. */ public val colors: SegmentedControlColors, + /** The size and spacing metrics for the segmented control. */ public val metrics: SegmentedControlMetrics, ) { + /** Companion object for [SegmentedControlStyle]. */ public companion object } +/** Holds color tokens for a segmented control component in its various states. */ @Immutable @GenerateDataFunctions public class SegmentedControlColors( + /** The border color in the normal state. */ public val border: Brush, + /** The border color when the control is disabled. */ public val borderDisabled: Brush, + /** The border color when the control is pressed. */ public val borderPressed: Brush, + /** The border color when the control is hovered. */ public val borderHovered: Brush, + /** The border color when the control is focused. */ public val borderFocused: Brush, ) { + /** Returns a [State] holding the border brush appropriate for the given [state]. */ @Composable public fun borderFor(state: SegmentedControlState): State = rememberUpdatedState( @@ -81,12 +92,19 @@ public class SegmentedControlColors( ")" } + /** Companion object for [SegmentedControlColors]. */ public companion object } +/** Holds size and spacing metrics for a segmented control component. */ @Stable @GenerateDataFunctions -public class SegmentedControlMetrics(public val cornerSize: CornerSize, public val borderWidth: Dp) { +public class SegmentedControlMetrics( + /** The corner radius of the segmented control. */ + public val cornerSize: CornerSize, + /** The width of the control border. */ + public val borderWidth: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -107,6 +125,7 @@ public class SegmentedControlMetrics(public val cornerSize: CornerSize, public v override fun toString(): String = "SegmentedControlMetrics(cornerSize=$cornerSize, borderWidth=$borderWidth)" + /** Companion object for [SegmentedControlMetrics]. */ public companion object } @@ -126,6 +145,7 @@ private fun SegmentedControlState.chooseValueIgnoreCompat( else -> normal } +/** CompositionLocal that provides the current [SegmentedControlStyle] to segmented control composables. */ public val LocalSegmentedControlStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalSegmentedControlStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SelectableLazyColumnStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SelectableLazyColumnStyle.kt index ad67325a0c08..66b5bc348b9d 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SelectableLazyColumnStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SelectableLazyColumnStyle.kt @@ -5,8 +5,17 @@ import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines item height and [SimpleListItemStyle] metrics for a selectable lazy column. */ @GenerateDataFunctions -public class SelectableLazyColumnStyle(public val itemHeight: Dp, public val simpleListItemStyle: SimpleListItemStyle) { +public class SelectableLazyColumnStyle( + /** + * The intended height for list items. Note: currently stored on the style but not applied to items by the + * SelectableLazyColumn component. + */ + public val itemHeight: Dp, + /** The style applied to each simple list item. */ + public val simpleListItemStyle: SimpleListItemStyle, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -32,9 +41,11 @@ public class SelectableLazyColumnStyle(public val itemHeight: Dp, public val sim ")" } + /** Companion object for [SelectableLazyColumnStyle]. */ public companion object } +/** CompositionLocal providing the [SelectableLazyColumnStyle] for the current theme. */ public val LocalSelectableLazyColumnStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalSelectableLazyColumnStyle provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SimpleListItemStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SimpleListItemStyle.kt index 3a287808603e..c87876538db0 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SimpleListItemStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SimpleListItemStyle.kt @@ -13,8 +13,14 @@ import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.ListItemState +/** Combines [SimpleListItemColors] and [SimpleListItemMetrics] to style a simple list item. */ @GenerateDataFunctions -public class SimpleListItemStyle(public val colors: SimpleListItemColors, public val metrics: SimpleListItemMetrics) { +public class SimpleListItemStyle( + /** The color tokens for this list item. */ + public val colors: SimpleListItemColors, + /** The size and spacing metrics for this list item. */ + public val metrics: SimpleListItemMetrics, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -35,21 +41,37 @@ public class SimpleListItemStyle(public val colors: SimpleListItemColors, public override fun toString(): String = "SimpleListItemStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [SimpleListItemStyle]. */ public companion object } +/** Holds color tokens for a simple list item in its various selection and activation states. */ @Stable @GenerateDataFunctions public class SimpleListItemColors( + /** The default background color. */ public val background: Color, + /** The background color when the item is active (focused container). */ public val backgroundActive: Color, + /** The background color when the item is selected. */ public val backgroundSelected: Color, + /** The background color when the item is both selected and active. */ public val backgroundSelectedActive: Color, + /** The default content (text/icon) color. */ public val content: Color, + /** The content color when the item is active. */ public val contentActive: Color, + /** The content color when the item is selected. */ public val contentSelected: Color, + /** The content color when the item is both selected and active. */ public val contentSelectedActive: Color, ) { + /** + * Returns a [State] holding the content color appropriate for the given [state]: selected-active, selected, active, + * or default. + * + * @param state The current [ListItemState] of the item. + */ @Composable public fun contentFor(state: ListItemState): State = rememberUpdatedState( @@ -61,6 +83,12 @@ public class SimpleListItemColors( } ) + /** + * Returns a [State] holding the background color appropriate for the given [state]: selected-active, selected, + * active, or default. + * + * @param state The current [ListItemState] of the item. + */ @Composable public fun backgroundFor(state: ListItemState): State = rememberUpdatedState( @@ -115,15 +143,21 @@ public class SimpleListItemColors( ")" } + /** Companion object for [SimpleListItemColors]. */ public companion object } +/** Holds size and spacing metrics for a simple list item, including padding, corner size, and icon-text gap. */ @Stable @GenerateDataFunctions public class SimpleListItemMetrics( + /** The padding applied inside the item content area. */ public val innerPadding: PaddingValues, + /** The padding applied outside the item, around the selection background. */ public val outerPadding: PaddingValues, + /** The corner size of the selection background shape. */ public val selectionBackgroundCornerSize: CornerSize, + /** The gap between an icon and its accompanying text. */ public val iconTextGap: Dp, ) { override fun equals(other: Any?): Boolean { @@ -157,9 +191,11 @@ public class SimpleListItemMetrics( ")" } + /** Companion object for [SimpleListItemMetrics]. */ public companion object } +/** CompositionLocal providing the [SimpleListItemStyle] for the current theme. */ public val LocalSimpleListItemStyleStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalSimpleListItemStyleStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SliderStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SliderStyling.kt index 1d6318f384f9..cdee0031f579 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SliderStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SliderStyling.kt @@ -15,11 +15,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.component.SliderState +/** Combines the [colors], [metrics], and [thumbShape] that define the appearance of a Slider component. */ @Stable @GenerateDataFunctions public class SliderStyle( + /** The color tokens for the slider. */ public val colors: SliderColors, + /** The size and spacing metrics for the slider. */ public val metrics: SliderMetrics, + /** The shape used for the thumb. */ public val thumbShape: Shape, ) { override fun equals(other: Any?): Boolean { @@ -44,28 +48,50 @@ public class SliderStyle( override fun toString(): String = "SliderStyle(colors=$colors, metrics=$metrics, thumbShape=$thumbShape)" + /** Companion object for [SliderStyle]. */ public companion object } +/** Holds color tokens for the Slider component's track, step markers, and thumb in all states. */ @Immutable @GenerateDataFunctions public class SliderColors( + /** The track color when enabled. */ public val track: Color, + /** The filled portion of the track color when enabled. */ public val trackFilled: Color, + /** The track color when disabled. */ public val trackDisabled: Color, + /** The filled portion of the track color when disabled. */ public val trackFilledDisabled: Color, + /** The color of the step marker indicators. */ public val stepMarker: Color, + /** The thumb fill color in the normal state. */ public val thumbFill: Color, + /** The thumb fill color when disabled. */ public val thumbFillDisabled: Color, + /** The thumb fill color when focused. */ public val thumbFillFocused: Color, + /** The thumb fill color when pressed. */ public val thumbFillPressed: Color, + /** The thumb fill color when hovered. */ public val thumbFillHovered: Color, + /** The thumb border color in the normal state. */ public val thumbBorder: Color, + /** The thumb border color when focused. */ public val thumbBorderFocused: Color, + /** The thumb border color when disabled. */ public val thumbBorderDisabled: Color, + /** The thumb border color when pressed. */ public val thumbBorderPressed: Color, + /** The thumb border color when hovered. */ public val thumbBorderHovered: Color, ) { + /** + * Returns a [State] holding the thumb fill color appropriate for the given [state]. + * + * @param state The current [SliderState]. + */ @Composable public fun thumbFillFor(state: SliderState): State = rememberUpdatedState( @@ -78,6 +104,11 @@ public class SliderColors( ) ) + /** + * Returns a [State] holding the thumb border color appropriate for the given [state]. + * + * @param state The current [SliderState]. + */ @Composable public fun thumbBorderFor(state: SliderState): State = rememberUpdatedState( @@ -170,17 +201,25 @@ public class SliderColors( ")" } + /** Companion object for [SliderColors]. */ public companion object } +/** Holds size and spacing metrics for the Slider component's track, thumb, and step line indicators. */ @Immutable @GenerateDataFunctions public class SliderMetrics( + /** The height of the track. */ public val trackHeight: Dp, + /** The size of the thumb. */ public val thumbSize: DpSize, + /** The width of the thumb border. */ public val thumbBorderWidth: Dp, + /** The height of the step line indicators. */ public val stepLineHeight: Dp, + /** The width of the step line indicators. */ public val stepLineWidth: Dp, + /** The spacing between the track and the step line indicators. */ public val trackToStepSpacing: Dp, ) { override fun equals(other: Any?): Boolean { @@ -220,9 +259,11 @@ public class SliderMetrics( ")" } + /** Companion object for [SliderMetrics]. */ public companion object } +/** CompositionLocal providing the [SliderStyle] for the current theme. */ public val LocalSliderStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No default SliderStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SpeedSearchStyle.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SpeedSearchStyle.kt index 8f2f021bbe57..17cf413778bf 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SpeedSearchStyle.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SpeedSearchStyle.kt @@ -11,11 +11,15 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.icons.AllIconsKeys +/** Combines [SpeedSearchColors], [SpeedSearchMetrics], and [SpeedSearchIcons] to style the SpeedSearch component. */ @Immutable @GenerateDataFunctions public class SpeedSearchStyle( + /** The color tokens for the SpeedSearch component. */ public val colors: SpeedSearchColors, + /** The size and spacing metrics for the SpeedSearch component. */ public val metrics: SpeedSearchMetrics, + /** The icon keys for the SpeedSearch component. */ public val icons: SpeedSearchIcons, ) { override fun equals(other: Any?): Boolean { @@ -40,15 +44,21 @@ public class SpeedSearchStyle( override fun toString(): String = "SpeedSearchStyle(colors=$colors, metrics=$metrics, icons=$icons)" + /** Companion object for [SpeedSearchStyle]. */ public companion object } +/** Holds color tokens for the SpeedSearch component in its various states. */ @Immutable @GenerateDataFunctions public class SpeedSearchColors( + /** The background color. */ public val background: Color, + /** The border color. */ public val border: Color, + /** The foreground (text) color. */ public val foreground: Color, + /** The color used to indicate an error state. */ public val error: Color, ) { override fun equals(other: Any?): Boolean { @@ -76,12 +86,17 @@ public class SpeedSearchColors( override fun toString(): String = "SpeedSearchColors(background=$background, border=$border, foreground=$foreground, error=$error)" + /** Companion object for [SpeedSearchColors]. */ public companion object } +/** Holds size and spacing metrics for the SpeedSearch component. */ @Immutable @GenerateDataFunctions -public class SpeedSearchMetrics(public val contentPadding: PaddingValues) { +public class SpeedSearchMetrics( + /** The padding around the content inside the SpeedSearch popup. */ + public val contentPadding: PaddingValues +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -95,12 +110,17 @@ public class SpeedSearchMetrics(public val contentPadding: PaddingValues) { override fun toString(): String = "SpeedSearchMetrics(contentPadding=$contentPadding)" + /** Companion object for [SpeedSearchMetrics]. */ public companion object } +/** Holds icon keys for the SpeedSearch component. */ @Immutable @GenerateDataFunctions -public class SpeedSearchIcons(public val magnifyingGlass: IconKey) { +public class SpeedSearchIcons( + /** The icon key for the magnifying glass search icon. */ + public val magnifyingGlass: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -114,9 +134,11 @@ public class SpeedSearchIcons(public val magnifyingGlass: IconKey) { override fun toString(): String = "SpeedSearchIcons(magnifyingGlass=$magnifyingGlass)" + /** Companion object for [SpeedSearchIcons]. */ public companion object } +/** Composition local that provides the current [SpeedSearchStyle] to the SpeedSearch component. */ public val LocalSpeedSearchStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No default SpeedSearchStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SplitButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SplitButtonStyling.kt index 318e82aa7a07..42a24d53f354 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SplitButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/SplitButtonStyling.kt @@ -8,11 +8,15 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines [ButtonStyle], [SplitButtonColors], and [SplitButtonMetrics] to style a split button component. */ @Stable @GenerateDataFunctions public class SplitButtonStyle( + /** The style applied to the underlying button portion of the split button. */ public val button: ButtonStyle, + /** The colors used for the split button divider and chevron. */ public val colors: SplitButtonColors, + /** The size and spacing metrics for the split button divider. */ public val metrics: SplitButtonMetrics, ) { override fun equals(other: Any?): Boolean { @@ -37,14 +41,19 @@ public class SplitButtonStyle( override fun toString(): String = "SplitButtonStyle(button=$button, colors=$colors, metrics=$metrics)" + /** Companion object for [SplitButtonStyle]. */ public companion object } +/** Holds color tokens for the split button divider and chevron in their various states. */ @Immutable @GenerateDataFunctions public class SplitButtonColors( + /** The color of the divider between the button and the chevron. */ public val dividerColor: Color, + /** The color of the divider when the split button is disabled. */ public val dividerDisabledColor: Color, + /** The color of the chevron icon. */ public val chevronColor: Color, ) { override fun equals(other: Any?): Boolean { @@ -75,12 +84,19 @@ public class SplitButtonColors( ")" } + /** Companion object for [SplitButtonColors]. */ public companion object } +/** Holds size and spacing metrics for the split button divider. */ @Stable @GenerateDataFunctions -public class SplitButtonMetrics(public val dividerMetrics: DividerMetrics, public val dividerPadding: Dp) { +public class SplitButtonMetrics( + /** The size and thickness metrics for the divider. */ + public val dividerMetrics: DividerMetrics, + /** The padding applied around the divider. */ + public val dividerPadding: Dp, +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -102,13 +118,16 @@ public class SplitButtonMetrics(public val dividerMetrics: DividerMetrics, publi override fun toString(): String = "SplitButtonMetrics(dividerMetrics=$dividerMetrics, dividerPadding=$dividerPadding)" + /** Companion object for [SplitButtonMetrics]. */ public companion object } +/** CompositionLocal providing the default [SplitButtonStyle] for split buttons. */ public val LocalDefaultSplitButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No default SplitButtonStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the outlined [SplitButtonStyle] for split buttons. */ public val LocalOutlinedSplitButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No outlined SplitButtonStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TabStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TabStyling.kt index ffb56f3418a4..60e46a158edd 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TabStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TabStyling.kt @@ -14,13 +14,19 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.TabState import org.jetbrains.jewel.ui.icon.IconKey +/** Combines colors, metrics, icons, content alpha, and scrollbar style for a tab component. */ @Stable @GenerateDataFunctions public class TabStyle( + /** The color tokens for the tab component. */ public val colors: TabColors, + /** The size and spacing metrics for the tab component. */ public val metrics: TabMetrics, + /** The icon keys for the tab component. */ public val icons: TabIcons, + /** The content alpha values for the tab component. */ public val contentAlpha: TabContentAlpha, + /** The scrollbar style used within the tab strip. */ public val scrollbarStyle: ScrollbarStyle, ) { override fun equals(other: Any?): Boolean { @@ -57,16 +63,23 @@ public class TabStyle( ")" } + /** Companion object for [TabStyle]. */ public companion object } +/** Holds size and spacing metrics for the tab component. */ @Stable @GenerateDataFunctions public class TabMetrics( + /** The thickness of the selected tab's underline indicator. */ public val underlineThickness: Dp, + /** The padding applied inside each tab. */ public val tabPadding: PaddingValues, + /** The height of a tab. */ public val tabHeight: Dp, + /** The spacing between elements inside a tab's content area. */ public val tabContentSpacing: Dp, + /** The gap between the close button and the tab content. */ public val closeContentGap: Dp, ) { override fun equals(other: Any?): Boolean { @@ -103,12 +116,17 @@ public class TabMetrics( ")" } + /** Companion object for [TabMetrics]. */ public companion object } +/** Holds the icon key for the tab component's close button. */ @Immutable @GenerateDataFunctions -public class TabIcons(public val close: IconKey) { +public class TabIcons( + /** The icon key for the tab's close button. */ + public val close: IconKey +) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -122,28 +140,52 @@ public class TabIcons(public val close: IconKey) { override fun toString(): String = "TabIcons(close=$close)" + /** Companion object for [TabIcons]. */ public companion object } +/** + * Holds color tokens for the tab component in its various states, including background, content, and underline colors. + */ @Immutable @GenerateDataFunctions public class TabColors( + /** The background color in the normal state. */ public val background: Color, + /** The background color when the tab is disabled. */ public val backgroundDisabled: Color, + /** The background color when the tab is pressed. */ public val backgroundPressed: Color, + /** The background color when the tab is hovered. */ public val backgroundHovered: Color, + /** The background color when the tab is selected. */ public val backgroundSelected: Color, + /** The content (text/icon) color in the normal state. */ public val content: Color, + /** The content color when the tab is disabled. */ public val contentDisabled: Color, + /** The content color when the tab is pressed. */ public val contentPressed: Color, + /** The content color when the tab is hovered. */ public val contentHovered: Color, + /** The content color when the tab is selected. */ public val contentSelected: Color, + /** The underline indicator color in the normal state. */ public val underline: Color, + /** The underline indicator color when the tab is disabled. */ public val underlineDisabled: Color, + /** The underline indicator color when the tab is pressed. */ public val underlinePressed: Color, + /** The underline indicator color when the tab is hovered. */ public val underlineHovered: Color, + /** The underline indicator color when the tab is selected. */ public val underlineSelected: Color, ) { + /** + * Returns a [State] holding the content color appropriate for the given [state]. + * + * @param state The current [TabState]. + */ @Composable public fun contentFor(state: TabState): State = rememberUpdatedState( @@ -160,6 +202,11 @@ public class TabColors( } ) + /** + * Returns a [State] holding the background color appropriate for the given [state]. + * + * @param state The current [TabState]. + */ @Composable public fun backgroundFor(state: TabState): State = rememberUpdatedState( @@ -173,6 +220,11 @@ public class TabColors( } ) + /** + * Returns a [State] holding the underline color appropriate for the given [state]. + * + * @param state The current [TabState]. + */ @Composable public fun underlineFor(state: TabState): State = rememberUpdatedState( @@ -253,23 +305,40 @@ public class TabColors( ")" } + /** Companion object for [TabColors]. */ public companion object } +/** Holds alpha values for icon and content in the tab component across its various states. */ @Immutable @GenerateDataFunctions public class TabContentAlpha( + /** The icon opacity in the normal state. */ public val iconNormal: Float, + /** The icon opacity when the tab is disabled. */ public val iconDisabled: Float, + /** The icon opacity when the tab is pressed. */ public val iconPressed: Float, + /** The icon opacity when the tab is hovered. */ public val iconHovered: Float, + /** The icon opacity when the tab is selected. */ public val iconSelected: Float, + /** The content opacity in the normal state. */ public val contentNormal: Float, + /** The content opacity when the tab is disabled. */ public val contentDisabled: Float, + /** The content opacity when the tab is pressed. */ public val contentPressed: Float, + /** The content opacity when the tab is hovered. */ public val contentHovered: Float, + /** The content opacity when the tab is selected. */ public val contentSelected: Float, ) { + /** + * Returns a [State] holding the icon opacity appropriate for the given [state]. + * + * @param state The current [TabState]. + */ @Composable public fun iconFor(state: TabState): State = rememberUpdatedState( @@ -286,6 +355,11 @@ public class TabContentAlpha( } ) + /** + * Returns a [State] holding the content opacity appropriate for the given [state]. + * + * @param state The current [TabState]. + */ @Composable public fun contentFor(state: TabState): State = rememberUpdatedState( @@ -351,6 +425,7 @@ public class TabContentAlpha( ")" } + /** Companion object for [TabContentAlpha]. */ public companion object } @@ -365,10 +440,12 @@ private fun TabState.chooseValueIgnoreCompat(normal: T, disabled: T, pressed else -> normal } +/** CompositionLocal providing the default [TabStyle] for non-editor tabs. */ public val LocalDefaultTabStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalDefaultTabStyle provided. Have you forgotten the theme?") } +/** CompositionLocal providing the [TabStyle] for editor tabs. */ public val LocalEditorTabStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalEditorTabStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextAreaStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextAreaStyling.kt index 22ef4087aadb..77f8b68942bb 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextAreaStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextAreaStyling.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines [TextAreaColors] and [TextAreaMetrics] to fully style a text area component. */ @Stable @GenerateDataFunctions public class TextAreaStyle(override val colors: TextAreaColors, override val metrics: TextAreaMetrics) : @@ -35,9 +36,14 @@ public class TextAreaStyle(override val colors: TextAreaColors, override val met override fun toString(): String = "TextAreaStyle(colors=$colors, metrics=$metrics)" + /** Companion object for [TextAreaStyle]. */ public companion object } +/** + * Holds color tokens for the text area component in its various states, including background, content, border, caret, + * and placeholder colors. + */ @Immutable @GenerateDataFunctions public class TextAreaColors( @@ -61,6 +67,7 @@ public class TextAreaColors( override val caretFocused: Color, override val caretPressed: Color, override val caretHovered: Color, + /** The color used for placeholder text when the text area is empty. */ public val placeholder: Color, ) : InputFieldColors { override fun equals(other: Any?): Boolean { @@ -145,9 +152,14 @@ public class TextAreaColors( ")" } + /** Companion object for [TextAreaColors]. */ public companion object } +/** + * Holds size and spacing metrics for the text area component, including border width, content padding, corner size, and + * minimum size. + */ @Stable @GenerateDataFunctions public class TextAreaMetrics( @@ -187,9 +199,11 @@ public class TextAreaMetrics( ")" } + /** Companion object for [TextAreaMetrics]. */ public companion object } +/** CompositionLocal used to provide the current [TextAreaStyle] down the composition tree. */ public val LocalTextAreaStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No TextAreaStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextFieldStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextFieldStyling.kt index 8971ffd4fe9f..d808c352d2dc 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextFieldStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TextFieldStyling.kt @@ -11,11 +11,18 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Combines colors, metrics, and an [IconButtonStyle] for styling a text field component. */ @Stable @GenerateDataFunctions public class TextFieldStyle( + /** The color tokens for the text field. */ override val colors: TextFieldColors, + /** The size and spacing metrics for the text field. */ override val metrics: TextFieldMetrics, + /** + * The [IconButtonStyle] to use for icon buttons that callers place in the text field's leading or trailing icon + * slots. Not applied automatically. + */ public val iconButtonStyle: IconButtonStyle, ) : InputFieldStyle { override fun equals(other: Any?): Boolean { @@ -41,32 +48,55 @@ public class TextFieldStyle( override fun toString(): String = "TextFieldStyle(colors=$colors, metrics=$metrics, iconButtonStyle=$iconButtonStyle)" + /** Companion object for [TextFieldStyle]. */ public companion object } +/** Holds color tokens for the text field component in its various interaction and focus states. */ @Immutable @GenerateDataFunctions public class TextFieldColors( + /** The background color in the default state. */ override val background: Color, + /** The background color in the disabled state. */ override val backgroundDisabled: Color, + /** The background color in the focused state. */ override val backgroundFocused: Color, + /** The background color in the pressed state. */ override val backgroundPressed: Color, + /** The background color in the hovered state. */ override val backgroundHovered: Color, + /** The text content color in the default state. */ override val content: Color, + /** The text content color in the disabled state. */ override val contentDisabled: Color, + /** The text content color in the focused state. */ override val contentFocused: Color, + /** The text content color in the pressed state. */ override val contentPressed: Color, + /** The text content color in the hovered state. */ override val contentHovered: Color, + /** The border color in the default state. */ override val border: Color, + /** The border color in the disabled state. */ override val borderDisabled: Color, + /** The border color in the focused state. */ override val borderFocused: Color, + /** The border color in the pressed state. */ override val borderPressed: Color, + /** The border color in the hovered state. */ override val borderHovered: Color, + /** The caret color in the default state. */ override val caret: Color, + /** The caret color in the disabled state. */ override val caretDisabled: Color, + /** The caret color in the focused state. */ override val caretFocused: Color, + /** The caret color in the pressed state. */ override val caretPressed: Color, + /** The caret color in the hovered state. */ override val caretHovered: Color, + /** The color of the placeholder text shown when the field is empty. */ public val placeholder: Color, ) : InputFieldColors { override fun equals(other: Any?): Boolean { @@ -151,15 +181,24 @@ public class TextFieldColors( ")" } + /** Companion object for [TextFieldColors]. */ public companion object } +/** + * Holds size and spacing metrics for the text field component, including border width, padding, corner size, and + * minimum size. + */ @Stable @GenerateDataFunctions public class TextFieldMetrics( + /** The width of the border stroke. */ override val borderWidth: Dp, + /** The padding applied around the text content inside the field. */ override val contentPadding: PaddingValues, + /** The corner radius of the text field. */ override val cornerSize: CornerSize, + /** The minimum size of the text field. */ override val minSize: DpSize, ) : InputFieldMetrics { override fun equals(other: Any?): Boolean { @@ -193,9 +232,11 @@ public class TextFieldMetrics( ")" } + /** Companion object for [TextFieldMetrics]. */ public companion object } +/** CompositionLocal used to provide the current [TextFieldStyle] down the composition tree. */ public val LocalTextFieldStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No TextFieldStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TooltipStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TooltipStyling.kt index 2cd9bbad1a78..cb3535d76ad4 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TooltipStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/TooltipStyling.kt @@ -17,11 +17,15 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi import org.jetbrains.jewel.foundation.GenerateDataFunctions import org.jetbrains.jewel.ui.component.FixedCursorPoint +/** Combines [TooltipColors] and [TooltipMetrics] to fully style a tooltip component. */ @Stable @GenerateDataFunctions public class TooltipStyle( + /** The color tokens for the tooltip. */ public val colors: TooltipColors, + /** The size and spacing metrics for the tooltip. */ public val metrics: TooltipMetrics, + /** Controls how long the tooltip remains visible before automatically hiding. */ public val autoHideBehavior: TooltipAutoHideBehavior, ) { public constructor( @@ -52,15 +56,21 @@ public class TooltipStyle( override fun toString(): String = "TooltipStyle(colors=$colors, metrics=$metrics, autoHideBehavior=$autoHideBehavior)" + /** Companion object for [TooltipStyle]. */ public companion object } +/** Holds color tokens for a tooltip component, covering background, content, border, and shadow. */ @Stable @GenerateDataFunctions public class TooltipColors( + /** The background color of the tooltip. */ public val background: Color, + /** The content (text) color of the tooltip. */ public val content: Color, + /** The border color of the tooltip. */ public val border: Color, + /** The shadow color of the tooltip. */ public val shadow: Color, ) { override fun equals(other: Any?): Boolean { @@ -94,19 +104,32 @@ public class TooltipColors( ")" } + /** Companion object for [TooltipColors]. */ public companion object } +/** + * Holds size and spacing metrics for a tooltip component, including padding, delays, corner size, border, shadow, and + * placement. + */ @Stable @GenerateDataFunctions public class TooltipMetrics( + /** The inner padding applied to the tooltip content. */ public val contentPadding: PaddingValues, + /** The delay before the tooltip appears after the cursor hovers over the target. */ public val showDelay: Duration, + /** The corner radius of the tooltip shape. */ public val cornerSize: CornerSize, + /** The width of the tooltip border. */ public val borderWidth: Dp, + /** The size of the drop shadow around the tooltip. */ public val shadowSize: Dp, + /** The placement policy for positioning the tooltip relative to the cursor. */ public val placement: TooltipPlacement, + /** The delay after which a regular tooltip automatically disappears. */ public val regularDisappearDelay: Duration, + /** The delay after which a full (rich) tooltip automatically disappears. */ public val fullDisappearDelay: Duration, ) { @Deprecated("Use the constructor with regularDisappearDelay and fullDisappearDelay parameters.") @@ -173,6 +196,7 @@ public class TooltipMetrics( ")" } + /** Companion object for [TooltipMetrics]. */ public companion object { @Deprecated("Use the version with `regularDisappearDelay` and `fullDisappearDelay` parameters.") public fun defaults( @@ -194,6 +218,18 @@ public class TooltipMetrics( 30000.milliseconds, ) + /** + * Creates default [TooltipMetrics] with standard Int UI values and configurable disappear delays. + * + * @param contentPadding Inner padding of the tooltip content. + * @param showDelay Delay before the tooltip appears after the cursor hovers. + * @param regularDisappearDelay Delay after which a regular tooltip disappears automatically. + * @param fullDisappearDelay Delay after which a full (rich) tooltip disappears automatically. + * @param cornerSize Corner radius of the tooltip shape. + * @param borderWidth Width of the tooltip border. + * @param shadowSize Size of the drop shadow. + * @param placement Policy for positioning the tooltip relative to the cursor. + */ public fun defaults( contentPadding: PaddingValues = PaddingValues(vertical = 9.dp, horizontal = 12.dp), showDelay: Duration = 500.milliseconds, // ide.tooltip.initialReshowDelay @@ -217,12 +253,17 @@ public class TooltipMetrics( } } +/** Controls how long a tooltip remains visible before automatically hiding. */ public enum class TooltipAutoHideBehavior { + /** The tooltip never hides automatically. */ Never, + /** The tooltip hides after the regular disappear delay. */ Normal, + /** The tooltip hides after the full (longer) disappear delay. */ Long, } +/** CompositionLocal that provides the current [TooltipStyle] for tooltip components. */ public val LocalTooltipStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No TooltipStyle provided. Have you forgotten the theme?") } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeImageResourceProvider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeImageResourceProvider.kt index 5d1d882509bd..8c8834cdaabd 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeImageResourceProvider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeImageResourceProvider.kt @@ -22,6 +22,7 @@ import org.jetbrains.jewel.foundation.InternalJewelApi import org.jetbrains.jewel.ui.painter.writeToString import org.w3c.dom.Element +/** An [ImageResourceProvider] that loads SVG and bitmap images using Compose painter and bitmap APIs. */ @InternalJewelApi @ApiStatus.Internal public class ComposeImageResourceProvider : ImageResourceProvider { diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeLayerPaintingContext.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeLayerPaintingContext.kt index aa203820d6f6..e8c9917ba973 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeLayerPaintingContext.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/ComposeLayerPaintingContext.kt @@ -25,16 +25,29 @@ import com.intellij.platform.icons.scale.fitArea import org.jetbrains.annotations.ApiStatus import org.jetbrains.jewel.foundation.InternalJewelApi +/** A [LayerPaintingContext] implementation that delegates drawing operations to a Compose [DrawScope]. */ @InternalJewelApi @ApiStatus.Internal public class ComposeLayerPaintingContext( + /** The Compose [DrawScope] to which drawing operations are delegated. */ public val drawScope: DrawScope, + /** + * The horizontal offset in pixels of this layer. Used only as the fallback x position when creating a nested layer + * via [createNestedLayer]; it is not added to the coordinates of drawing operations in this context. + */ public override val offsetX: Int = 0, + /** + * The layer's vertical offset in pixels. Used only as the fallback y position for a nested layer created via + * [createNestedLayer]; it is not added to the coordinates of this context's own drawing operations. + */ public override val offsetY: Int = 0, + /** The width of the slot in pixels, or null if unconstrained. */ override val slotWidth: Int? = null, + /** The height of the slot in pixels, or null if unconstrained. */ override val slotHeight: Int? = null, private val overrideColorFilter: ColorFilter? = null, override val alpha: Float = 1f, + /** The scaling context used to resolve display density and context scale. */ override val scaling: ScalingContext = DefaultScalingContext(drawScope.drawContext.density.density, 1f), ) : LayerPaintingContext { override fun createNestedLayer( diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconKey.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconKey.kt index f34e4fd5602d..911d82850ab0 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconKey.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconKey.kt @@ -4,16 +4,26 @@ import com.intellij.platform.icons.design.IconDesigner import com.intellij.platform.icons.modifiers.IconModifier import org.jetbrains.jewel.foundation.GenerateDataFunctions +/** Represents a key that resolves to an icon path, associated with a class loader. */ public interface IconKey { + /** The class used to locate the icon resource on the classpath. */ public val iconClass: Class<*> + /** Returns the classpath-relative resource path for this icon, selecting the New UI or Classic UI variant. */ public fun path(isNewUi: Boolean): String } +/** + * Renders the icon described by [iconKey] in this [IconDesigner], using the New UI path and applying [modifier]. + * + * @param iconKey The [IconKey] identifying the icon resource. + * @param modifier The [IconModifier] to apply to the icon. Defaults to the identity modifier. + */ public fun IconDesigner.iconKey(iconKey: IconKey, modifier: IconModifier = IconModifier) { image(iconKey.path(isNewUi = true), iconKey.iconClass.classLoader, modifier) } +/** An [IconKey] that resolves to a single fixed icon [path], regardless of the UI mode. */ @GenerateDataFunctions public class PathIconKey(private val path: String, override val iconClass: Class<*>) : IconKey { override fun path(isNewUi: Boolean): String = path @@ -39,10 +49,14 @@ public class PathIconKey(private val path: String, override val iconClass: Class override fun toString(): String = "PathIconKey(path='$path', iconClass=$iconClass)" } +/** An [IconKey] that resolves to different icon paths for the old and new IntelliJ UI. */ @GenerateDataFunctions public class IntelliJIconKey( + /** The classpath-relative resource path used when the Classic UI is active. */ public val oldUiPath: String, + /** The classpath-relative resource path used when the New UI is active. */ public val newUiPath: String, + /** The class used to locate the icon resource on the classpath. */ override val iconClass: Class<*>, ) : IconKey { override fun path(isNewUi: Boolean): String = if (isNewUi) newUiPath else oldUiPath @@ -75,5 +89,6 @@ public class IntelliJIconKey( ")" } + /** Companion object for [IntelliJIconKey]. */ public companion object } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconUtils.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconUtils.kt index a574d165f453..f5fb05d4b4b7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconUtils.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/IconUtils.kt @@ -30,31 +30,53 @@ import org.jetbrains.jewel.foundation.ExperimentalJewelApi @ExperimentalJewelApi @ApiStatus.Experimental +/** + * Applies a tint of [composeColor] with [blendMode] to this [IconModifier], converting to the IntelliJ Platform Icons + * color and blend-mode types. + * + * @param composeColor The Compose [Color] to use as the tint. + * @param blendMode The [BlendMode] to use for blending. Defaults to [BlendMode.SrcIn]. + */ public fun IconModifier.tintColor(composeColor: Color, blendMode: BlendMode = BlendMode.SrcIn): IconModifier = tintColor(composeColor.toIconsColor(), blendMode.toIconsBlendMode()) +/** Creates a [Circle] shape with the given [radius] for use in the IntelliJ Platform icon DSL. */ @ExperimentalJewelApi @ApiStatus.Experimental public fun circle(radius: Dp): Circle = circle(radius.toIconsDp()) @ExperimentalJewelApi @ApiStatus.Experimental +/** Creates a [Rectangle] shape with the given dimensions for use in the IntelliJ Platform icon DSL. */ public fun rectangle(width: Dp, heigth: Dp): Rectangle = rectangle(width.toIconsDp(), heigth.toIconsDp()) @ExperimentalJewelApi @ApiStatus.Experimental +/** Creates a [FitAreaScale] that fits the icon within the given dimensions. */ public fun fitArea(width: Dp, heigth: Dp): FitAreaScale = fitArea(width.toIconsDp(), heigth.toIconsDp()) @ExperimentalJewelApi @ApiStatus.Experimental +/** Creates a [FillAreaScale] that fills the icon to the given dimensions. */ public fun fillArea(width: Dp, heigth: Dp): FillAreaScale = fillArea(width.toIconsDp(), heigth.toIconsDp()) +/** Converts this Compose [Dp] value to an IntelliJ Platform Icons [DisplayPoint]. */ @ExperimentalJewelApi @ApiStatus.Experimental public fun Dp.toIconsDp(): DisplayPoint = this.value.dp @ExperimentalJewelApi @ApiStatus.Experimental +/** Applies a stroke with the given Compose [composeColor] to this [IconModifier]. */ public fun IconModifier.stroke(composeColor: Color): IconModifier = stroke(composeColor.toIconsColor()) @ExperimentalJewelApi @ApiStatus.Experimental +/** + * Adds a badge to this icon using a Compose [color], with configurable [shape], [align], [cutout], and [modifier]. + * + * @param color The Compose color for the badge. + * @param shape The shape of the badge. Defaults to a small circle. + * @param align Where to position the badge. Defaults to [IconAlign.TopRight]. + * @param cutout The size of the cutout carved into the icon beneath the badge. + * @param modifier Additional icon modifier to apply to the badge. + */ public fun IconDesigner.badge( color: Color, shape: Shape = circle(2.8.dp), @@ -67,6 +89,9 @@ public fun IconDesigner.badge( @ExperimentalJewelApi @ApiStatus.Experimental +/** + * Converts this IntelliJ Platform [ColorFilter] to a Compose [ColorFilter][androidx.compose.ui.graphics.ColorFilter]. + */ public fun ColorFilter.toCompose(): androidx.compose.ui.graphics.ColorFilter = when (this) { is TintColorFilter -> androidx.compose.ui.graphics.ColorFilter.tint(color.toCompose(), blendMode.toCompose()) @@ -75,6 +100,7 @@ public fun ColorFilter.toCompose(): androidx.compose.ui.graphics.ColorFilter = @ExperimentalJewelApi @ApiStatus.Experimental +/** Converts this IntelliJ Platform Icons [Color][com.intellij.platform.icons.design.Color] to a Compose [Color]. */ public fun com.intellij.platform.icons.design.Color.toCompose(): Color = when (this) { is DefaultSRGB -> Color(red, green, blue, alpha) @@ -83,6 +109,10 @@ public fun com.intellij.platform.icons.design.Color.toCompose(): Color = @ExperimentalJewelApi @ApiStatus.Experimental +/** + * Converts this IntelliJ Platform Icons [BlendMode][com.intellij.platform.icons.design.BlendMode] to a Compose + * [BlendMode]. + */ public fun com.intellij.platform.icons.design.BlendMode.toCompose(): BlendMode = when (this) { com.intellij.platform.icons.design.BlendMode.SrcIn -> BlendMode.SrcIn @@ -95,6 +125,10 @@ public fun com.intellij.platform.icons.design.BlendMode.toCompose(): BlendMode = @ExperimentalJewelApi @ApiStatus.Experimental +/** + * Converts this Compose [BlendMode] to the equivalent IntelliJ Platform Icons + * [BlendMode][com.intellij.platform.icons.design.BlendMode]. + */ public fun BlendMode.toIconsBlendMode(): com.intellij.platform.icons.design.BlendMode = when (this) { BlendMode.SrcIn -> com.intellij.platform.icons.design.BlendMode.SrcIn @@ -108,4 +142,5 @@ public fun BlendMode.toIconsBlendMode(): com.intellij.platform.icons.design.Blen @ExperimentalJewelApi @ApiStatus.Experimental +/** Converts this Compose [Color] to an IntelliJ Platform Icons [Color][com.intellij.platform.icons.design.Color]. */ public fun Color.toIconsColor(): com.intellij.platform.icons.design.Color = DefaultSRGB(red, green, blue, alpha) diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/NewUiChecker.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/NewUiChecker.kt index c260d05b3a86..c5388f609dcd 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/NewUiChecker.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/icon/NewUiChecker.kt @@ -5,13 +5,17 @@ import androidx.compose.runtime.ProvidableCompositionLocal import androidx.compose.runtime.staticCompositionLocalOf import org.jetbrains.jewel.foundation.theme.JewelTheme +/** Functional interface that determines whether the IDE is running with the New UI enabled. */ public fun interface NewUiChecker { + /** Returns `true` if the IDE is currently using the New UI. */ public fun isNewUi(): Boolean } +/** CompositionLocal that provides the current [NewUiChecker] instance. */ public val LocalNewUiChecker: ProvidableCompositionLocal = staticCompositionLocalOf { error("No NewUiChecker provided") } +/** The [NewUiChecker] for the current [JewelTheme]. */ public val JewelTheme.Companion.newUiChecker: NewUiChecker @Composable get() = LocalNewUiChecker.current diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHint.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHint.kt index 12541b0c7a41..550a0a3ad5fd 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHint.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHint.kt @@ -19,6 +19,7 @@ import org.w3c.dom.Element */ @Immutable public sealed interface PainterHint { + /** Returns `true` if this hint should be applied for the resource at the current [PainterProviderScope.path]. */ public fun PainterProviderScope.canApply(): Boolean = true /** An empty [PainterHint], it will be ignored. */ @@ -72,8 +73,10 @@ public interface PainterSvgPatchHint : SvgPainterHint { public fun PainterProviderScope.patch(element: Element) } +/** A [PainterHint] that wraps the loaded [Painter] with another [Painter], allowing post-load decoration. */ @Immutable public interface PainterWrapperHint : PainterHint { + /** Wraps the loaded [painter] with another [Painter], returning the decorated result. */ public fun PainterProviderScope.wrap(painter: Painter): Painter } @@ -93,6 +96,7 @@ public abstract class PainterPrefixHint : PainterPathHint { append(path.substringAfterLast('.')) } + /** Returns the prefix string to prepend to the file name portion of the resource path. */ public abstract fun PainterProviderScope.prefix(): String } @@ -113,5 +117,6 @@ public abstract class PainterSuffixHint : PainterPathHint { append(path.substringAfterLast('.')) } + /** Returns the suffix string to insert before the file extension of the resource path. */ public abstract fun PainterProviderScope.suffix(): String } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHintsProvider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHintsProvider.kt index 55ec2b7b0052..3f8bc6abb976 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHintsProvider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterHintsProvider.kt @@ -34,6 +34,7 @@ public object CommonPainterHintsProvider : PainterHintsProvider { @Composable override fun hints(path: String): List = listOf(HiDpi(), Dark(JewelTheme.isDark)) } +/** The composition local that provides the current [PainterHintsProvider]. */ public val LocalPainterHintsProvider: ProvidableCompositionLocal = staticCompositionLocalOf { CommonPainterHintsProvider } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterProviderScope.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterProviderScope.kt index a2b3cc9161d3..9d9cb35f6bf7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterProviderScope.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/PainterProviderScope.kt @@ -2,14 +2,20 @@ package org.jetbrains.jewel.ui.painter import androidx.compose.ui.unit.Density +/** Provides path, resolved path, and accepted hints to composables that load painters from a [PainterProvider]. */ public interface PainterProviderScope : Density { + /** The original, unmodified resource path as provided by the caller. */ public val rawPath: String + /** The resolved resource path after applying any path transformations or hint overrides. */ public val path: String + /** The list of [PainterHint]s that were accepted and applied to this scope. */ public val acceptedHints: List } +/** Extends [PainterProviderScope] with the set of [ClassLoader]s used to resolve resource-backed painters. */ public interface ResourcePainterProviderScope : PainterProviderScope { + /** The set of [ClassLoader]s used to locate and load resource-backed painter assets. */ public val classLoaders: Set } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt index 9a14b7f3a2ad..c13fc80075f8 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/ResourcePainterProvider.kt @@ -268,6 +268,13 @@ internal fun Document.writeToString(): String { } } +/** + * Creates and remembers a [ResourcePainterProvider] for the given [iconKey], resolving the resource path for the + * current UI mode (New UI vs. Classic UI). + * + * @param iconKey The [IconKey] identifying the icon resource. + * @param iconClass The class whose [ClassLoader] is used to locate the resource. Defaults to [IconKey.iconClass]. + */ @Composable public fun rememberResourcePainterProvider(iconKey: IconKey, iconClass: Class<*> = iconKey.iconClass): PainterProvider { val isNewUi = LocalNewUiChecker.current.isNewUi() @@ -276,6 +283,12 @@ public fun rememberResourcePainterProvider(iconKey: IconKey, iconClass: Class<*> } } +/** + * Creates and remembers a [ResourcePainterProvider] for the given resource [path]. + * + * @param path The classpath-relative path of the icon resource. + * @param iconClass The class whose [ClassLoader] is used to locate the resource. + */ @Composable public fun rememberResourcePainterProvider(path: String, iconClass: Class<*>): PainterProvider = remember(path, iconClass.classLoader) { ResourcePainterProvider(path, iconClass.classLoader) } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/badge/DotBadgeShape.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/badge/DotBadgeShape.kt index e46c1f1b3385..ac234a53d633 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/badge/DotBadgeShape.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/badge/DotBadgeShape.kt @@ -13,9 +13,13 @@ import org.jetbrains.jewel.foundation.GenerateDataFunctions @Immutable @GenerateDataFunctions public class DotBadgeShape( + /** The horizontal center of the dot as a fraction of the icon width. */ public val x: Float = 16.5f / 20, + /** The vertical center of the dot as a fraction of the icon height. */ public val y: Float = 3.5f / 20, + /** The radius of the dot as a fraction of the icon's smallest dimension. */ public val radius: Float = 3.5f / 20, + /** The border (hole expansion) size as a fraction of the icon's smallest dimension. */ public val border: Float = 1.5f / 20, ) : BadgeShape { override fun createHoleOutline(size: Size, layoutDirection: LayoutDirection, density: Density): Outline = @@ -75,7 +79,9 @@ public class DotBadgeShape( override fun toString(): String = "DotBadgeShape(x=$x, y=$y, radius=$radius, border=$border)" + /** Companion object for [DotBadgeShape]. */ public companion object { + /** The default [DotBadgeShape] instance. */ public val Default: DotBadgeShape = DotBadgeShape() } } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/EmbeddedToInlineCssStyleSvgPatchHint.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/EmbeddedToInlineCssStyleSvgPatchHint.kt index c2cbd4858f5a..39491923ea4a 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/EmbeddedToInlineCssStyleSvgPatchHint.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/EmbeddedToInlineCssStyleSvgPatchHint.kt @@ -126,6 +126,7 @@ public object EmbeddedToInlineCssStyleSvgPatchHint : PainterSvgPatchHint { * ``` * * @param cache Pre-built cache containing CSS class-to-rule mappings + * @param parser The [CssParser] used to parse inline style values during merging. */ private fun Element.inlineStyleDeclarations(cache: CssClassAttributesCache, parser: CssParser) { val classAttributeName = "class" diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/Selected.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/Selected.kt index c6e529717c95..a62639e629eb 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/Selected.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/painter/hints/Selected.kt @@ -26,4 +26,5 @@ private object SelectedImpl : PainterSuffixHint() { @Suppress("FunctionName") public fun Selected(selected: Boolean = true): PainterHint = if (selected) SelectedImpl else PainterHint.None +/** Selects the "selected" variant of an image based on [state]'s [SelectableComponentState.isSelected] flag. */ @Suppress("FunctionName") public fun Selected(state: SelectableComponentState): PainterHint = Selected(state.isSelected) diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/platform/PlatformCursorController.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/platform/PlatformCursorController.kt index 4a8b9fa15271..d8dd2bea86cc 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/platform/PlatformCursorController.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/platform/PlatformCursorController.kt @@ -19,6 +19,7 @@ public interface PlatformCursorController { public fun hideCursor() } +/** CompositionLocal that provides the current [PlatformCursorController]. */ public val LocalPlatformCursorController: ProvidableCompositionLocal = staticCompositionLocalOf { error("No LocalPlatformCursorController provided. Have you forgotten the theme?") diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt index 5e12213ec060..15f4c79b83f6 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt @@ -91,9 +91,11 @@ import org.jetbrains.jewel.ui.component.styling.TextAreaStyle import org.jetbrains.jewel.ui.component.styling.TextFieldStyle import org.jetbrains.jewel.ui.component.styling.TooltipStyle +/** The color palette for the current theme. */ public val JewelTheme.Companion.colorPalette: ThemeColorPalette @Composable @ReadOnlyComposable get() = LocalColorPalette.current +/** The icon data for the current theme. */ public val JewelTheme.Companion.iconData: ThemeIconData @Composable @ReadOnlyComposable get() = LocalIconData.current @@ -101,119 +103,157 @@ public val JewelTheme.Companion.iconData: ThemeIconData // Component styling // ----------------- +/** The styling for default banner components. */ public val JewelTheme.Companion.defaultBannerStyle: DefaultBannerStyles @Composable @ReadOnlyComposable get() = LocalDefaultBannerStyle.current +/** The styling for the default (filled) button. */ public val JewelTheme.Companion.defaultButtonStyle: ButtonStyle @Composable @ReadOnlyComposable get() = LocalDefaultButtonStyle.current +/** The styling for the outlined button. */ public val JewelTheme.Companion.outlinedButtonStyle: ButtonStyle @Composable @ReadOnlyComposable get() = LocalOutlinedButtonStyle.current +/** The styling for the default (filled) split button. */ public val JewelTheme.Companion.defaultSplitButtonStyle: SplitButtonStyle @Composable @ReadOnlyComposable get() = LocalDefaultSplitButtonStyle.current +/** The styling for the outlined split button. */ public val JewelTheme.Companion.outlinedSplitButtonStyle: SplitButtonStyle @Composable @ReadOnlyComposable get() = LocalOutlinedSplitButtonStyle.current +/** The styling for checkbox components. */ public val JewelTheme.Companion.checkboxStyle: CheckboxStyle @Composable @ReadOnlyComposable get() = LocalCheckboxStyle.current +/** The styling for chip components. */ public val JewelTheme.Companion.chipStyle: ChipStyle @Composable @ReadOnlyComposable get() = LocalChipStyle.current +/** The styling for divider components. */ public val JewelTheme.Companion.dividerStyle: DividerStyle @Composable @ReadOnlyComposable get() = LocalDividerStyle.current +/** The styling for dropdown components. */ public val JewelTheme.Companion.dropdownStyle: DropdownStyle @Composable @ReadOnlyComposable get() = LocalDefaultDropdownStyle.current +/** The styling for combo box components. */ public val JewelTheme.Companion.comboBoxStyle: ComboBoxStyle @Composable @ReadOnlyComposable get() = LocalDefaultComboBoxStyle.current +/** The styling for group header components. */ public val JewelTheme.Companion.groupHeaderStyle: GroupHeaderStyle @Composable @ReadOnlyComposable get() = LocalGroupHeaderStyle.current +/** The styling for inline banner components. */ public val JewelTheme.Companion.inlineBannerStyle: InlineBannerStyles @Composable @ReadOnlyComposable get() = LocalInlineBannerStyle.current +/** The styling for link components. */ public val JewelTheme.Companion.linkStyle: LinkStyle @Composable @ReadOnlyComposable get() = LocalLinkStyle.current +/** The styling for menu components. */ public val JewelTheme.Companion.menuStyle: MenuStyle @Composable @ReadOnlyComposable get() = LocalMenuStyle.current +/** The styling for popup container components. */ public val JewelTheme.Companion.popupContainerStyle: PopupContainerStyle @Composable @ReadOnlyComposable get() = LocalPopupContainerStyle.current +/** The styling for horizontal progress bar components. */ public val JewelTheme.Companion.horizontalProgressBarStyle: HorizontalProgressBarStyle @Composable @ReadOnlyComposable get() = LocalHorizontalProgressBarStyle.current +/** The styling for radio button components. */ public val JewelTheme.Companion.radioButtonStyle: RadioButtonStyle @Composable @ReadOnlyComposable get() = LocalRadioButtonStyle.current +/** The styling for scrollbar components. */ public val JewelTheme.Companion.scrollbarStyle: ScrollbarStyle @Composable @ReadOnlyComposable get() = LocalScrollbarStyle.current +/** The styling for selectable lazy column components. */ public val JewelTheme.Companion.selectableLazyColumnStyle: SelectableLazyColumnStyle @Composable @ReadOnlyComposable get() = LocalSelectableLazyColumnStyle.current +/** The styling for segmented control button components. */ public val JewelTheme.Companion.segmentedControlButtonStyle: SegmentedControlButtonStyle @Composable @ReadOnlyComposable get() = LocalSegmentedControlButtonStyle.current +/** The styling for segmented control components. */ public val JewelTheme.Companion.segmentedControlStyle: SegmentedControlStyle @Composable @ReadOnlyComposable get() = LocalSegmentedControlStyle.current +/** The styling for simple list item components. */ public val JewelTheme.Companion.simpleListItemStyle: SimpleListItemStyle @Composable @ReadOnlyComposable get() = LocalSimpleListItemStyleStyle.current +/** The styling for text area components. */ public val JewelTheme.Companion.textAreaStyle: TextAreaStyle @Composable @ReadOnlyComposable get() = LocalTextAreaStyle.current +/** The styling for text field components. */ public val JewelTheme.Companion.textFieldStyle: TextFieldStyle @Composable @ReadOnlyComposable get() = LocalTextFieldStyle.current +/** The styling for lazy tree components. */ public val JewelTheme.Companion.treeStyle: LazyTreeStyle @Composable @ReadOnlyComposable get() = LocalLazyTreeStyle.current +/** The styling for default tab components. */ public val JewelTheme.Companion.defaultTabStyle: TabStyle @Composable @ReadOnlyComposable get() = LocalDefaultTabStyle.current +/** The styling for editor tab components. */ public val JewelTheme.Companion.editorTabStyle: TabStyle @Composable @ReadOnlyComposable get() = LocalEditorTabStyle.current +/** The styling for circular progress indicator components. */ public val JewelTheme.Companion.circularProgressStyle: CircularProgressStyle @Composable @ReadOnlyComposable get() = LocalCircularProgressStyle.current +/** The styling for tooltip components. */ public val JewelTheme.Companion.tooltipStyle: TooltipStyle @Composable @ReadOnlyComposable get() = LocalTooltipStyle.current +/** The styling for icon button components. */ public val JewelTheme.Companion.iconButtonStyle: IconButtonStyle @Composable @ReadOnlyComposable get() = LocalIconButtonStyle.current +/** The styling for transparent icon button components. */ @get:ApiStatus.Experimental @ExperimentalJewelApi public val JewelTheme.Companion.transparentIconButtonStyle: IconButtonStyle @Composable @ReadOnlyComposable get() = LocalTransparentIconButtonStyle.current +/** The styling for slider components. */ public val JewelTheme.Companion.sliderStyle: SliderStyle @Composable @ReadOnlyComposable get() = LocalSliderStyle.current +/** The styling for speed search components. */ public val JewelTheme.Companion.speedSearchStyle: SpeedSearchStyle @Composable @ReadOnlyComposable get() = LocalSpeedSearchStyle.current +/** The styling for search match highlight components. */ public val JewelTheme.Companion.searchMatchStyle: SearchMatchStyle @Composable @ReadOnlyComposable get() = LocalSearchMatchStyle.current +/** The styling for popup ad components. */ public val JewelTheme.Companion.popupAdStyle: PopupAdStyle @Composable @ReadOnlyComposable get() = LocalPopupAdStyle.current +/** The styling for the default (filled) slim button. */ public val JewelTheme.Companion.defaultSlimButtonStyle: ButtonStyle @Composable @ReadOnlyComposable get() = LocalDefaultSlimButtonStyle.current +/** The styling for the outlined slim button. */ public val JewelTheme.Companion.outlinedSlimButtonStyle: ButtonStyle @Composable @ReadOnlyComposable get() = LocalOutlinedSlimButtonStyle.current +/** The styling for badge components. */ public val JewelTheme.Companion.badgeStyle: BadgeStyles @Composable @ReadOnlyComposable get() = LocalBadgeStyle.current @@ -237,6 +277,14 @@ public fun BaseJewelTheme(theme: ThemeDefinition, styling: ComponentStyling, con BaseJewelTheme(theme, styling, swingCompatMode = false, content) } +/** + * Applies [theme] and [styling] to the [content] composition tree. + * + * @param theme The [ThemeDefinition] describing colors, metrics, and text styles. + * @param styling The [ComponentStyling] providing all component-level styles. + * @param swingCompatMode Whether to enable Swing compatibility mode (disables hover/press state changes). + * @param content The composable content to render under this theme. + */ @Composable public fun BaseJewelTheme( theme: ThemeDefinition, diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/util/MessageResourceResolver.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/util/MessageResourceResolver.kt index 81ca7c843e47..56ad98c58ea7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/util/MessageResourceResolver.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/util/MessageResourceResolver.kt @@ -26,6 +26,7 @@ public interface MessageResourceResolver { @Nls public fun resolveIdeBundleMessage(key: String): String } +/** The composition local providing the [MessageResourceResolver] for resolving IDE bundle messages. */ @InternalJewelApi @get:ApiStatus.Internal public val LocalMessageResourceResolverProvider: ProvidableCompositionLocal =