Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(VDataTable): add mobile view #19431

Merged
merged 79 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
bcbe2e1
add mobile thead holder for sortby select
webdevnerdstuff Mar 15, 2024
3b205a4
add mobile items
webdevnerdstuff Mar 16, 2024
aee39ee
update nesting classes
webdevnerdstuff Mar 16, 2024
699dc6e
update mobile style and organize some nested elements
webdevnerdstuff Mar 17, 2024
5dbc552
change classname
webdevnerdstuff Mar 17, 2024
8ceee42
move mobile view to be more streamline and reduce duplication
webdevnerdstuff Mar 17, 2024
76b3a0f
change class and remove unused prop
webdevnerdstuff Mar 17, 2024
34d27a7
add mobileView type
webdevnerdstuff Mar 17, 2024
9fcdb04
fix mobileView when no prop is set by user
webdevnerdstuff Mar 17, 2024
ce28ed6
add mobileView
webdevnerdstuff Mar 17, 2024
895a4b9
update style of expanded row
webdevnerdstuff Mar 17, 2024
c586bba
add align left to mobile title col
webdevnerdstuff Mar 17, 2024
4fc420f
change mobile header to empty for now
webdevnerdstuff Mar 17, 2024
f7cd478
add vselect to header column
webdevnerdstuff Mar 18, 2024
106e40f
Add sort by
webdevnerdstuff Mar 19, 2024
73bdb28
fix formatting
webdevnerdstuff Mar 19, 2024
aefd678
add mobile footer styles
webdevnerdstuff Mar 19, 2024
e4ac43c
add slots for mobile view
webdevnerdstuff Mar 19, 2024
bbc3ebf
change mobileView prop to mobile
webdevnerdstuff Mar 19, 2024
248f314
fix mobile to default to mobile if undefined
webdevnerdstuff Mar 19, 2024
46f3832
fix styles
webdevnerdstuff Mar 20, 2024
ae33f25
fix styles
webdevnerdstuff Mar 20, 2024
56d2f65
resolve merge conflicts
webdevnerdstuff Apr 24, 2024
0f92d10
fix indentation
webdevnerdstuff Apr 24, 2024
ca01dbf
update viewportWidth to 1280
webdevnerdstuff Apr 25, 2024
a26479c
change default mobile breakpoint to smAndDown
webdevnerdstuff Apr 25, 2024
e540446
add viewport for horizontal scroll
webdevnerdstuff Apr 25, 2024
8d8cda8
Removed temp markup
webdevnerdstuff Apr 25, 2024
a748f0d
Merge branch 'dev' into feat/data-table-mobile-view
webdevnerdstuff Apr 25, 2024
dacb102
Added mobile prop api description for vdatatable
cjhudson101 Apr 26, 2024
5067592
Merge pull request #1 from cjhudson101/feat/data-table-mobile-view
webdevnerdstuff Apr 26, 2024
aacca8b
Update packages/vuetify/src/components/VDataTable/VDataTable.tsx
webdevnerdstuff Apr 26, 2024
501dbcd
Update packages/vuetify/src/components/VDataTable/VDataTable.tsx
webdevnerdstuff Apr 26, 2024
3bfd340
Update packages/vuetify/src/components/VDataTable/VDataTableColumn.tsx
webdevnerdstuff Apr 26, 2024
3c38443
Update packages/vuetify/src/components/VDataTable/VDataTable.tsx
webdevnerdstuff Apr 26, 2024
369ba9a
change to use sass variables
webdevnerdstuff Apr 26, 2024
63a824e
add parens
webdevnerdstuff Apr 26, 2024
c5bf078
remove utility class
webdevnerdstuff Apr 26, 2024
0f1980b
change sort icon to use color classes using sass variables
webdevnerdstuff Apr 26, 2024
e87c9fc
remove color prop
webdevnerdstuff Apr 26, 2024
3194d90
changed text to useLocale
webdevnerdstuff Apr 26, 2024
1d56e92
change to use makeDisplayProps
webdevnerdstuff Apr 26, 2024
1a366a6
fix default mobileView
webdevnerdstuff Apr 26, 2024
1c46636
add mobile prop
webdevnerdstuff Apr 26, 2024
7cda61b
remove console logs
webdevnerdstuff Apr 26, 2024
50e1ed2
chore(VDataTable): revert import ordering changes
johnleider Apr 26, 2024
a4ab6f8
chore(VDataTable): implement display composable
johnleider Apr 26, 2024
190fa02
chore(VDataTable): remove mobile prop language
johnleider Apr 26, 2024
b9ef5dd
chore(VDatatTableVirtual): update useDisplay consumption
johnleider Apr 26, 2024
ad3445e
chore(VDataTableServer): change how useDisplay is consumed
johnleider Apr 26, 2024
1b97f24
chore(VDataTable): remove mobileBreakpoint from slot props
johnleider Apr 26, 2024
2e74db0
feat(display): add explicit prop that overrides mobile
johnleider Apr 26, 2024
b38ac2c
chore(VDataTable): revert prop spread change
johnleider Apr 26, 2024
8a0e060
fix(VDataTableRow/Rows/Headers): reimplement display composable
johnleider Apr 26, 2024
b63f067
fix(VDataTableHeaders): remove utility class
johnleider Apr 26, 2024
cf2f3f2
fix(VDataTableRow): incorrectly applying mobile class
johnleider Apr 26, 2024
cfb97a5
Updated api desc for mobileBreakpoint prop
cjhudson101 Apr 26, 2024
46e54d7
resolved merge conflict
cjhudson101 Apr 26, 2024
a332868
chore(VDataTableRows): remove unused dep
johnleider Apr 26, 2024
c2ec5f0
merge from origin
cjhudson101 Apr 26, 2024
976dd4a
Update api descriptions for mobile display
cjhudson101 Apr 26, 2024
08ab749
chore(VDatatTable/display.json): adjust language
johnleider Apr 26, 2024
cd9eed1
chore(VDataTableRow): revert indentation change
johnleider Apr 26, 2024
0332323
fix(VDataTableRow): use explicit mobile value in checks
johnleider Apr 26, 2024
2f6c483
revert(VDatatTableRows): remove headerProps
johnleider Apr 26, 2024
ff65eb0
chore(VDataTableRow): clean-up template code
johnleider Apr 26, 2024
9ba7927
chore(VDataTableRow): move VDataTableColumn import location
johnleider Apr 26, 2024
bb7d8dc
chore to remove duplicated styles missed in a merge
webdevnerdstuff Apr 26, 2024
330eb5d
revert(VDataTable): revert unrelated changes to sass
johnleider Apr 26, 2024
a941d19
chore: remove dev code
johnleider Apr 26, 2024
4e33cf7
chore(VDataTable): adjust mobile styles
johnleider Apr 26, 2024
1708e5e
Merge branch 'dev' into feat/data-table-mobile-view
johnleider Apr 27, 2024
8d40f04
revert: remove local usage of useDisplay in all tables
johnleider Apr 27, 2024
0a95bfc
chore(VDataTableRow): revert columnKey change
johnleider Apr 27, 2024
e40d930
refactor(VDataTableRow): update how styles are applied for mobile
johnleider Apr 27, 2024
dd2cb96
chore: code clean-up
johnleider Apr 27, 2024
7f29061
chore: fix test
johnleider Apr 27, 2024
9c70f65
changed checkbox to be end aligned
webdevnerdstuff Apr 28, 2024
1d206d5
feat(VDataTableHeaders): add support for select all
johnleider Apr 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/api-generator/src/locale/en/VDataTable.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"itemClass": "Property on supplied `items` that contains item's row class or function that takes an item as an argument and returns the class of corresponding row.",
"itemsPerPage": "Changes how many items per page should be visible. Can be used with `.sync` modifier. Setting this prop to `-1` will display all items on the page.",
"locale": "Sets the locale used for sorting. This is passed into [`Intl.Collator()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator) in the default `customSort` function.",
"mobileBreakpoint": "Used to set when to toggle between regular table and mobile view.",
"multiSort": "If `true` then one can sort on multiple properties.",
"mustSort": "If `true` then one can not disable sorting, it will always switch between ascending and descending.",
"page": "The current displayed page number (1-indexed).",
Expand Down
3 changes: 2 additions & 1 deletion packages/api-generator/src/locale/en/display.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"props": {
"mobileBreakpoint": "Sets the designated mobile breakpoint for the component."
"mobile": "Explicitly designate as a mobile display configuration.",
"mobileBreakpoint": "Overrides the display configuration default."
}
}
35 changes: 34 additions & 1 deletion packages/vuetify/src/components/VDataTable/VDataTable.sass
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
align-items: center

