@redseed/redseed-ui-vue3 8.33.2 → 8.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -108,12 +108,6 @@ function handleMoreActionsClick() {
|
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
</div>
|
|
111
|
-
<!-- Badge slot, optional -->
|
|
112
|
-
<div class="rsui-card-header__badge"
|
|
113
|
-
v-if="showBadge && $slots.badge"
|
|
114
|
-
>
|
|
115
|
-
<slot name="badge"></slot>
|
|
116
|
-
</div>
|
|
117
111
|
<!-- Subtitle slot, optional -->
|
|
118
112
|
<div :class="[
|
|
119
113
|
'rsui-card-header__subtitle',
|
|
@@ -125,6 +119,13 @@ function handleMoreActionsClick() {
|
|
|
125
119
|
>
|
|
126
120
|
<slot name="subtitle"></slot>
|
|
127
121
|
</div>
|
|
122
|
+
|
|
123
|
+
<!-- Badge slot, optional -->
|
|
124
|
+
<div class="rsui-card-header__badge"
|
|
125
|
+
v-if="showBadge && $slots.badge"
|
|
126
|
+
>
|
|
127
|
+
<slot name="badge"></slot>
|
|
128
|
+
</div>
|
|
128
129
|
</div>
|
|
129
130
|
|
|
130
131
|
<!-- Actions slot, optional -->
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, watch } from 'vue'
|
|
2
|
+
import { ref, watch, computed } from 'vue'
|
|
3
3
|
import FormFieldSlot from './FormFieldSlot.vue'
|
|
4
4
|
import { CheckIcon } from '@heroicons/vue/24/outline'
|
|
5
5
|
import { useFormFieldA11y } from '../../composables/useFormFieldA11y.js'
|
|
@@ -8,6 +8,22 @@ defineOptions({
|
|
|
8
8
|
inheritAttrs: false,
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
+
const props = defineProps({
|
|
12
|
+
// Smaller variants for dense surfaces. Default (no flag) is the 24px size;
|
|
13
|
+
// only the smallest enabled flag applies (xs wins over sm).
|
|
14
|
+
sm: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: false,
|
|
17
|
+
},
|
|
18
|
+
xs: {
|
|
19
|
+
type: Boolean,
|
|
20
|
+
default: false,
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Resolve to a single size modifier so only one applies at a time.
|
|
25
|
+
const size = computed(() => props.xs ? 'xs' : props.sm ? 'sm' : null)
|
|
26
|
+
|
|
11
27
|
const model = defineModel()
|
|
12
28
|
|
|
13
29
|
const checked = ref(false)
|
|
@@ -35,7 +51,7 @@ function check(event) {
|
|
|
35
51
|
>
|
|
36
52
|
<template #label>
|
|
37
53
|
<div class="rsui-form-field-checkbox__checkbox">
|
|
38
|
-
<div class="rsui-form-field-checkbox__check">
|
|
54
|
+
<div :class="['rsui-form-field-checkbox__check', size && `rsui-form-field-checkbox__check--${size}`]">
|
|
39
55
|
<CheckIcon v-if="checked" aria-hidden="true"></CheckIcon>
|
|
40
56
|
<input
|
|
41
57
|
:checked="checked"
|
|
@@ -52,7 +68,7 @@ function check(event) {
|
|
|
52
68
|
>
|
|
53
69
|
</div>
|
|
54
70
|
<div v-if="$slots.label"
|
|
55
|
-
class="rsui-form-field-checkbox__label"
|
|
71
|
+
:class="['rsui-form-field-checkbox__label', size && `rsui-form-field-checkbox__label--${size}`]"
|
|
56
72
|
>
|
|
57
73
|
<slot name="label"></slot>
|
|
58
74
|
<span
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import DropdownMenu from '../DropdownMenu/DropdownMenu.vue'
|
|
4
|
+
import ButtonSecondary from '../Button/ButtonSecondary.vue'
|
|
4
5
|
import ButtonTertiary from '../Button/ButtonTertiary.vue'
|
|
5
6
|
import Icon from '../Icon/Icon.vue'
|
|
6
|
-
import
|
|
7
|
+
import FormFieldCheckbox from '../FormField/FormFieldCheckbox.vue'
|
|
8
|
+
import { AdjustmentsHorizontalIcon } from '@heroicons/vue/24/outline'
|
|
7
9
|
|
|
8
10
|
const props = defineProps({
|
|
9
11
|
columns: {
|
|
@@ -19,9 +21,22 @@ const props = defineProps({
|
|
|
19
21
|
|
|
20
22
|
const visibleKeys = defineModel('visibleKeys', { type: Array, required: true })
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
// Columns shown in the picker — `pickerHidden` columns are omitted entirely.
|
|
25
|
+
const pickerColumns = computed(() => props.columns.filter(c => !c.pickerHidden))
|
|
26
|
+
|
|
27
|
+
// Required columns are always rendered by the table (Table.vue), so the picker
|
|
28
|
+
// treats them as visible regardless of `visibleKeys` — keeps the locked-on
|
|
29
|
+
// checkbox checked and the count consistent even when a controlled
|
|
30
|
+
// `visibleKeys` omits the required key.
|
|
31
|
+
const isVisible = (key) => {
|
|
32
|
+
const column = props.columns.find(c => c.key === key)
|
|
33
|
+
if (column?.required) return true
|
|
34
|
+
return visibleKeys.value.includes(key)
|
|
35
|
+
}
|
|
23
36
|
|
|
24
37
|
function toggle(key) {
|
|
38
|
+
const column = props.columns.find(c => c.key === key)
|
|
39
|
+
if (column?.required) return
|
|
25
40
|
if (visibleKeys.value.includes(key)) {
|
|
26
41
|
visibleKeys.value = visibleKeys.value.filter(k => k !== key)
|
|
27
42
|
} else {
|
|
@@ -29,37 +44,53 @@ function toggle(key) {
|
|
|
29
44
|
}
|
|
30
45
|
}
|
|
31
46
|
|
|
32
|
-
const visibleCount = computed(() =>
|
|
33
|
-
const totalCount = computed(() =>
|
|
47
|
+
const visibleCount = computed(() => pickerColumns.value.filter(c => isVisible(c.key)).length)
|
|
48
|
+
const totalCount = computed(() => pickerColumns.value.length)
|
|
34
49
|
</script>
|
|
35
50
|
|
|
36
51
|
<template>
|
|
37
52
|
<DropdownMenu right class="rsui-column-picker">
|
|
38
53
|
<template #trigger="{ open, isOpen }">
|
|
39
|
-
<ButtonTertiary :aria-expanded="isOpen"
|
|
54
|
+
<ButtonTertiary :aria-expanded="isOpen"
|
|
55
|
+
class="rsui-column-picker__trigger--desktop"
|
|
56
|
+
@click="open"
|
|
57
|
+
>
|
|
40
58
|
<Icon sm><AdjustmentsHorizontalIcon /></Icon>
|
|
41
59
|
{{ label }}
|
|
42
60
|
<span class="rsui-column-picker__count">{{ visibleCount }}/{{ totalCount }}</span>
|
|
43
61
|
</ButtonTertiary>
|
|
62
|
+
<ButtonSecondary :aria-expanded="isOpen"
|
|
63
|
+
class="rsui-column-picker__trigger--mobile"
|
|
64
|
+
@click="open"
|
|
65
|
+
>
|
|
66
|
+
<Icon sm><AdjustmentsHorizontalIcon /></Icon>
|
|
67
|
+
{{ label }}
|
|
68
|
+
<span class="rsui-column-picker__count">{{ visibleCount }}/{{ totalCount }}</span>
|
|
69
|
+
</ButtonSecondary>
|
|
44
70
|
</template>
|
|
45
71
|
|
|
46
72
|
<ul class="rsui-column-picker__list" role="none">
|
|
47
|
-
<li v-for="column in
|
|
73
|
+
<li v-for="column in pickerColumns"
|
|
48
74
|
:key="column.key"
|
|
49
|
-
class="rsui-column-picker__item"
|
|
75
|
+
:class="['rsui-column-picker__item', { 'rsui-column-picker__item--disabled': column.required }]"
|
|
50
76
|
role="menuitemcheckbox"
|
|
51
77
|
:aria-checked="isVisible(column.key)"
|
|
52
|
-
|
|
78
|
+
:aria-disabled="column.required ? 'true' : undefined"
|
|
79
|
+
:aria-label="column.name || column.key"
|
|
80
|
+
:tabindex="column.required ? -1 : 0"
|
|
53
81
|
@click.stop="toggle(column.key)"
|
|
54
82
|
@keydown.enter.self.prevent="toggle(column.key)"
|
|
55
83
|
@keydown.space.self.prevent="toggle(column.key)"
|
|
56
84
|
>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
<!-- The row owns the click, keyboard and aria state; this rsui
|
|
86
|
+
checkbox is purely presentational, controlled by the row's
|
|
87
|
+
visible state. `inert` keeps its input out of the tab order
|
|
88
|
+
and a11y tree (the row carries the label via aria-label). -->
|
|
89
|
+
<span class="rsui-column-picker__checkbox" inert>
|
|
90
|
+
<FormFieldCheckbox sm :disabled="column.required" :model-value="isVisible(column.key)">
|
|
91
|
+
<template #label>{{ column.name || column.key }}</template>
|
|
92
|
+
</FormFieldCheckbox>
|
|
61
93
|
</span>
|
|
62
|
-
<span class="rsui-column-picker__label">{{ column.name || column.key }}</span>
|
|
63
94
|
</li>
|
|
64
95
|
</ul>
|
|
65
96
|
</DropdownMenu>
|
|
@@ -81,7 +81,11 @@ const effectiveVisibleKeys = computed({
|
|
|
81
81
|
})
|
|
82
82
|
|
|
83
83
|
const visibleColumns = computed(() => {
|
|
84
|
-
return props.columns.filter(column =>
|
|
84
|
+
return props.columns.filter(column => {
|
|
85
|
+
// `required` and `pickerHidden` columns are always rendered, regardless of visibleKeys.
|
|
86
|
+
if (column.required || column.pickerHidden) return true
|
|
87
|
+
return effectiveVisibleKeys.value.includes(column.key)
|
|
88
|
+
})
|
|
85
89
|
})
|
|
86
90
|
</script>
|
|
87
91
|
|