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(VIconBtn): create new component #21114

Merged
merged 55 commits into from
Mar 28, 2025
Merged

feat(VIconBtn): create new component #21114

merged 55 commits into from
Mar 28, 2025

Conversation

johnleider
Copy link
Member

@johnleider johnleider commented Mar 17, 2025

Motivation and Context

  • A new lightweight component (50% 30% faster than VBtn) that will be used to eventually replace VBtn usage throughout
  • Currently VBtn is used in a variety of components such as VTreeview, VDataTable, VDatePicker, VCarousel where it contains infinitely more functionality than what will ever be needed
  • Wanted to have a way to start bringing back toggle icons rotating for expansion components like VList, VTreeview, VExpansionPanels
  • Will also eventually replace closable buttons

Markup:

<template>
  <v-container class="pa-md-12 text-center">
    <v-sheet
      class="d-inline-flex ga-1 pa-4 align-center justify-center mx-auto"
      color="surface-light"
      rounded="pill"
    >
      <v-sheet
        :rounded="!mic ? 'lg' : 'xl'"
        class="overflow-visible d-flex align-center"
        color="surface"
        height="48"
        width="88"
        flat
      >
        <v-icon-btn
          v-model:active="micOptions"
          :active-variant="!mic ? 'flat' : 'text'"
          :base-variant="!mic ? 'flat' : 'text'"
          :color="!mic ? 'error' : ''"
          :rounded="!mic ? 'lg' : 'circle'"
          active-icon="mdi-chevron-down"
          icon="mdi-chevron-up"
          size="48"
          hide-overlay
        />

        <v-icon-btn
          v-model:active="mic"
          :rounded="!mic ? 'lg' : 'circle'"
          active-color=""
          active-icon="mdi-microphone"
          active-variant="tonal"
          base-variant="flat"
          class="ms-n2"
          color="#f9dedc"
          icon="mdi-microphone-off"
          size="48"
          v-ripple
        />
      </v-sheet>

      <v-sheet
        :rounded="!video ? 'lg' : 'xl'"
        class="overflow-visible d-flex align-center"
        color="surface"
        height="48"
        width="88"
        flat
      >
        <v-icon-btn
          v-model:active="videoOptions"
          :active-variant="!video ? 'flat' : 'text'"
          :base-variant="!video ? 'flat' : 'text'"
          :color="!video ? 'error' : ''"
          :rounded="!video ? 'lg' : 'circle'"
          active-icon="mdi-chevron-down"
          icon="mdi-chevron-up"
          size="48"
          hide-overlay
        />

        <v-icon-btn
          v-model:active="video"
          :rounded="!video ? 'lg' : 'circle'"
          active-color=""
          active-icon="mdi-video-outline"
          active-variant="tonal"
          base-variant="flat"
          class="ms-n2"
          color="#f9dedc"
          icon="mdi-video-off"
          size="48"
        />
      </v-sheet>

      <v-icon-btn
        v-model:active="caption"
        :class="!caption ? 'mx-1' : undefined"
        :rounded="!caption ? 'circle' : 'lg'"
        :width="caption ? 56 : 48"
        active-color="#9bbbef"
        active-icon="mdi-closed-caption"
        active-variant="flat"
        height="48"
        icon="mdi-closed-caption-outline"
      />

      <v-icon-btn
        v-model:active="emoji"
        :class="!emoji ? 'mx-1' : undefined"
        :rounded="!emoji ? 'circle' : 'lg'"
        :width="emoji ? 56 : 48"
        active-color="#9bbbef"
        active-icon="mdi-emoticon"
        height="48"
        icon="mdi-emoticon-outline"
      />

      <v-icon-btn
        v-model:active="share"
        :class="!share ? 'mx-1' : undefined"
        :rounded="!share ? 'circle' : 'lg'"
        :width="share ? 56 : 48"
        active-color="#9bbbef"
        active-icon="mdi-arrow-up-bold-box"
        height="48"
        icon="mdi-arrow-up-bold-box-outline"
        @click="onClick"
      />

      <v-icon-btn
        v-model:active="raised"
        :class="!raised ? 'mx-1' : undefined"
        :rounded="!raised ? 'circle' : 'lg'"
        :width="raised ? 56 : 48"
        active-color="#9bbbef"
        active-icon="mdi-hand-back-right"
        height="48"
        icon="mdi-hand-back-right-outline"
      />

      <v-icon-btn
        height="48"
        icon="mdi-dots-vertical"
        rounded="xl"
        variant="tonal"
      >
        <v-icon />

        <v-menu activator="parent" offset="4" origin="bottom" position="top">
          <v-list rounded="lg" slim>
            <v-list-item
              prepend-icon="mdi-radiobox-marked"
              title="Manage recording"
              link
            />

            <v-divider class="my-2" />

            <v-list-item
              prepend-icon="mdi-view-grid-outline"
              title="Change layout"
              link
            />

            <v-list-item
              prepend-icon="mdi-fullscreen"
              title="Full screen"
              link
            />

            <v-list-item
              prepend-icon="mdi-share-variant-outline"
              title="Share screen"
              link
            />

            <v-divider class="my-2" />

            <v-list-item
              prepend-icon="mdi-cog-outline"
              title="Settings"
              link
            />
          </v-list>
        </v-menu>
      </v-icon-btn>

      <v-icon-btn
        v-model:active="hangup"
        active-variant="outlined"
        base-variant="flat"
        color="error"
        height="48"
        icon="mdi-phone-hangup-outline"
        rounded="xl"
        width="72"
      />
    </v-sheet>
  </v-container>