> th.v-data-table__th--fixed
position: sticky
position: sticky

> th.v-data-table__th--sortable:hover
cursor: pointer
Expand Down Expand Up @@ -126,3 +126,36 @@
.v-data-table-rows-loading,
.v-data-table-rows-no-data
text-align: center

.v-data-table__tr--mobile
> .v-data-table__td--expanded-row
grid-template-columns: 0
justify-content: center

> .v-data-table__td--select-row
grid-template-columns: 0
justify-content: end

> td
align-items: center
column-gap: 4px
display: grid
grid-template-columns: repeat(2, 1fr)
min-height: var(--v-table-row-height)

&:not(:last-child)
border-bottom: 0 !important

.v-data-table__td-title
font-weight: bold
text-align: left

.v-data-table__td-value
text-align: right

.v-data-table__td
&-sort-icon
color: $data-table-header-mobile-chip-icon-color

&-active
color: $data-table-header-mobile-chip-icon-color-active
42 changes: 21 additions & 21 deletions packages/vuetify/src/components/VDataTable/VDataTableFooter.sass
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@

@include tools.layer('components')
.v-data-table-footer
display: flex
align-items: center
display: flex
flex-wrap: wrap
padding: $data-table-footer-padding
justify-content: flex-end
padding: $data-table-footer-padding

