mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 01:54:47 +00:00
refactor: Button components (#6929)
* feat: refactor button components
* fix: qa
* fix: storybook
* a11y: pass
* fix: build
* fix: rename default ->md
* fix: lint
* docs: buttons.md
* refactor part 1
* refactor part 2
* fix: undo refactor for fresh restart
* refactor
* Revert "refactor"
This reverts commit 96d65902d7.
* refactor: part 1
* fix: qa
* fix: qa
* fix: qa
* fix: qa
* fix: qa
* fix: qa
* fix: qa
* fix: qa
* fix: remove text-contrast
* fix: qa
* fix: v-tooltip
* fix: lint
* fix: split broken
* fix: passkey qa
* fix: qa
* fix: qa
* fix: prepr
* fix: splitbutton
* improve button group seam
---------
Signed-off-by: Calum H. <calum@modrinth.com>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
@@ -49,19 +49,19 @@
|
||||
</div>
|
||||
|
||||
<!-- Standard mode: button trigger -->
|
||||
<span
|
||||
<ButtonFrame
|
||||
v-else
|
||||
ref="triggerRef"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
class="relative flex min-h-5 w-full items-center justify-between overflow-hidden rounded-xl bg-surface-4 px-4 py-2 text-left transition-all duration-200 text-button-text gap-2.5"
|
||||
as="button"
|
||||
native-type="button"
|
||||
:type="triggerType"
|
||||
:size="triggerSize"
|
||||
:interaction="triggerInteraction"
|
||||
:disabled="disabled"
|
||||
:class="[
|
||||
'min-w-full w-full !justify-between overflow-hidden text-left',
|
||||
props.triggerClass,
|
||||
{
|
||||
'z-[9999]': isOpen,
|
||||
'cursor-not-allowed opacity-50': disabled,
|
||||
'cursor-pointer hover:brightness-[115%] active:brightness-[115%]': !disabled,
|
||||
},
|
||||
{ 'z-[9999]': isOpen },
|
||||
]"
|
||||
:aria-expanded="isOpen"
|
||||
:aria-haspopup="listbox ? 'listbox' : 'menu'"
|
||||
@@ -78,7 +78,7 @@
|
||||
/>
|
||||
<span
|
||||
v-if="selectedOption"
|
||||
class="min-w-0 truncate text-primary font-semibold leading-tight"
|
||||
class="min-w-0 truncate font-semibold leading-tight text-inherit"
|
||||
>
|
||||
<slot name="selected" :label="selectedTriggerText">{{ selectedTriggerText }}</slot>
|
||||
</span>
|
||||
@@ -94,7 +94,7 @@
|
||||
:class="isOpen ? (openDirection === 'down' ? 'rotate-90' : '-rotate-90') : '-rotate-90'"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
</ButtonFrame>
|
||||
|
||||
<Teleport to="#teleports">
|
||||
<Transition
|
||||
@@ -217,6 +217,13 @@ import {
|
||||
watch,
|
||||
} from 'vue'
|
||||
|
||||
import ButtonFrame from './buttons/ButtonFrame.vue'
|
||||
import type {
|
||||
ButtonElementHandle,
|
||||
ButtonInteraction,
|
||||
ButtonSize,
|
||||
ButtonType,
|
||||
} from './buttons/types'
|
||||
import StyledInput from './StyledInput.vue'
|
||||
|
||||
export interface ComboboxOption<T> {
|
||||
@@ -281,6 +288,10 @@ const props = withDefaults(
|
||||
displayValue?: string
|
||||
searchValue?: string
|
||||
triggerClass?: string
|
||||
/** Shared button frame style for non-searchable combobox triggers. */
|
||||
triggerType?: ButtonType
|
||||
triggerSize?: ButtonSize
|
||||
triggerInteraction?: ButtonInteraction
|
||||
dropdownClass?: string
|
||||
/** Additional selectors to ignore when detecting outside clicks */
|
||||
outsideClickIgnore?: string[]
|
||||
@@ -322,6 +333,9 @@ const props = withDefaults(
|
||||
selectSearchTextOnFocus: false,
|
||||
showSearchIcon: false,
|
||||
searchType: 'text',
|
||||
triggerType: 'base',
|
||||
triggerSize: 'md',
|
||||
triggerInteraction: 'surface',
|
||||
outsideClickIgnore: () => [],
|
||||
},
|
||||
)
|
||||
@@ -343,7 +357,7 @@ const searchQuery = ref('')
|
||||
const userHasTyped = ref(false)
|
||||
const focusedIndex = ref(-1)
|
||||
const containerRef = ref<HTMLElement>()
|
||||
const triggerRef = ref<HTMLElement>()
|
||||
const triggerRef = ref<ButtonElementHandle>()
|
||||
const searchTriggerRef = ref<InstanceType<typeof StyledInput>>()
|
||||
const dropdownRef = ref<HTMLElement>()
|
||||
const optionsScrollbarRef = ref<HTMLElement>()
|
||||
@@ -357,10 +371,11 @@ const effectiveTriggerEl = computed(() => {
|
||||
if (props.searchable && searchTriggerRef.value) {
|
||||
return (searchTriggerRef.value as unknown as { $el: HTMLElement }).$el as HTMLElement
|
||||
}
|
||||
return triggerRef.value
|
||||
|
||||
return triggerRef.value?.element ?? undefined
|
||||
})
|
||||
const outsideClickIgnoreTargets = computed(() => [
|
||||
triggerRef,
|
||||
effectiveTriggerEl,
|
||||
containerRef,
|
||||
...props.outsideClickIgnore,
|
||||
])
|
||||
@@ -642,7 +657,7 @@ function closeDropdown() {
|
||||
|
||||
if (!props.searchable) {
|
||||
nextTick(() => {
|
||||
triggerRef.value?.focus()
|
||||
effectiveTriggerEl.value?.focus()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user