Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
johnleider committed Jul 16, 2024
2 parents 39e7c64 + 209dc01 commit d85a1ae
Show file tree
Hide file tree
Showing 29 changed files with 176 additions and 54 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "@vuetify/vuetify-root",
"private": true,
"workspaces": [
"packages/*"
Expand Down
2 changes: 1 addition & 1 deletion packages/api-generator/src/locale/en/VField.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"props": {
"appendInnerIcon": "Creates a [v-icon](/api/v-icon/) component in the **append-inner** slot.",
"baseColor": "Sets the color of the input when it is not focused.",
"centerAffix": "Automatically apply **[singleLine](/api/v-field/#props-single-line)** under the hood, and vertically align **appendInner**, **prependInner**, **clearIcon**, **label** and **input field** in the center.",
"centerAffix": "Vertically align **appendInner**, **prependInner**, **clearIcon** and **label** in the center.",
"clearIcon": "The icon used when the **clearable** prop is set to true.",
"dirty": "Manually apply the dirty state styling.",
"disabled": "Removes the ability to click or target the input.",
Expand Down
2 changes: 1 addition & 1 deletion packages/api-generator/src/locale/en/VInput.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"props": {
"backgroundColor": "Changes the background-color of the input.",
"centerAffix": "Vertically align **append** and **prepend** in the center.",
"centerAffix": "Vertically align **appendInner**, **prependInner**, **clearIcon** and **label** in the center.",
"direction": "Changes the direction of the input.",
"hideDetails": "Hides hint and validation errors. When set to `auto` messages will be rendered only if there's a message (hint, error message, counter value etc) to display.",
"hideSpinButtons": "Hides spin buttons on the input when type is set to `number`.",
Expand Down
4 changes: 3 additions & 1 deletion packages/api-generator/src/locale/en/VList.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"link": "Applies `v-list-item` hover styles. Useful when using the item is an _activator_.",
"nav": "An alternative styling that reduces `v-list-item` width and rounds the corners. Typically used with **[v-navigation-drawer](/components/navigation-drawers)**.",
"subheader": "Removes the top padding from `v-list-subheader` components. When used as a **String**, renders a subheader for you.",
"slim": "Reduces horizontal spacing for badges, icons, tooltips, and avatars within slim list items to create a more compact visual representation."
"slim": "Reduces horizontal spacing for badges, icons, tooltips, and avatars within slim list items to create a more compact visual representation.",
"collapseIcon": "Icon to display when the list item is expanded.",
"expandIcon": "Icon to display when the list item is collapsed."
}
}
2 changes: 1 addition & 1 deletion packages/docs/src/components/app/Toc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
</v-col>
<v-col
v-if="!user.disableAds && spot.spot"
v-if="(!user.disableAds || (user.showHouseAds && spot.spot.sponsor === 'Vuetify')) && spot.spot"
cols="12"
>
<a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<v-card
class="pa-4"
height="300px"
img="https://cdn.vuetifyjs.com/images/toolbar/map.jpg"
image="https://cdn.vuetifyjs.com/images/toolbar/map.jpg"
flat
>
<v-toolbar
Expand Down
1 change: 1 addition & 0 deletions packages/docs/src/pages/en/components/app-bars.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ The `v-app-bar` component has a variety of props that allow you to customize its
Available values:

- **hide**: The default slot area will shift up and hide as the user scrolls down. The extension slot remains visible.
- **fully-hide**: The entire app bar will hide as the user scrolls down.
- **collapse**: Shrink horizontally to a small bar in one corner.
- **elevate**: Add a drop shadow to the app bar when scrolling. Ignores `scroll-threshold`, will always be applied with any amount of scrolling.
- **fade-image**: Fade out the image as the user scrolls down.
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/pages/en/components/buttons.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The `v-btn` component replaces the standard html button with a material design t

<PageFeatures />

<VoPromotionsCardVuetify />
<VoPromotionsCardVuetify slug="vuetify-snips" />

## Usage

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/pages/en/components/cards.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ features:

<PageFeatures />

<VoPromotionsCardVuetify />
<VoPromotionsCardVuetify slug="vuetify-snips" />

## Usage

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/src/pages/en/introduction/why-vuetify.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Learn more about what Vuetify is, how to create an application from scratch, bro

<PageFeatures />

<VoPromotionsCardVuetify />
<VoPromotionsCardVuetify slug="vuetify-snips" />

## What is Vuetify?

Expand Down
2 changes: 1 addition & 1 deletion packages/vuetify/src/components/VAppBar/VAppBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { PropType } from 'vue'
import type { VToolbarSlots } from '@/components/VToolbar/VToolbar'

export const makeVAppBarProps = propsFactory({
scrollBehavior: String as PropType<'hide' | 'inverted' | 'collapse' | 'elevate' | 'fade-image' | (string & {})>,
scrollBehavior: String as PropType<'hide' | 'fully-hide' | 'inverted' | 'collapse' | 'elevate' | 'fade-image' | (string & {})>,
modelValue: {
type: Boolean,
default: true,
Expand Down
3 changes: 3 additions & 0 deletions packages/vuetify/src/components/VBtn/VBtn.sass
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
.v-icon
--v-icon-size-multiplier: #{calc(24/21)}

&.v-btn--block
min-width: 100%

.v-btn__loader
align-items: center
display: flex
Expand Down
7 changes: 4 additions & 3 deletions packages/vuetify/src/components/VDataTable/VDataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { provideDefaults } from '@/composables/defaults'
import { makeFilterProps, useFilter } from '@/composables/filter'

// Utilities
import { computed, toRef } from 'vue'
import { computed, toRef, toRefs } from 'vue'
import { genericComponent, propsFactory, useRender } from '@/util'

// Types
Expand Down Expand Up @@ -130,6 +130,7 @@ export const VDataTable = genericComponent<new <T extends readonly any[], V>(
const { groupBy } = createGroupBy(props)
const { sortBy, multiSort, mustSort } = createSort(props)
const { page, itemsPerPage } = createPagination(props)
const { disableSort } = toRefs(props)

const {
columns,
Expand All @@ -152,10 +153,10 @@ export const VDataTable = genericComponent<new <T extends readonly any[], V>(
})

const { toggleSort } = provideSort({ sortBy, multiSort, mustSort, page })
const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy })
const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy, disableSort })

const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, {
transform: item => item.columns,
transform: item => ({ ...item.raw, ...item.columns }),
sortFunctions,
sortRawFunctions,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { createSort, provideSort } from './composables/sort'
import { provideDefaults } from '@/composables/defaults'

// Utilities
import { computed, provide, toRef } from 'vue'
import { computed, provide, toRef, toRefs } from 'vue'
import { genericComponent, propsFactory, useRender } from '@/util'

// Types
Expand Down Expand Up @@ -69,6 +69,7 @@ export const VDataTableServer = genericComponent<new <T extends readonly any[],
const { groupBy } = createGroupBy(props)
const { sortBy, multiSort, mustSort } = createSort(props)
const { page, itemsPerPage } = createPagination(props)
const { disableSort } = toRefs(props)
const itemsLength = computed(() => parseInt(props.itemsLength, 10))

const { columns, headers } = createHeaders(props, {
Expand All @@ -81,7 +82,7 @@ export const VDataTableServer = genericComponent<new <T extends readonly any[],

const { toggleSort } = provideSort({ sortBy, multiSort, mustSort, page })

const { opened, isGroupOpen, toggleGroup, extractRows } = provideGroupBy({ groupBy, sortBy })
const { opened, isGroupOpen, toggleGroup, extractRows } = provideGroupBy({ groupBy, sortBy, disableSort })

const { pageCount, setItemsPerPage } = providePagination({ page, itemsPerPage, itemsLength })

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { makeFilterProps, useFilter } from '@/composables/filter'
import { makeVirtualProps, useVirtual } from '@/composables/virtual'

// Utilities
import { computed, shallowRef, toRef } from 'vue'
import { computed, shallowRef, toRef, toRefs } from 'vue'
import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'

// Types
Expand Down Expand Up @@ -85,6 +85,7 @@ export const VDataTableVirtual = genericComponent<new <T extends readonly any[],
setup (props, { attrs, slots }) {
const { groupBy } = createGroupBy(props)
const { sortBy, multiSort, mustSort } = createSort(props)
const { disableSort } = toRefs(props)

const {
columns,
Expand All @@ -106,10 +107,10 @@ export const VDataTableVirtual = genericComponent<new <T extends readonly any[],
})

const { toggleSort } = provideSort({ sortBy, multiSort, mustSort })
const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy })
const { sortByWithGroups, opened, extractRows, isGroupOpen, toggleGroup } = provideGroupBy({ groupBy, sortBy, disableSort })

const { sortedItems } = useSortedItems(props, filteredItems, sortByWithGroups, {
transform: item => item.columns,
transform: item => ({ ...item.raw, ...item.columns }),
sortFunctions,
sortRawFunctions,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const DESSERT_HEADERS = [
{ title: 'Carbs (g)', key: 'carbs' },
{ title: 'Protein (g)', key: 'protein' },
{ title: 'Iron (%)', key: 'iron' },
{ title: 'Group', key: 'group' },
]

const DESSERT_ITEMS = [
Expand All @@ -24,6 +25,7 @@ const DESSERT_ITEMS = [
carbs: 24,
protein: 4.0,
iron: '1%',
group: 1,
},
{
name: 'Ice cream sandwich',
Expand All @@ -32,6 +34,7 @@ const DESSERT_ITEMS = [
carbs: 37,
protein: 4.3,
iron: '1%',
group: 3,
},
{
name: 'Eclair',
Expand All @@ -40,6 +43,7 @@ const DESSERT_ITEMS = [
carbs: 23,
protein: 6.0,
iron: '7%',
group: 2,
},
{
name: 'Cupcake',
Expand All @@ -48,6 +52,7 @@ const DESSERT_ITEMS = [
carbs: 67,
protein: 4.3,
iron: '8%',
group: 2,
},
{
name: 'Gingerbread',
Expand All @@ -56,6 +61,7 @@ const DESSERT_ITEMS = [
carbs: 49,
protein: 3.9,
iron: '16%',
group: 3,
},
{
name: 'Jelly bean',
Expand All @@ -64,6 +70,7 @@ const DESSERT_ITEMS = [
carbs: 94,
protein: 0.0,
iron: '0%',
group: 1,
},
{
name: 'Lollipop',
Expand All @@ -72,6 +79,7 @@ const DESSERT_ITEMS = [
carbs: 98,
protein: 0,
iron: '2%',
group: 2,
},
{
name: 'Honeycomb',
Expand All @@ -80,6 +88,7 @@ const DESSERT_ITEMS = [
carbs: 87,
protein: 6.5,
iron: '45%',
group: 3,
},
{
name: 'Donut',
Expand All @@ -88,6 +97,7 @@ const DESSERT_ITEMS = [
carbs: 51,
protein: 4.9,
iron: '22%',
group: 3,
},
{
name: 'KitKat',
Expand All @@ -96,6 +106,7 @@ const DESSERT_ITEMS = [
carbs: 65,
protein: 7,
iron: '6%',
group: 1,
},
]

Expand Down Expand Up @@ -356,4 +367,92 @@ describe('VDataTable', () => {
cy.get('.v-data-table').find('h3').should('exist')
})
})

describe('sort', () => {
it('should sort by sortBy', () => {
cy.mount(() => (
<Application>
<VDataTable
items={ DESSERT_ITEMS }
headers={ DESSERT_HEADERS }
itemsPerPage={ 10 }
sortBy={[{ key: 'fat', order: 'asc' }]}
/>
</Application>
))
cy.get('thead .v-data-table__td').eq(2).should('have.class', 'v-data-table__th--sorted')
.get('tbody td:nth-child(3)').then(rows => {
const actualFat = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedFat = DESSERT_ITEMS.map(d => d.fat).sort((a, b) => a - b)
expect(actualFat).to.deep.equal(expectedFat)
})
cy.get('thead .v-data-table__td').eq(2).click()
.get('thead .v-data-table__td').eq(2).should('have.class', 'v-data-table__th--sorted')
.get('tbody td:nth-child(3)').then(rows => {
const actualFat = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedFat = DESSERT_ITEMS.map(d => d.fat).sort((a, b) => b - a)
expect(actualFat).to.deep.equal(expectedFat)
})
})

it('should sort by groupBy and sortBy', () => {
cy.mount(() => (
<Application>
<VDataTable
items={ DESSERT_ITEMS }
headers={ DESSERT_HEADERS }
itemsPerPage={ 10 }
groupBy={[{ key: 'group', order: 'desc' }]}
sortBy={[{ key: 'calories', order: 'desc' }]}
/>
</Application>
)).get('tr.v-data-table-group-header-row .v-data-table__td button + span').then(rows => {
const actualGroup = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedGroup = [...new Set(DESSERT_ITEMS.map(d => d.group))].sort((a, b) => b - a)
expect(actualGroup).to.deep.equal(expectedGroup)
}).get('.v-data-table-group-header-row button').eq(0).click()
.get('.v-data-table__tr td:nth-child(3)').then(rows => {
const actualCalories = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedCalories = DESSERT_ITEMS.filter(d => d.group === 3).map(d => d.calories).sort((a, b) => b - a)
expect(actualCalories).to.deep.equal(expectedCalories)
})
})

// https:/vuetifyjs/vuetify/issues/20046
it('should sort by groupBy while sort is disabled', () => {
cy.mount(() => (
<Application>
<VDataTable
items={ DESSERT_ITEMS }
headers={ DESSERT_HEADERS }
itemsPerPage={ 10 }
groupBy={[{ key: 'group', order: 'desc' }]}
sortBy={[{ key: 'calories', order: 'desc' }]}
disableSort
/>
</Application>
)).get('tr.v-data-table-group-header-row .v-data-table__td button + span').then(rows => {
const actualGroup = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedGroup = [...new Set(DESSERT_ITEMS.map(d => d.group))].sort((a, b) => b - a)
expect(actualGroup).to.deep.equal(expectedGroup)
}).get('.v-data-table-group-header-row button').eq(0).click()
.get('.v-data-table__tr td:nth-child(3)').then(rows => {
const actualCalories = Array.from(rows).map(row => {
return Number(row.textContent)
})
const expectedCalories = DESSERT_ITEMS.filter(d => d.group === 3).map(d => d.calories)
expect(actualCalories).to.deep.equal(expectedCalories)
})
})
})
})
10 changes: 7 additions & 3 deletions packages/vuetify/src/components/VDataTable/composables/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,19 @@ export function createGroupBy (props: GroupProps) {
return { groupBy }
}

export function provideGroupBy (options: { groupBy: Ref<readonly SortItem[]>, sortBy: Ref<readonly SortItem[]> }) {
const { groupBy, sortBy } = options
export function provideGroupBy (options: {
groupBy: Ref<readonly SortItem[]>
sortBy: Ref<readonly SortItem[]>
disableSort?: Ref<boolean>
}) {
const { disableSort, groupBy, sortBy } = options
const opened = ref(new Set<string>())

const sortByWithGroups = computed(() => {
return groupBy.value.map<SortItem>(val => ({
...val,
order: val.order ?? false,
})).concat(sortBy.value)
})).concat(disableSort?.value ? [] : sortBy.value)
})

function isGroupOpen (group: Group) {
Expand Down
Loading

0 comments on commit d85a1ae

Please sign in to comment.