.v-data-table-footer__items-per-page
display: flex
align-items: center
justify-content: center
&__items-per-page
align-items: center
display: flex
justify-content: center

> span
padding-inline-end: $data-table-footer-items-per-page-padding
> span
padding-inline-end: $data-table-footer-items-per-page-padding

> .v-select
width: $data-table-footer-select-width
> .v-select
width: $data-table-footer-select-width

.v-data-table-footer__info
display: flex
justify-content: flex-end
min-width: $data-table-footer-info-min-width
padding: $data-table-footer-info-padding
&__info
display: flex
justify-content: flex-end
min-width: $data-table-footer-info-min-width
padding: $data-table-footer-info-padding

.v-data-table-footer__pagination
display: flex
align-items: center
margin-inline-start: $data-table-footer-pagination-margin-inline-start
&__paginationz
align-items: center
display: flex
margin-inline-start: $data-table-footer-pagination-margin-inline-start

.v-data-table-footer__page
padding: 0 8px
&__page
padding: 0 8px
92 changes: 87 additions & 5 deletions packages/vuetify/src/components/VDataTable/VDataTableHeaders.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
// Components
import { VDataTableColumn } from './VDataTableColumn'
import { VCheckboxBtn } from '@/components/VCheckbox'
import { VChip } from '@/components/VChip'
import { VIcon } from '@/components/VIcon'
import { VSelect } from '@/components/VSelect'

// Composables
import { useHeaders } from './composables/headers'
import { useSelection } from './composables/select'
import { useSort } from './composables/sort'
import { useBackgroundColor } from '@/composables/color'
import { makeDisplayProps, useDisplay } from '@/composables/display'
import { IconValue } from '@/composables/icons'
import { LoaderSlot, makeLoaderProps, useLoader } from '@/composables/loader'
import { useLocale } from '@/composables/locale'

// Utilities
import { computed, mergeProps } from 'vue'
Expand All @@ -20,6 +24,7 @@ import type { CSSProperties, PropType, UnwrapRef } from 'vue'
import type { provideSelection } from './composables/select'
import type { provideSort } from './composables/sort'
import type { InternalDataTableHeader } from './types'
import type { ItemProps } from '@/composables/list-items'
import type { LoaderSlotProps } from '@/composables/loader'

