@@ -5,34 +5,24 @@ import { useMutation } from '@tanstack/react-query'
5
5
6
6
import PlusIcon from '#/assets/plus.svg'
7
7
import Trash2Icon from '#/assets/trash2.svg'
8
-
9
- import { backendMutationOptions , useBackendQuery } from '#/hooks/backendHooks'
10
-
11
- import * as modalProvider from '#/providers/ModalProvider'
12
- import * as textProvider from '#/providers/TextProvider'
13
-
14
8
import * as ariaComponents from '#/components/AriaComponents'
15
9
import Label from '#/components/dashboard/Label'
16
10
import FocusArea from '#/components/styled/FocusArea'
17
11
import FocusRing from '#/components/styled/FocusRing'
18
12
import SvgMask from '#/components/SvgMask'
19
-
13
+ import AssetEventType from '#/events/AssetEventType'
14
+ import { backendMutationOptions , useBackendQuery } from '#/hooks/backendHooks'
15
+ import { useDispatchAssetEvent } from '#/layouts/AssetsTable/EventListProvider'
20
16
import ConfirmDeleteModal from '#/modals/ConfirmDeleteModal'
21
17
import DragModal from '#/modals/DragModal'
22
18
import NewLabelModal from '#/modals/NewLabelModal'
23
-
19
+ import * as modalProvider from '#/providers/ModalProvider'
20
+ import * as textProvider from '#/providers/TextProvider'
24
21
import type Backend from '#/services/Backend'
25
-
26
- import AssetEventType from '#/events/AssetEventType'
27
- import { useDispatchAssetEvent } from '#/layouts/AssetsTable/EventListProvider'
28
22
import * as array from '#/utilities/array'
29
23
import type AssetQuery from '#/utilities/AssetQuery'
30
24
import * as drag from '#/utilities/drag'
31
25
32
- // ==============
33
- // === Labels ===
34
- // ==============
35
-
36
26
/** Props for a {@link Labels}. */
37
27
export interface LabelsProps {
38
28
readonly backend : Backend
@@ -61,96 +51,98 @@ export default function Labels(props: LabelsProps) {
61
51
return (
62
52
< FocusArea direction = "vertical" >
63
53
{ ( innerProps ) => (
64
- < div
65
- data-testid = "labels"
66
- className = "flex flex-1 flex-col items-start gap-4 overflow-auto"
67
- { ...innerProps }
68
- >
69
- < ariaComponents . Text variant = "subtitle" className = "px-2 font-bold" >
70
- { getText ( 'labels' ) }
71
- </ ariaComponents . Text >
54
+ < div className = "flex flex-1 flex-col overflow-auto" >
72
55
< div
73
- data-testid = "labels-list "
74
- aria-label = { getText ( 'labelsListLabel' ) }
75
- className = "flex flex-1 flex-col items-start gap-labels overflow-auto"
56
+ data-testid = "labels"
57
+ className = "flex flex-col items-start gap-4 overflow-auto"
58
+ { ... innerProps }
76
59
>
77
- { labels . map ( ( label ) => {
78
- const negated = currentNegativeLabels . some ( ( term ) =>
79
- array . shallowEqual ( term , [ label . value ] ) ,
80
- )
81
- return (
82
- < div key = { label . id } className = "group relative flex items-center gap-label-icons" >
83
- < Label
84
- draggable = { draggable }
85
- color = { label . color }
86
- active = {
87
- negated ||
88
- currentLabels . some ( ( term ) => array . shallowEqual ( term , [ label . value ] ) )
89
- }
90
- negated = { negated }
91
- onPress = { ( event ) => {
92
- setQuery ( ( oldQuery ) =>
93
- oldQuery . withToggled (
94
- 'labels' ,
95
- 'negativeLabels' ,
96
- label . value ,
97
- event . shiftKey ,
98
- ) ,
99
- )
100
- } }
101
- onDragStart = { ( event ) => {
102
- drag . setDragImageToBlank ( event )
103
- const payload : drag . LabelsDragPayload = new Set ( [ label . value ] )
104
- drag . LABELS . bind ( event , payload )
105
- setModal (
106
- < DragModal
107
- event = { event }
108
- onDragEnd = { ( ) => {
109
- drag . LABELS . unbind ( payload )
60
+ < ariaComponents . Text variant = "subtitle" className = "px-2 font-bold" >
61
+ { getText ( 'labels' ) }
62
+ </ ariaComponents . Text >
63
+ < div
64
+ data-testid = "labels-list"
65
+ aria-label = { getText ( 'labelsListLabel' ) }
66
+ className = "flex flex-1 flex-col items-start gap-labels overflow-auto"
67
+ >
68
+ { labels . map ( ( label ) => {
69
+ const negated = currentNegativeLabels . some ( ( term ) =>
70
+ array . shallowEqual ( term , [ label . value ] ) ,
71
+ )
72
+ return (
73
+ < div key = { label . id } className = "group relative flex items-center gap-label-icons" >
74
+ < Label
75
+ draggable = { draggable }
76
+ color = { label . color }
77
+ active = {
78
+ negated ||
79
+ currentLabels . some ( ( term ) => array . shallowEqual ( term , [ label . value ] ) )
80
+ }
81
+ negated = { negated }
82
+ onPress = { ( event ) => {
83
+ setQuery ( ( oldQuery ) =>
84
+ oldQuery . withToggled (
85
+ 'labels' ,
86
+ 'negativeLabels' ,
87
+ label . value ,
88
+ event . shiftKey ,
89
+ ) ,
90
+ )
91
+ } }
92
+ onDragStart = { ( event ) => {
93
+ drag . setDragImageToBlank ( event )
94
+ const payload : drag . LabelsDragPayload = new Set ( [ label . value ] )
95
+ drag . LABELS . bind ( event , payload )
96
+ setModal (
97
+ < DragModal
98
+ event = { event }
99
+ onDragEnd = { ( ) => {
100
+ drag . LABELS . unbind ( payload )
101
+ } }
102
+ >
103
+ < Label active color = { label . color } onPress = { ( ) => { } } >
104
+ { label . value }
105
+ </ Label >
106
+ </ DragModal > ,
107
+ )
108
+ } }
109
+ >
110
+ { label . value }
111
+ </ Label >
112
+ < FocusRing placement = "after" >
113
+ < ariaComponents . DialogTrigger >
114
+ < ariaComponents . Button
115
+ variant = "icon"
116
+ icon = { Trash2Icon }
117
+ aria-label = { getText ( 'delete' ) }
118
+ tooltipPlacement = "right"
119
+ className = "relative flex size-4 text-delete opacity-0 transition-all after:absolute after:-inset-1 after:rounded-button-focus-ring group-has-[[data-focus-visible]]:active group-hover:active"
120
+ />
121
+ < ConfirmDeleteModal
122
+ actionText = { getText ( 'deleteLabelActionText' , label . value ) }
123
+ doDelete = { ( ) => {
124
+ deleteTag ( [ label . id , label . value ] )
110
125
} }
111
- >
112
- < Label active color = { label . color } onPress = { ( ) => { } } >
113
- { label . value }
114
- </ Label >
115
- </ DragModal > ,
116
- )
117
- } }
118
- >
119
- { label . value }
120
- </ Label >
121
- < FocusRing placement = "after" >
122
- < ariaComponents . DialogTrigger >
123
- < ariaComponents . Button
124
- variant = "icon"
125
- icon = { Trash2Icon }
126
- aria-label = { getText ( 'delete' ) }
127
- tooltipPlacement = "right"
128
- className = "relative flex size-4 text-delete opacity-0 transition-all after:absolute after:-inset-1 after:rounded-button-focus-ring group-has-[[data-focus-visible]]:active group-hover:active"
129
- />
130
- < ConfirmDeleteModal
131
- actionText = { getText ( 'deleteLabelActionText' , label . value ) }
132
- doDelete = { ( ) => {
133
- deleteTag ( [ label . id , label . value ] )
134
- } }
135
- />
136
- </ ariaComponents . DialogTrigger >
137
- </ FocusRing >
138
- </ div >
139
- )
140
- } ) }
141
- < ariaComponents . DialogTrigger >
142
- < ariaComponents . Button
143
- size = "xsmall"
144
- variant = "outline"
145
- className = "pl-1 pr-2"
146
- /* eslint-disable-next-line no-restricted-syntax */
147
- icon = { < SvgMask src = { PlusIcon } alt = "" className = "ml-auto size-[8px]" /> }
148
- >
149
- { getText ( 'newLabelButtonLabel' ) }
150
- </ ariaComponents . Button >
151
- < NewLabelModal backend = { backend } />
152
- </ ariaComponents . DialogTrigger >
126
+ />
127
+ </ ariaComponents . DialogTrigger >
128
+ </ FocusRing >
129
+ </ div >
130
+ )
131
+ } ) }
132
+ </ div >
153
133
</ div >
134
+ < ariaComponents . DialogTrigger >
135
+ < ariaComponents . Button
136
+ size = "xsmall"
137
+ variant = "outline"
138
+ className = "mt-1 self-start pl-1 pr-2"
139
+ /* eslint-disable-next-line no-restricted-syntax */
140
+ icon = { < SvgMask src = { PlusIcon } alt = "" className = "ml-auto size-[8px]" /> }
141
+ >
142
+ { getText ( 'newLabelButtonLabel' ) }
143
+ </ ariaComponents . Button >
144
+ < NewLabelModal backend = { backend } />
145
+ </ ariaComponents . DialogTrigger >
154
146
</ div >
155
147
) }
156
148
</ FocusArea >
0 commit comments