mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[JEWEL-1346] Force Auto Correct + Enable Documentation Rules
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
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ea32a85584
commit
a4b53943c8
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+8
@@ -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)
|
||||
}
|
||||
|
||||
+9
@@ -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,
|
||||
|
||||
+29
@@ -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)
|
||||
|
||||
+40
@@ -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,
|
||||
|
||||
+64
-1
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
+7
@@ -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(
|
||||
|
||||
+19
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+25
-2
@@ -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<Color> =
|
||||
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<DecoratedWindowStyle> = staticCompositionLocalOf {
|
||||
error("No DecoratedWindowStyle provided. Have you forgotten the theme?")
|
||||
}
|
||||
|
||||
+43
-6
@@ -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<Color> =
|
||||
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<TitleBarStyle> = staticCompositionLocalOf {
|
||||
error("No TitleBarStyle provided. Have you forgotten the theme?")
|
||||
}
|
||||
|
||||
+10
@@ -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 {
|
||||
|
||||
+22
@@ -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))
|
||||
}
|
||||
|
||||
+38
-10
@@ -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<String> by config(defaultValue = listOf("equals", "hashCode", "toString"))
|
||||
|
||||
@Configuration("Only check classes annotated with these annotations")
|
||||
private val annotated: List<String> 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<KtObjectDeclaration>().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<String>) {
|
||||
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<KtObjectDeclaration>().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)
|
||||
}
|
||||
}
|
||||
|
||||
+33
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-4
@@ -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) {
|
||||
|
||||
+22
-6
@@ -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" +
|
||||
| ")"
|
||||
|}
|
||||
|}
|
||||
"""
|
||||
|
||||
+29
-29
@@ -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()
|
||||
|
||||
@@ -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<List<Findin
|
||||
val ktFile = compileContentForTest(code)
|
||||
ensurePsiMutationSupported()
|
||||
val findings = visitFile(ktFile, FakeLanguageVersionSettings())
|
||||
return findings to ktFile.text
|
||||
return findings to (ktFile.modifiedText ?: ktFile.text)
|
||||
}
|
||||
|
||||
internal fun ObjectAssert<Finding>.hasMessage(message: String) =
|
||||
|
||||
+10
-10
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
+2
@@ -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<DisabledAppearanceValues> =
|
||||
staticCompositionLocalOf {
|
||||
error("No DisabledAppearanceValues provided. Have you forgotten the theme?")
|
||||
|
||||
+4
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -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<GlobalMetrics> = staticCompositionLocalOf {
|
||||
error("No GlobalMetrics provided. Have you forgotten the theme?")
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+3
@@ -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 <TValue : Any> set(key: String, value: TValue?)
|
||||
|
||||
/** Registers a lazily-initialized value for the given [key]; [initializer] is invoked on first access. */
|
||||
public fun <TValue : Any> lazy(key: String, initializer: () -> TValue?)
|
||||
}
|
||||
|
||||
+6
-1
@@ -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
|
||||
}
|
||||
|
||||
+10
@@ -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\", " +
|
||||
|
||||
+5
@@ -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<AnnotatedString>
|
||||
}
|
||||
|
||||
/** The composition local that provides the current [CodeHighlighter] instance. */
|
||||
@ExperimentalJewelApi
|
||||
@get:ApiStatus.Experimental
|
||||
public val LocalCodeHighlighter: ProvidableCompositionLocal<CodeHighlighter> = staticCompositionLocalOf {
|
||||
|
||||
+1
@@ -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 {
|
||||
|
||||
+12
@@ -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
|
||||
|
||||
+18
@@ -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)
|
||||
}
|
||||
|
||||
+26
@@ -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 <T : Any> SelectableLazyListScope.items(
|
||||
items: List<T>,
|
||||
key: (item: T) -> Any = { it },
|
||||
@@ -168,6 +178,16 @@ public fun <T : Any> 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 <T : Any> SelectableLazyListScope.itemsIndexed(
|
||||
items: List<T>,
|
||||
key: (index: Int, item: T) -> Any = { _, item -> item },
|
||||
@@ -184,6 +204,12 @@ public fun <T : Any> 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,
|
||||
|
||||
+60
@@ -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<Any>
|
||||
}
|
||||
|
||||
@@ -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<Any> 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<Any>
|
||||
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<Any>
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
+34
-1
@@ -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 <T> 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,
|
||||
|
||||
+48
-2
@@ -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 <T> buildTree(builder: TreeBuilder<T>.() -> Unit): Tree<T> = TreeBuilder<T>().apply(builder).build()
|
||||
|
||||
/** A DSL builder for constructing a [Tree], used via [buildTree]. */
|
||||
public class TreeBuilder<T> : TreeGeneratorScope<T> {
|
||||
/** 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<T> {
|
||||
/** 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<T>(public val data: T, override val id: Any?) : Element<T>() {
|
||||
public class Leaf<T>(
|
||||
/** The data held by this leaf. */
|
||||
public val data: T,
|
||||
override val id: Any?,
|
||||
) : Element<T>() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
@@ -34,10 +48,13 @@ public class TreeBuilder<T> : TreeGeneratorScope<T> {
|
||||
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<T>(
|
||||
/** 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<T>.() -> Unit,
|
||||
) : Element<T>() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
@@ -78,6 +95,7 @@ public class TreeBuilder<T> : TreeGeneratorScope<T> {
|
||||
heads.add(element)
|
||||
}
|
||||
|
||||
/** Constructs and returns the [Tree] from all root entries added to this builder. */
|
||||
public fun build(): Tree<T> {
|
||||
val elements = mutableListOf<Tree.Element<T>>()
|
||||
for (index in heads.indices) {
|
||||
@@ -167,17 +185,30 @@ private fun <T> evaluatePrevious(element: Tree.Element<T>): Tree.Element<T> =
|
||||
}
|
||||
}
|
||||
|
||||
/** A DSL scope for adding [TreeBuilder.Element.Leaf] and [TreeBuilder.Element.Node] entries to a tree or subtree. */
|
||||
public interface TreeGeneratorScope<T> {
|
||||
/** 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<T>.() -> 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<T>)
|
||||
}
|
||||
|
||||
/** A [TreeGeneratorScope] used inside a node's children generator lambda, providing access to [parent] info. */
|
||||
public class ChildrenGeneratorScope<T>(private val parentElement: Tree.Element.Node<T>) : TreeGeneratorScope<T> {
|
||||
/** Holds identifying information about a node's parent: its data, depth in the tree, and child index. */
|
||||
@GenerateDataFunctions
|
||||
public class ParentInfo<T>(public val data: T, public val depth: Int, public val index: Int) {
|
||||
public class ParentInfo<T>(
|
||||
/** 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<T>(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<T> by lazy {
|
||||
ParentInfo(parentElement.data, parentElement.depth, parentElement.childIndex)
|
||||
}
|
||||
@@ -220,8 +252,22 @@ public class ChildrenGeneratorScope<T>(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<File> = 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<File> = buildTree {
|
||||
addNode(this@asTree, isOpen(this@asTree)) { generateFileNodes(isOpen) }
|
||||
}
|
||||
|
||||
+8
@@ -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
|
||||
|
||||
+1
@@ -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,
|
||||
|
||||
+80
@@ -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<SelectableLazyListKey>,
|
||||
@@ -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<SelectableLazyListKey>,
|
||||
@@ -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<SelectableLazyListKey>,
|
||||
@@ -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 <T> 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(
|
||||
|
||||
+44
@@ -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 <T> emptyTree(): Tree<T> = Tree.EMPTY as Tree<T>
|
||||
|
||||
/**
|
||||
* 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<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
/** Provides the [EMPTY] singleton for an empty tree with no root elements. */
|
||||
public companion object {
|
||||
internal val EMPTY = Tree(roots = emptyList<Element<Any?>>())
|
||||
}
|
||||
|
||||
/** 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<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a [Sequence] that traverses the tree in breadth-first order, opening nodes as it visits them. */
|
||||
public fun walkBreadthFirst(): Sequence<Element<T>> = walk(true)
|
||||
|
||||
/** Returns a [Sequence] that traverses the tree in depth-first order, opening nodes as it visits them. */
|
||||
public fun walkDepthFirst(): Sequence<Element<T>> = 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<T> {
|
||||
/** 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<T>?
|
||||
|
||||
/** 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<T>?
|
||||
|
||||
/** The previous element in the flattened linked list, or `null` if this is the first element. */
|
||||
public var previous: Element<T>?
|
||||
|
||||
/** 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<Element<T>> =
|
||||
buildList {
|
||||
var next: Element<T>? = this@Element
|
||||
@@ -50,12 +77,15 @@ public class Tree<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
}
|
||||
.reversed()
|
||||
|
||||
/** Returns an [Iterable] over elements preceding this one in the flattened linked list, in reverse order. */
|
||||
public fun previousElementsIterable(): Iterable<Element<T>> = 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<Element<T>> = Iterable { elementIterator(next) { it.next } }
|
||||
|
||||
/** A terminal element in the tree that holds [data] and has no children. */
|
||||
public class Leaf<T>(
|
||||
override val data: T,
|
||||
override val depth: Int,
|
||||
@@ -66,6 +96,9 @@ public class Tree<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
override val id: Any,
|
||||
) : Element<T>
|
||||
|
||||
/**
|
||||
* A branching element in the tree that holds [data] and can lazily generate [children] when [open] is called.
|
||||
*/
|
||||
public class Node<T>(
|
||||
override val data: T,
|
||||
override val depth: Int,
|
||||
@@ -76,6 +109,7 @@ public class Tree<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
override var previous: Element<T>?,
|
||||
override val id: Any,
|
||||
) : Element<T> {
|
||||
/** The lazily evaluated children of this node, or `null` if [open] has not been called yet. */
|
||||
public var children: List<Element<T>>? = null
|
||||
private set
|
||||
|
||||
@@ -103,11 +137,21 @@ public class Tree<T> internal constructor(public val roots: List<Element<T>>) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Node<*>>()?.forEach { it.closeRecursively() }
|
||||
|
||||
+21
@@ -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<Pair<Any, Int>>()
|
||||
|
||||
/** 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<Any> by mutableStateOf<Set<Any>>(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<Any>) {
|
||||
openNodes += nodes
|
||||
}
|
||||
|
||||
+1
@@ -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<SelectableLazyListKey>, state: SelectableLazyListState)
|
||||
|
||||
+1
@@ -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<Boolean> = modifierLocalOf { false }
|
||||
|
||||
+11
@@ -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 {
|
||||
|
||||
+8
-1
@@ -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<IntRange>) : 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<IntRange>?): 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 <T> Iterable<T>.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
|
||||
|
||||
+15
@@ -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
|
||||
}
|
||||
|
||||
+5
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
+8
@@ -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
|
||||
}
|
||||
|
||||
+2
@@ -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
|
||||
}
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+31
@@ -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<String> = staticCompositionLocalOf {
|
||||
error("No ThemeName provided")
|
||||
}
|
||||
@@ -89,6 +114,7 @@ public val LocalThemeInstanceUuid: ProvidableCompositionLocal<UUID> = 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<Color> = staticCompositionLocalOf {
|
||||
error("No ContentColor provided. Have you forgotten the theme?")
|
||||
}
|
||||
@@ -102,20 +128,25 @@ internal val LocalSwingCompatMode: ProvidableCompositionLocal<Boolean> = staticC
|
||||
false
|
||||
}
|
||||
|
||||
/** Composition local providing the color palette for the current theme. */
|
||||
public val LocalColorPalette: ProvidableCompositionLocal<ThemeColorPalette> = staticCompositionLocalOf {
|
||||
ThemeColorPalette.Empty
|
||||
}
|
||||
|
||||
/** Composition local providing icon data (mappings and overrides) for the current theme. */
|
||||
public val LocalIconData: ProvidableCompositionLocal<ThemeIconData> = staticCompositionLocalOf { ThemeIconData.Empty }
|
||||
|
||||
/** Composition local providing the default text style for the current theme. */
|
||||
public val LocalTextStyle: ProvidableCompositionLocal<TextStyle> = staticCompositionLocalOf {
|
||||
error("No TextStyle provided. Have you forgotten the theme?")
|
||||
}
|
||||
|
||||
/** Composition local providing the text style used in editor components. */
|
||||
public val LocalEditorTextStyle: ProvidableCompositionLocal<TextStyle> = 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<TextStyle> = staticCompositionLocalOf {
|
||||
error("No ConsoleTextStyle provided. Have you forgotten the theme?")
|
||||
}
|
||||
|
||||
+1
@@ -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(
|
||||
|
||||
+15
@@ -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.")
|
||||
|
||||
+8
@@ -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
|
||||
}
|
||||
|
||||
+10
@@ -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<String, String>,
|
||||
/** Maps color hex strings to replacement color hex strings (or null to leave unchanged) for icon tinting. */
|
||||
public val colorPalette: Map<String, String?>,
|
||||
/** Maps color hex strings to replacement ARGB int values used for selected icon tinting. */
|
||||
public val selectionColorPalette: Map<String, Int>,
|
||||
) {
|
||||
/**
|
||||
* 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<Color, Color> =
|
||||
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())
|
||||
|
||||
+19
@@ -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 <reified T : Any> 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}")
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -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()
|
||||
|
||||
+7
@@ -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)
|
||||
|
||||
+12
@@ -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 }
|
||||
}
|
||||
|
||||
+3
@@ -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<String>, type: String) :
|
||||
JewelBridgeException(
|
||||
"Keys ${keys.joinToString(", ") { "'$it'" }} not found in Swing LaF, " +
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+4
@@ -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
|
||||
|
||||
+7
@@ -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<Unit>(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()
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -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,
|
||||
|
||||
+1
@@ -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(),
|
||||
|
||||
+4
@@ -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)
|
||||
|
||||
+6
@@ -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),
|
||||
|
||||
+3
@@ -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),
|
||||
|
||||
+2
@@ -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(),
|
||||
|
||||
+1
@@ -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.
|
||||
*/
|
||||
|
||||
+7
@@ -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
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
+1
@@ -63,5 +63,6 @@ private val JetBrainsMonoFontFamily =
|
||||
),
|
||||
)
|
||||
|
||||
/** The JetBrains Mono font family, bundled with Jewel. */
|
||||
public val FontFamily.Companion.JetBrainsMono: FontFamily
|
||||
get() = JetBrainsMonoFontFamily
|
||||
|
||||
+1
@@ -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 =
|
||||
|
||||
+1
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -49,9 +49,11 @@ public open class DynamicBundle(bundleClass: Class<*>, private val pathToBundle:
|
||||
|
||||
private val cache = ConcurrentHashMap<String, ResourceBundle>()
|
||||
|
||||
/** 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(
|
||||
|
||||
+4
@@ -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 {
|
||||
|
||||
+58
-20
@@ -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(),
|
||||
|
||||
+51
@@ -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),
|
||||
|
||||
+32
@@ -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),
|
||||
|
||||
+7
@@ -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)
|
||||
|
||||
+6
@@ -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),
|
||||
|
||||
+2
@@ -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),
|
||||
|
||||
+21
@@ -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)
|
||||
|
||||
+2
@@ -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(),
|
||||
|
||||
+19
@@ -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)
|
||||
|
||||
+5
@@ -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)
|
||||
|
||||
+5
@@ -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,
|
||||
|
||||
+9
@@ -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,
|
||||
|
||||
+7
@@ -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,
|
||||
|
||||
+6
@@ -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,
|
||||
|
||||
+10
@@ -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)
|
||||
|
||||
+6
@@ -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,
|
||||
|
||||
+5
@@ -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),
|
||||
|
||||
+7
@@ -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)
|
||||
|
||||
+5
@@ -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),
|
||||
|
||||
+5
@@ -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),
|
||||
|
||||
+5
@@ -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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user