export type HeadersSlotProps = {
Expand All @@ -34,7 +39,7 @@ export type HeadersSlotProps = {
isSorted: ReturnType<typeof provideSort>['isSorted']
}

type VDataTableHeaderCellColumnSlotProps = {
export type VDataTableHeaderCellColumnSlotProps = {
column: InternalDataTableHeader
selectAll: ReturnType<typeof provideSelection>['selectAll']
isSorted: ReturnType<typeof provideSort>['isSorted']
Expand Down Expand Up @@ -68,6 +73,7 @@ export const makeVDataTableHeadersProps = propsFactory({
type: Object as PropType<Record<string, any>>,
},

...makeDisplayProps(),
...makeLoaderProps(),
}, 'VDataTableHeaders')

Expand All @@ -77,6 +83,7 @@ export const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({
props: makeVDataTableHeadersProps(),

setup (props, { slots }) {
const { t } = useLocale()
const { toggleSort, sortBy, isSorted } = useSort()
const { someSelected, allSelected, selectAll, showSelectAll } = useSelection()
const { columns, headers } = useHeaders()
Expand All @@ -102,6 +109,8 @@ export const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({

const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(props, 'color')

const { displayClasses, mobile } = useDisplay(props)

const slotProps = computed(() => ({
headers: headers.value,
columns: columns.value,
Expand All @@ -114,6 +123,15 @@ export const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({
getSortIcon,
} satisfies HeadersSlotProps))

const headerCellClasses = computed(() => ([
'v-data-table__th',
{
'v-data-table__th--sticky': props.sticky,
},
displayClasses.value,
loaderClasses.value,
]))

const VDataTableHeaderCell = ({ column, x, y }: { column: InternalDataTableHeader, x: number, y: number }) => {
const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand'
const headerProps = mergeProps(props.headerProps ?? {}, column.headerProps ?? {})
Expand All @@ -123,14 +141,12 @@ export const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({
tag="th"
align={ column.align }
class={[
'v-data-table__th',
{
'v-data-table__th--sortable': column.sortable,
'v-data-table__th--sorted': isSorted(column),
'v-data-table__th--fixed': column.fixed,
'v-data-table__th--sticky': props.sticky,
},
loaderClasses.value,
...headerCellClasses.value,
]}
style={{
width: convertToUnit(column.width),
Expand Down Expand Up @@ -203,8 +219,74 @@ export const VDataTableHeaders = genericComponent<VDataTableHeadersSlots>()({
)
}

useRender(() => {
const VDataTableMobileHeaderCell = () => {
const headerProps = mergeProps(props.headerProps ?? {} ?? {})

const displayItems = computed<ItemProps['items']>(() => {
return columns.value.filter(column => column?.sortable)
})

const appendIcon = computed(() => {
return allSelected.value ? '$checkboxOn' : someSelected.value ? '$checkboxIndeterminate' : '$checkboxOff'
})

return (
<VDataTableColumn
tag="th"
class={[
...headerCellClasses.value,
]}
colspan={ headers.value.length + 1 }
{ ...headerProps }
>
<div class="v-data-table-header__content">
<VSelect
chips
class="v-data-table__td-sort-select"
clearable
density="default"
items={ displayItems.value }
label={ t('$vuetify.dataTable.sortBy') }
multiple={ props.multiSort }
variant="underlined"
onClick:clear={ () => sortBy.value = [] }
appendIcon={ appendIcon.value }
onClick:append={ () => selectAll(!allSelected.value) }
>
{{
...slots,
chip: props => (
<VChip
onClick={ props.item.raw?.sortable ? () => toggleSort(props.item.raw) : undefined }
onMousedown={ (e: MouseEvent) => {
e.preventDefault()
e.stopPropagation()
}}
>
{ props.item.title }
<VIcon
class={[
'v-data-table__td-sort-icon',
isSorted(props.item.raw) && 'v-data-table__td-sort-icon-active',
]}
icon={ getSortIcon(props.item.raw) }
size="small"
/>
</VChip>
),
}}
</VSelect>
</div>
</VDataTableColumn>
)
}

useRender(() => {
return mobile.value ? (
<tr>
<VDataTableMobileHeaderCell />
</tr>
) : (
<>
{ slots.headers
? slots.headers(slotProps.value)
Expand Down
Loading
Loading