mirror of
https://github.com/modrinth/code.git
synced 2026-08-26 01:26:23 +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:
+7
-11
@@ -12,23 +12,19 @@
|
||||
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled type="transparent">
|
||||
<button @click="modal?.hide()">
|
||||
{{ formatMessage(analyticsChartMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="orange">
|
||||
<button class="!shadow-none" @click="confirm">
|
||||
{{ formatMessage(analyticsChartMessages.showAll) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<Button type="quiet" @click="modal?.hide()">
|
||||
{{ formatMessage(analyticsChartMessages.cancelButton) }}
|
||||
</Button>
|
||||
<Button type="colored" color="orange" @click="confirm">
|
||||
{{ formatMessage(analyticsChartMessages.showAll) }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { Button, NewModal, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import { analyticsChartMessages } from '../../analytics-messages'
|
||||
|
||||
|
||||
@@ -31,23 +31,22 @@
|
||||
wrapper-class="w-full sm:w-64"
|
||||
@focusin="selectSearchInputText"
|
||||
/>
|
||||
<ButtonStyled>
|
||||
<OverflowMenu
|
||||
class="!shadow-none"
|
||||
:options="csvExportOptions"
|
||||
:disabled="isDataLoading || filteredRows.length === 0"
|
||||
>
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(analyticsTableMessages.exportCsvButton) }}
|
||||
<DropdownIcon />
|
||||
<template #cumulative-csv>
|
||||
{{ formatMessage(analyticsTableMessages.cumulativeCsv) }}
|
||||
</template>
|
||||
<template #grouped-csv>
|
||||
{{ formatMessage(analyticsTableMessages.groupedCsv, { groupBy: groupByLabel }) }}
|
||||
</template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
<TeleportOverflowMenu
|
||||
label="More options"
|
||||
class="!w-auto !rounded-xl !px-2.5"
|
||||
:options="csvExportOptions"
|
||||
:disabled="isDataLoading || filteredRows.length === 0"
|
||||
>
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(analyticsTableMessages.exportCsvButton) }}
|
||||
<DropdownIcon />
|
||||
<template #cumulative-csv>
|
||||
{{ formatMessage(analyticsTableMessages.cumulativeCsv) }}
|
||||
</template>
|
||||
<template #grouped-csv>
|
||||
{{ formatMessage(analyticsTableMessages.groupedCsv, { groupBy: groupByLabel }) }}
|
||||
</template>
|
||||
</TeleportOverflowMenu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -191,9 +190,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon, DropdownIcon, SearchIcon, UserIcon } from '@modrinth/assets'
|
||||
import { TeleportOverflowMenu } from '@modrinth/ui'
|
||||
import {
|
||||
ButtonStyled,
|
||||
OverflowMenu,
|
||||
type OverflowMenuOption,
|
||||
Pagination,
|
||||
StyledInput,
|
||||
@@ -370,10 +368,12 @@ const csvExportOptions = computed<OverflowMenuOption[]>(() => {
|
||||
return [
|
||||
{
|
||||
id: 'cumulative-csv',
|
||||
label: formatMessage(analyticsTableMessages.cumulativeCsv),
|
||||
action: () => downloadCsv('breakdown_only'),
|
||||
},
|
||||
{
|
||||
id: 'grouped-csv',
|
||||
label: formatMessage(analyticsTableMessages.groupedCsv, { groupBy: groupByLabel.value }),
|
||||
action: () => downloadCsv('date_breakdown'),
|
||||
},
|
||||
]
|
||||
@@ -384,6 +384,10 @@ const csvExportOptions = computed<OverflowMenuOption[]>(() => {
|
||||
return [
|
||||
{
|
||||
id: mode === 'date_breakdown' ? 'grouped-csv' : 'cumulative-csv',
|
||||
label:
|
||||
mode === 'date_breakdown'
|
||||
? formatMessage(analyticsTableMessages.groupedCsv, { groupBy: groupByLabel.value })
|
||||
: formatMessage(analyticsTableMessages.cumulativeCsv),
|
||||
action: () => downloadCsv(mode),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -6,25 +6,23 @@
|
||||
{{ formatMessage(analyticsMessages.title) }}
|
||||
</span>
|
||||
<div class="flex flex-wrap items-center justify-end gap-2">
|
||||
<ButtonStyled type="transparent">
|
||||
<button
|
||||
type="button"
|
||||
:disabled="isAnalyticsQueryBuilderDefault"
|
||||
@click="resetAnalyticsQueryBuilder"
|
||||
>
|
||||
{{ formatMessage(analyticsMessages.resetButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled type="outlined">
|
||||
<button
|
||||
type="button"
|
||||
:disabled="projects.length === 0 || !fetchRequest || isRefetching"
|
||||
@click="refreshAnalyticsQuery"
|
||||
>
|
||||
<RefreshCwIcon :class="isRefetching ? 'animate-spin' : ''" />
|
||||
{{ formatMessage(analyticsMessages.refreshButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<Button
|
||||
type="quiet"
|
||||
native-type="button"
|
||||
:disabled="isAnalyticsQueryBuilderDefault"
|
||||
@click="resetAnalyticsQueryBuilder"
|
||||
>
|
||||
{{ formatMessage(analyticsMessages.resetButton) }}
|
||||
</Button>
|
||||
<Button
|
||||
type="outlined"
|
||||
native-type="button"
|
||||
:disabled="projects.length === 0 || !fetchRequest || isRefetching"
|
||||
@click="refreshAnalyticsQuery"
|
||||
>
|
||||
<RefreshCwIcon :class="isRefetching ? 'animate-spin' : ''" />
|
||||
{{ formatMessage(analyticsMessages.refreshButton) }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<QueryBuilder />
|
||||
@@ -37,7 +35,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RefreshCwIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, injectProjectPageContext, useVIntl } from '@modrinth/ui'
|
||||
import { Button, injectProjectPageContext, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import {
|
||||
createAnalyticsDashboardContext,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
:show-preview-filter-icon="showPreviewFilterIcon"
|
||||
:preview-trigger-class="previewTriggerClass"
|
||||
:add-button-class="addButtonClass"
|
||||
:add-button-size="addButtonSize"
|
||||
:clear-label="formatMessage(analyticsMessages.resetButton)"
|
||||
:add-label="resolvedAddLabel"
|
||||
checkbox-position="right"
|
||||
@@ -199,6 +200,7 @@
|
||||
import { BoxIcon, UserIcon } from '@modrinth/assets'
|
||||
import {
|
||||
buildDependentsSearchFilters,
|
||||
type ButtonSize,
|
||||
DropdownFilterBar,
|
||||
type DropdownFilterBarCategory,
|
||||
type DropdownFilterBarOption,
|
||||
@@ -273,6 +275,7 @@ const props = withDefaults(
|
||||
showPreviewFilterIcon?: boolean
|
||||
previewTriggerClass?: string
|
||||
addButtonClass?: string
|
||||
addButtonSize?: ButtonSize
|
||||
showClearAction?: boolean
|
||||
}>(),
|
||||
{
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
:min-date="ANALYTICS_START_DATE_INPUT_VALUE"
|
||||
:now-timestamp="queryRefreshTimestamp"
|
||||
:trigger-class="triggerClass"
|
||||
:trigger-type="triggerType"
|
||||
:trigger-size="triggerSize"
|
||||
:trigger-interaction="triggerInteraction"
|
||||
@open="handleTimeframeOpen"
|
||||
@commit="handleTimeframeCommit"
|
||||
@apply="handleTimeframeApply"
|
||||
@@ -23,6 +26,9 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
type ButtonInteraction,
|
||||
type ButtonSize,
|
||||
type ButtonType,
|
||||
type ComboboxOption,
|
||||
TimeFramePicker as BaseTimeFramePicker,
|
||||
type TimeFramePickerSelection,
|
||||
@@ -58,6 +64,9 @@ const {
|
||||
|
||||
defineProps<{
|
||||
triggerClass?: string
|
||||
triggerType?: ButtonType
|
||||
triggerSize?: ButtonSize
|
||||
triggerInteraction?: ButtonInteraction
|
||||
}>()
|
||||
|
||||
const draftSelectedGroupBy = ref(selectedGroupBy.value)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
:max-tag-rows="1"
|
||||
:trigger-class="analyticsQueryChipTriggerClass"
|
||||
fit-content
|
||||
trigger-type="base"
|
||||
checkbox-position="right"
|
||||
show-selection-actions
|
||||
@open="handleProjectSelectOpen"
|
||||
@@ -32,7 +33,7 @@
|
||||
decoding="async"
|
||||
/>
|
||||
<LayersIcon v-else class="size-5 shrink-0 text-primary" />
|
||||
<span class="min-w-0 flex-1 truncate px-0.5 font-semibold text-primary">
|
||||
<span class="min-w-0 flex-1 truncate px-0.5 font-semibold text-inherit">
|
||||
{{ selectedProjectLabel }}
|
||||
</span>
|
||||
<ChevronLeftIcon
|
||||
@@ -145,6 +146,7 @@
|
||||
:dropdown-min-width="QUERY_BUILDER_DROPDOWN_MIN_WIDTH"
|
||||
:display-value="selectedGroupByLabel"
|
||||
:trigger-class="analyticsQueryChipTriggerClass"
|
||||
trigger-type="base"
|
||||
>
|
||||
<template #prefix>
|
||||
<ClockIcon class="size-5 shrink-0 text-primary" />
|
||||
@@ -160,6 +162,7 @@
|
||||
:dropdown-min-width="QUERY_BUILDER_DROPDOWN_MIN_WIDTH"
|
||||
:trigger-class="analyticsQueryChipTriggerClass"
|
||||
fit-content
|
||||
trigger-type="base"
|
||||
checkbox-position="right"
|
||||
:placeholder="formatMessage(analyticsMessages.none)"
|
||||
show-selection-actions
|
||||
@@ -170,7 +173,7 @@
|
||||
<div class="flex min-h-7 min-w-0 max-w-full flex-1 items-center gap-1.5 pr-1">
|
||||
<BlocksIcon class="size-5 shrink-0 text-primary" />
|
||||
<span
|
||||
class="min-w-0 flex-1 truncate px-0.5 font-semibold text-primary"
|
||||
class="min-w-0 flex-1 truncate px-0.5 font-semibold text-inherit"
|
||||
:title="mobileSelectedBreakdownLabel"
|
||||
>
|
||||
{{ mobileSelectedBreakdownLabel }}
|
||||
@@ -191,6 +194,7 @@
|
||||
show-preview-filter-icon
|
||||
:show-clear-action="false"
|
||||
:add-button-class="analyticsQueryAddFilterButtonClass"
|
||||
add-button-size="lg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -214,6 +218,7 @@
|
||||
:searchable="projectOptions.length > 6"
|
||||
fuzzy-search
|
||||
:max-tag-rows="1"
|
||||
trigger-type="base"
|
||||
checkbox-position="right"
|
||||
show-selection-actions
|
||||
@open="handleProjectSelectOpen"
|
||||
@@ -243,7 +248,7 @@
|
||||
class="size-5 shrink-0 text-primary"
|
||||
/>
|
||||
<BoxIcon v-else class="size-5 shrink-0 text-primary" />
|
||||
<span class="min-w-0 flex-1 truncate px-1.5 font-semibold text-primary">
|
||||
<span class="min-w-0 flex-1 truncate px-1.5 font-semibold text-inherit">
|
||||
{{ selectedProjectLabel }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -372,18 +377,19 @@
|
||||
:options="groupByOptions"
|
||||
:max-height="QUERY_BUILDER_DROPDOWN_MAX_HEIGHT"
|
||||
:dropdown-min-width="QUERY_BUILDER_DROPDOWN_MIN_WIDTH"
|
||||
trigger-type="base"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ButtonStyled v-if="!isTimeframeAndGroupByDefault" type="transparent">
|
||||
<button
|
||||
type="button"
|
||||
:disabled="isTimeframeAndGroupByDefault"
|
||||
@click="resetTimeframeAndGroupBy"
|
||||
>
|
||||
{{ formatMessage(analyticsMessages.resetButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<Button
|
||||
v-if="!isTimeframeAndGroupByDefault"
|
||||
type="quiet"
|
||||
native-type="button"
|
||||
:disabled="isTimeframeAndGroupByDefault"
|
||||
@click="resetTimeframeAndGroupBy"
|
||||
>
|
||||
{{ formatMessage(analyticsMessages.resetButton) }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-start gap-2">
|
||||
@@ -403,6 +409,7 @@
|
||||
:max-height="QUERY_BUILDER_DROPDOWN_MAX_HEIGHT"
|
||||
:dropdown-width="QUERY_BUILDER_DROPDOWN_MIN_WIDTH"
|
||||
:dropdown-min-width="QUERY_BUILDER_DROPDOWN_MIN_WIDTH"
|
||||
trigger-type="base"
|
||||
checkbox-position="right"
|
||||
:placeholder="formatMessage(analyticsMessages.none)"
|
||||
show-selection-actions
|
||||
@@ -412,7 +419,7 @@
|
||||
<template #input-content="{ isOpen, openDirection }">
|
||||
<div class="flex min-h-7 min-w-0 flex-1 items-center gap-1.5 pr-1">
|
||||
<span
|
||||
class="min-w-0 flex-1 truncate font-semibold text-primary"
|
||||
class="min-w-0 flex-1 truncate font-semibold text-inherit"
|
||||
:title="selectedBreakdownLabel"
|
||||
>
|
||||
{{ selectedBreakdownLabel }}
|
||||
@@ -453,8 +460,8 @@ import {
|
||||
LayersIcon,
|
||||
UserIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import {
|
||||
ButtonStyled,
|
||||
Combobox,
|
||||
type ComboboxOption,
|
||||
MultiSelect,
|
||||
@@ -504,7 +511,7 @@ import TimeFramePicker from './TimeframePicker.vue'
|
||||
const QUERY_BUILDER_DROPDOWN_MAX_HEIGHT = 500
|
||||
const QUERY_BUILDER_DROPDOWN_MIN_WIDTH = '14rem'
|
||||
const analyticsQueryChipTriggerClass = 'h-10 '
|
||||
const analyticsQueryAddFilterButtonClass = '!h-10 max-w-full !w-max !px-3.5 flex !gap-2'
|
||||
const analyticsQueryAddFilterButtonClass = 'max-w-full !w-max !px-3.5 flex !gap-2'
|
||||
const projectOptionCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })
|
||||
type ProjectSelectionPreset = 'user' | 'all'
|
||||
|
||||
|
||||
@@ -12,12 +12,16 @@
|
||||
{{ formatMessage(analyticsStatCardMessages.monetizationBannerBody) }}
|
||||
</div>
|
||||
<template #actions>
|
||||
<ButtonStyled color="blue">
|
||||
<a href="https://modrinth.com/legal/cmp-info" target="_blank" class="w-fit !px-4">
|
||||
{{ formatMessage(analyticsStatCardMessages.monetizationBannerLearnMore) }}
|
||||
<RightArrowIcon aria-hidden="true" />
|
||||
</a>
|
||||
</ButtonStyled>
|
||||
<ButtonLink
|
||||
type="colored"
|
||||
color="blue"
|
||||
href="https://modrinth.com/legal/cmp-info"
|
||||
target="_blank"
|
||||
class="w-fit !px-4"
|
||||
>
|
||||
{{ formatMessage(analyticsStatCardMessages.monetizationBannerLearnMore) }}
|
||||
<RightArrowIcon aria-hidden="true" />
|
||||
</ButtonLink>
|
||||
</template>
|
||||
</Admonition>
|
||||
<div class="grid grid-cols-2 gap-3 lg:grid-cols-4">
|
||||
@@ -39,7 +43,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RightArrowIcon } from '@modrinth/assets'
|
||||
import { Admonition, ButtonStyled, useFormatNumber, useVIntl } from '@modrinth/ui'
|
||||
import { Admonition, ButtonLink, useFormatNumber, useVIntl } from '@modrinth/ui'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user