collab_panel.ts

  1import {
  2    background,
  3    border,
  4    border_color,
  5    foreground,
  6    text,
  7} from "./components"
  8import { interactive, toggleable } from "../element"
  9import { useTheme } from "../theme"
 10import collab_modals from "./collab_modals"
 11import { icon_button, toggleable_icon_button } from "../component/icon_button"
 12import { indicator } from "../component/indicator"
 13
 14export default function contacts_panel(): any {
 15    const theme = useTheme()
 16
 17    const CHANNEL_SPACING = 4 as const
 18    const NAME_MARGIN = 6 as const
 19    const SPACING = 12 as const
 20    const INDENT_SIZE = 8 as const
 21    const ITEM_HEIGHT = 28 as const
 22
 23    const layer = theme.middle
 24
 25    const contact_button = {
 26        background: background(layer, "on"),
 27        color: foreground(layer, "on"),
 28        icon_width: 14,
 29        button_width: 16,
 30        corner_radius: 8,
 31    }
 32
 33    const project_row = {
 34        guest_avatar_spacing: 4,
 35        height: 24,
 36        guest_avatar: {
 37            corner_radius: 8,
 38            width: 14,
 39        },
 40        name: {
 41            ...text(layer, "sans", { size: "sm" }),
 42            margin: {
 43                left: NAME_MARGIN,
 44                right: 4,
 45            },
 46        },
 47        guests: {
 48            margin: {
 49                left: NAME_MARGIN,
 50                right: NAME_MARGIN,
 51            },
 52        },
 53        padding: {
 54            left: SPACING,
 55            right: SPACING,
 56        },
 57    }
 58
 59    const icon_style = {
 60        color: foreground(layer, "variant"),
 61        width: 14,
 62    }
 63
 64    const header_icon_button = toggleable_icon_button({
 65        variant: "ghost",
 66        size: "sm",
 67        active_layer: theme.lowest,
 68    })
 69
 70    const subheader_row = toggleable({
 71        base: interactive({
 72            base: {
 73                ...text(layer, "sans", { size: "sm" }),
 74                padding: {
 75                    left: SPACING,
 76                    right: SPACING,
 77                },
 78            },
 79            state: {
 80                hovered: {
 81                    background: background(layer, "hovered"),
 82                },
 83                clicked: {
 84                    background: background(layer, "pressed"),
 85                },
 86            },
 87        }),
 88        state: {
 89            active: {
 90                default: {
 91                    ...text(theme.lowest, "sans", { size: "sm" }),
 92                    background: background(theme.lowest),
 93                },
 94                clicked: {
 95                    background: background(layer, "pressed"),
 96                },
 97            },
 98        },
 99    })
100
101    const filter_input = {
102        background: background(layer, "on"),
103        corner_radius: 6,
104        text: text(layer, "sans", "base"),
105        placeholder_text: text(layer, "sans", "base", "disabled", {
106            size: "xs",
107        }),
108        selection: theme.players[0],
109        border: border(layer, "on"),
110        padding: {
111            bottom: 4,
112            left: 8,
113            right: 8,
114            top: 4,
115        },
116        margin: {
117            left: SPACING,
118            right: SPACING,
119        },
120    }
121
122    const item_row = toggleable({
123        base: interactive({
124            base: {
125                padding: {
126                    left: SPACING,
127                    right: SPACING,
128                },
129            },
130            state: {
131                clicked: {
132                    background: background(layer, "pressed"),
133                },
134            },
135        }),
136        state: {
137            inactive: {
138                hovered: {
139                    background: background(layer, "hovered"),
140                },
141            },
142            active: {
143                default: {
144                    ...text(theme.lowest, "sans", { size: "sm" }),
145                    background: background(theme.lowest),
146                },
147                clicked: {
148                    background: background(layer, "pressed"),
149                },
150            },
151        },
152    })
153
154    return {
155        ...collab_modals(),
156        disclosure: {
157            button: icon_button({ variant: "ghost", size: "sm" }),
158            spacing: CHANNEL_SPACING,
159        },
160        log_in_button: interactive({
161            base: {
162                background: background(theme.middle),
163                border: border(theme.middle, "active"),
164                corner_radius: 4,
165                margin: {
166                    top: 4,
167                    left: 16,
168                    right: 16,
169                },
170                padding: {
171                    top: 3,
172                    bottom: 3,
173                    left: 7,
174                    right: 7,
175                },
176                ...text(theme.middle, "sans", "default", { size: "sm" }),
177            },
178            state: {
179                hovered: {
180                    ...text(theme.middle, "sans", "default", { size: "sm" }),
181                    background: background(theme.middle, "hovered"),
182                    border: border(theme.middle, "active"),
183                },
184                clicked: {
185                    ...text(theme.middle, "sans", "default", { size: "sm" }),
186                    background: background(theme.middle, "pressed"),
187                    border: border(theme.middle, "active"),
188                },
189            },
190        }),
191        background: background(layer),
192        padding: {
193            top: SPACING,
194        },
195        user_query_editor: filter_input,
196        channel_hash: icon_style,
197        user_query_editor_height: 33,
198        add_contact_button: header_icon_button,
199        add_channel_button: header_icon_button,
200        leave_call_button: header_icon_button,
201        row_height: ITEM_HEIGHT,
202        channel_indent: INDENT_SIZE * 2 + 2,
203        section_icon_size: 14,
204        header_row: {
205            ...text(layer, "sans", { size: "sm", weight: "bold" }),
206            margin: { top: SPACING },
207            padding: {
208                left: SPACING,
209                right: SPACING,
210            },
211        },
212        subheader_row,
213        leave_call: interactive({
214            base: {
215                background: background(layer),
216                border: border(layer),
217                corner_radius: 6,
218                margin: {
219                    top: 1,
220                },
221                padding: {
222                    top: 1,
223                    bottom: 1,
224                    left: 7,
225                    right: 7,
226                },
227                ...text(layer, "sans", "variant", { size: "xs" }),
228            },
229            state: {
230                hovered: {
231                    ...text(layer, "sans", "hovered", { size: "xs" }),
232                    background: background(layer, "hovered"),
233                    border: border(layer, "hovered"),
234                },
235            },
236        }),
237        contact_row: toggleable({
238            base: interactive({
239                base: {
240                    padding: {
241                        left: SPACING,
242                        right: SPACING,
243                    },
244                },
245                state: {
246                    clicked: {
247                        background: background(layer, "pressed"),
248                    },
249                },
250            }),
251            state: {
252                inactive: {
253                    hovered: {
254                        background: background(layer, "hovered"),
255                    },
256                },
257                active: {
258                    default: {
259                        ...text(theme.lowest, "sans", { size: "sm" }),
260                        background: background(theme.lowest),
261                    },
262                    clicked: {
263                        background: background(layer, "pressed"),
264                    },
265                },
266            },
267        }),
268        channel_row: item_row,
269        channel_name: {
270            ...text(layer, "sans", { size: "sm" }),
271            margin: {
272                left: CHANNEL_SPACING,
273            },
274        },
275        list_empty_label_container: {
276            margin: {
277                left: NAME_MARGIN,
278            },
279        },
280        list_empty_icon: {
281            color: foreground(layer, "variant"),
282            width: 14,
283        },
284        list_empty_state: toggleable({
285            base: interactive({
286                base: {
287                    ...text(layer, "sans", "variant", { size: "sm" }),
288                    padding: {
289                        top: SPACING / 2,
290                        bottom: SPACING / 2,
291                        left: SPACING,
292                        right: SPACING,
293                    },
294                },
295                state: {
296                    clicked: {
297                        background: background(layer, "pressed"),
298                    },
299                },
300            }),
301            state: {
302                inactive: {
303                    hovered: {
304                        background: background(layer, "hovered"),
305                    },
306                },
307                active: {
308                    default: {
309                        ...text(theme.lowest, "sans", { size: "sm" }),
310                        background: background(theme.lowest),
311                    },
312                    clicked: {
313                        background: background(layer, "pressed"),
314                    },
315                },
316            },
317        }),
318        contact_avatar: {
319            corner_radius: 10,
320            width: 20,
321        },
322        channel_avatar: {
323            corner_radius: 10,
324            width: 20,
325        },
326        extra_participant_label: {
327            corner_radius: 10,
328            padding: {
329                left: 10,
330                right: 4,
331            },
332            background: background(layer, "hovered"),
333            ...text(layer, "sans", "hovered", { size: "xs" }),
334        },
335        contact_status_free: indicator({ layer, color: "positive" }),
336        contact_status_busy: indicator({ layer, color: "negative" }),
337        contact_username: {
338            ...text(layer, "sans", { size: "sm" }),
339            margin: {
340                left: NAME_MARGIN,
341            },
342        },
343        contact_button_spacing: NAME_MARGIN,
344        contact_button: icon_button({
345            variant: "ghost",
346            color: "variant",
347            size: "sm",
348        }),
349        disabled_button: {
350            ...contact_button,
351            background: background(layer, "on"),
352            color: foreground(layer, "on"),
353        },
354        calling_indicator: {
355            ...text(layer, "sans", "variant", { size: "xs" }),
356        },
357        tree_branch: toggleable({
358            base: interactive({
359                base: {
360                    color: border_color(layer),
361                    width: 1,
362                },
363                state: {
364                    hovered: {
365                        color: border_color(layer),
366                    },
367                },
368            }),
369            state: {
370                active: {
371                    default: {
372                        color: border_color(layer),
373                    },
374                },
375            },
376        }),
377        project_row: toggleable({
378            base: interactive({
379                base: {
380                    ...project_row,
381                    icon: {
382                        margin: { left: NAME_MARGIN },
383                        color: foreground(layer, "variant"),
384                        width: 14,
385                    },
386                    name: {
387                        ...project_row.name,
388                        ...text(layer, "sans", { size: "sm" }),
389                    },
390                },
391                state: {
392                    hovered: {
393                        background: background(layer, "hovered"),
394                    },
395                },
396            }),
397            state: {
398                active: {
399                    default: { background: background(theme.lowest) },
400                },
401            },
402        }),
403        face_overlap: 8,
404        channel_editor: {
405            padding: {
406                left: NAME_MARGIN,
407            },
408        },
409    }
410}