</template>
<script setup>
  import { shallowRef } from 'vue'

  const caption = shallowRef(false)
  const emoji = shallowRef(false)
  const raised = shallowRef(false)
  const hangup = shallowRef(false)
  const mic = shallowRef(true)
  const micOptions = shallowRef(false)
  const share = shallowRef(false)
  const video = shallowRef(true)
  const videoOptions = shallowRef(false)

  function onClick () {
    console.log('clicked', share.value)
  }
</script>

@johnleider johnleider self-assigned this Mar 17, 2025
@MajesticPotatoe MajesticPotatoe added the T: feature A new feature label Mar 18, 2025
@johnleider johnleider marked this pull request as ready for review March 22, 2025 19:23
@johnleider johnleider added the C: New Component This issue would need a new component to be developed. label Mar 22, 2025
@johnleider johnleider added this to the v3.8.0 (Andromeda) milestone Mar 22, 2025
@johnleider johnleider requested a review from a team March 22, 2025 19:29
@MatthewAry
Copy link
Contributor

Might be out of scope but would love to see a loading state. 🥹

@KaelWD
Copy link
Member

KaelWD commented Mar 27, 2025

Like this one?

{ !!props.loading && (
<span key="loader" class="v-icon-btn__loader">
{ slots.loader?.() ?? (
<VProgressCircular
color={ typeof props.loading === 'boolean' ? undefined : props.loading }
indeterminate="disable-shrink"
width="2"
size={ iconSize }
/>
)}
</span>
)}

@MatthewAry
Copy link
Contributor

MatthewAry commented Mar 27, 2025

I looked at the prop list (the one used for docs) and I didn't see a loading prop, but I forgot about how the props are inherited.

@johnleider johnleider force-pushed the feat/v-icon-btn branch 2 times, most recently from a7aa529 to 0f9bbbc Compare March 27, 2025 04:35
@johnleider johnleider added the labs Must be completed for this component to leave labs label Mar 28, 2025
@johnleider johnleider merged commit 3b8a325 into dev Mar 28, 2025
18 checks passed
@johnleider johnleider deleted the feat/v-icon-btn branch March 28, 2025 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: New Component This issue would need a new component to be developed. labs Must be completed for this component to leave labs T: feature A new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants