mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
* fix: keep the instance users table's actions and header in view Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015pMjimm9tUMXtD8rkWB62w * fix: lock only the User option for group-granted roles and keep pinned cells opaque Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015pMjimm9tUMXtD8rkWB62w * fix: close the instance settings drawer from the manage-in-workspace menu item Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015pMjimm9tUMXtD8rkWB62w --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
126 lines
3.8 KiB
Svelte
126 lines
3.8 KiB
Svelte
<script lang="ts">
|
|
import { twMerge } from 'tailwind-merge'
|
|
import Tooltip from '$lib/components/meltComponents/Tooltip.svelte'
|
|
import { type ToggleGroupElements, type ToggleGroupItemProps, melt } from '@melt-ui/svelte'
|
|
import { Info } from 'lucide-svelte'
|
|
import { ButtonType } from '$lib/components/common/button/model'
|
|
|
|
interface Props {
|
|
label?: string | undefined
|
|
/** Shown instead of `label` below the `xl` breakpoint, for groups that must keep
|
|
* their width inside a narrow table cell. The full label stays the accessible name. */
|
|
shortLabel?: string | undefined
|
|
iconOnly?: boolean
|
|
tooltip?: string | undefined
|
|
icon?: any | undefined
|
|
disabled?: boolean
|
|
selectedColor?: string | undefined
|
|
small?: boolean
|
|
size?: 'sm' | 'md' | 'lg'
|
|
iconProps?: Record<string, any>
|
|
showTooltipIcon?: boolean
|
|
documentationLink?: string | undefined
|
|
id?: string | undefined
|
|
item: ToggleGroupElements['item']
|
|
value: ToggleGroupItemProps
|
|
class?: string
|
|
// Fires on activation, including on the already-selected button — which the
|
|
// group's onSelected never reports (melt treats it as a deselection and the
|
|
// group keeps the current value). Keyboard activation needs its own keydown
|
|
// branch below: melt preventDefaults Enter/Space, so no click is synthesized.
|
|
onActivate?: (e: Event) => void
|
|
}
|
|
|
|
let {
|
|
label = undefined,
|
|
shortLabel = undefined,
|
|
iconOnly = false,
|
|
tooltip = undefined,
|
|
icon = undefined,
|
|
disabled = false,
|
|
selectedColor = undefined,
|
|
small = false,
|
|
size = undefined,
|
|
iconProps = {},
|
|
showTooltipIcon = false,
|
|
documentationLink = undefined,
|
|
id = undefined,
|
|
item,
|
|
value,
|
|
class: className = '',
|
|
onActivate
|
|
}: Props = $props()
|
|
|
|
// Handle backward compatibility: small prop maps to size="sm"
|
|
const actualSize = $derived(size ?? (small ? 'sm' : 'md'))
|
|
|
|
// Direct access to unified sizing
|
|
const horizontalPadding = $derived(
|
|
iconOnly
|
|
? ButtonType.UnifiedIconOnlySizingClasses[actualSize]
|
|
: ButtonType.UnifiedSizingClasses[actualSize]
|
|
)
|
|
const height = $derived(ButtonType.UnifiedHeightClasses[actualSize])
|
|
const iconSize = $derived(ButtonType.UnifiedIconSizes[actualSize])
|
|
</script>
|
|
|
|
<Tooltip
|
|
class={twMerge('flex', disabled ? 'cursor-not-allowed' : 'cursor-pointer')}
|
|
disablePopup={tooltip === undefined}
|
|
{documentationLink}
|
|
>
|
|
<button
|
|
{id}
|
|
{disabled}
|
|
aria-label={shortLabel ? label : undefined}
|
|
class={twMerge(
|
|
'group rounded-md transition-all font-normal flex gap-1 flex-row items-center justify-center border text-xs',
|
|
horizontalPadding,
|
|
height,
|
|
'text-primary data-[state=on]:text-primary',
|
|
'data-[state=on]:bg-surface-tertiary data-[state=off]:border-transparent data-[state=on]:border-border-normal/30',
|
|
'bg-surface-transparent hover:bg-surface-hover',
|
|
disabled ? '!shadow-none !text-disabled' : '',
|
|
className
|
|
)}
|
|
use:melt={$item(value)}
|
|
style={selectedColor ? `--selected-color: ${selectedColor}` : ''}
|
|
onclick={onActivate}
|
|
onkeydown={(e) => {
|
|
// `repeat` filtered out: a held key keeps firing keydown, and one activation
|
|
// must mean one call however the consumer's side effect behaves.
|
|
if (!e.repeat && (e.key === 'Enter' || e.key === ' ')) onActivate?.(e)
|
|
}}
|
|
>
|
|
{#if icon}
|
|
{@const SvelteComponent = icon}
|
|
<SvelteComponent
|
|
size={iconSize}
|
|
{...iconProps}
|
|
class={twMerge(
|
|
'text-primary',
|
|
selectedColor
|
|
? 'group-data-[state=on]:text-[var(--selected-color)]'
|
|
: 'group-data-[state=on]:text-blue-500 dark:group-data-[state=on]:text-nord-800',
|
|
iconProps.class
|
|
)}
|
|
/>
|
|
{/if}
|
|
{#if label && !iconOnly}
|
|
{#if shortLabel}
|
|
<span class="hidden xl:inline">{label}</span>
|
|
<span class="xl:hidden" aria-hidden="true">{shortLabel}</span>
|
|
{:else}
|
|
{label}
|
|
{/if}
|
|
{/if}
|
|
{#if showTooltipIcon}
|
|
<Info size={iconSize} class="text-gray-400" />
|
|
{/if}
|
|
</button>
|
|
|
|
{#snippet text()}
|
|
{tooltip}
|
|
{/snippet}
|
|
</Tooltip>
|