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 { text_button } from "../component/text_button"
 12import { icon_button, toggleable_icon_button } from "../component/icon_button"
 13import { indicator } from "../component/indicator"
 14
 15export default function contacts_panel(): any {
 16    const theme = useTheme()
 17
 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, "ui_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(theme, {
 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, "ui_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, "ui_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, "ui_sans", "base"),
105        placeholder_text: text(layer, "ui_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, "ui_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        log_in_button: interactive({
157            base: {
158                background: background(theme.middle),
159                border: border(theme.middle, "active"),
160                corner_radius: 4,
161                margin: {
162                    top: 4,
163                    left: 16,
164                    right: 16,
165                },
166                padding: {
167                    top: 3,
168                    bottom: 3,
169                    left: 7,
170                    right: 7,
171                },
172                ...text(theme.middle, "sans", "default", { size: "sm" }),
173            },
174            state: {
175                hovered: {
176                    ...text(theme.middle, "sans", "default", { size: "sm" }),
177                    background: background(theme.middle, "hovered"),
178                    border: border(theme.middle, "active"),
179                },
180                clicked: {
181                    ...text(theme.middle, "sans", "default", { size: "sm" }),
182                    background: background(theme.middle, "pressed"),
183                    border: border(theme.middle, "active"),
184                },
185            },
186        }),
187        background: background(layer),
188        padding: {
189            top: SPACING,
190        },
191        user_query_editor: filter_input,
192        channel_hash: icon_style,
193        user_query_editor_height: 33,
194        add_contact_button: header_icon_button,
195        add_channel_button: header_icon_button,
196        leave_call_button: header_icon_button,
197        row_height: ITEM_HEIGHT,
198        channel_indent: INDENT_SIZE,
199        section_icon_size: 14,
200        header_row: {
201            ...text(layer, "ui_sans", { size: "sm", weight: "bold" }),
202            margin: { top: SPACING },
203            padding: {
204                left: SPACING,
205                right: SPACING,
206            },
207        },
208        subheader_row,
209        leave_call: interactive({
210            base: {
211                background: background(layer),
212                border: border(layer),
213                corner_radius: 6,
214                margin: {
215                    top: 1,
216                },
217                padding: {
218                    top: 1,
219                    bottom: 1,
220                    left: 7,
221                    right: 7,
222                },
223                ...text(layer, "sans", "variant", { size: "xs" }),
224            },
225            state: {
226                hovered: {
227                    ...text(layer, "sans", "hovered", { size: "xs" }),
228                    background: background(layer, "hovered"),
229                    border: border(layer, "hovered"),
230                },
231            },
232        }),
233        contact_row: toggleable({
234            base: interactive({
235                base: {
236                    padding: {
237                        left: SPACING,
238                        right: SPACING,
239                    },
240                },
241                state: {
242                    clicked: {
243                        background: background(layer, "pressed"),
244                    },
245                },
246            }),
247            state: {
248                inactive: {
249                    hovered: {
250                        background: background(layer, "hovered"),
251                    },
252                },
253                active: {
254                    default: {
255                        ...text(theme.lowest, "ui_sans", { size: "sm" }),
256                        background: background(theme.lowest),
257                    },
258                    clicked: {
259                        background: background(layer, "pressed"),
260                    },
261                },
262            },
263        }),
264        channel_row: item_row,
265        channel_name: {
266            ...text(layer, "ui_sans", { size: "sm" }),
267            margin: {
268                left: NAME_MARGIN,
269            },
270        },
271        list_empty_label_container: {
272            margin: {
273                left: NAME_MARGIN,
274            }
275        },
276        list_empty_icon: {
277            color: foreground(layer, "variant"),
278            width: 14,
279        },
280        list_empty_state: toggleable({
281            base: interactive({
282                base: {
283                    ...text(layer, "ui_sans", "variant", { size: "sm" }),
284                    padding: {
285                        top: SPACING / 2,
286                        bottom: SPACING / 2,
287                        left: SPACING,
288                        right: SPACING
289                    },
290                },
291                state: {
292                    clicked: {
293                        background: background(layer, "pressed"),
294                    },
295                },
296            }),
297            state: {
298                inactive: {
299                    hovered: {
300                        background: background(layer, "hovered"),
301                    },
302                },
303                active: {
304                    default: {
305                        ...text(theme.lowest, "ui_sans", { size: "sm" }),
306                        background: background(theme.lowest),
307                    },
308                    clicked: {
309                        background: background(layer, "pressed"),
310                    },
311                },
312            },
313        }),
314        contact_avatar: {
315            corner_radius: 10,
316            width: 20,
317        },
318        channel_avatar: {
319            corner_radius: 10,
320            width: 20,
321        },
322        extra_participant_label: {
323            corner_radius: 10,
324            padding: {
325                left: 10,
326                right: 4,
327            },
328            background: background(layer, "hovered"),
329            ...text(layer, "ui_sans", "hovered", { size: "xs" })
330        },
331        contact_status_free: indicator({ layer, color: "positive" }),
332        contact_status_busy: indicator({ layer, color: "negative" }),
333        contact_username: {
334            ...text(layer, "ui_sans", { size: "sm" }),
335            margin: {
336                left: NAME_MARGIN,
337            },
338        },
339        contact_button_spacing: NAME_MARGIN,
340        contact_button: icon_button({
341            variant: "ghost",
342            color: "variant",
343            size: "sm",
344        }),
345        disabled_button: {
346            ...contact_button,
347            background: background(layer, "on"),
348            color: foreground(layer, "on"),
349        },
350        calling_indicator: {
351            ...text(layer, "mono", "variant", { size: "xs" }),
352        },
353        tree_branch: toggleable({
354            base: interactive({
355                base: {
356                    color: border_color(layer),
357                    width: 1,
358                },
359                state: {
360                    hovered: {
361                        color: border_color(layer),
362                    },
363                },
364            }),
365            state: {
366                active: {
367                    default: {
368                        color: border_color(layer),
369                    },
370                },
371            },
372        }),
373        project_row: toggleable({
374            base: interactive({
375                base: {
376                    ...project_row,
377                    icon: {
378                        margin: { left: NAME_MARGIN },
379                        color: foreground(layer, "variant"),
380                        width: 14,
381                    },
382                    name: {
383                        ...project_row.name,
384                        ...text(layer, "mono", { size: "sm" }),
385                    },
386                },
387                state: {
388                    hovered: {
389                        background: background(layer, "hovered"),
390                    },
391                },
392            }),
393            state: {
394                active: {
395                    default: { background: background(theme.lowest) },
396                },
397            },
398        }),
399        face_overlap: 8,
400        channel_editor: {
401            padding: {
402                left: NAME_MARGIN,
403            }
404        }
405    }
406}