Skip to content

Migrating from ghl-ui Drawer to HighRise Drawer

This guide provides step-by-step instructions for migrating from the ghl-ui Drawer component to the new HighRise Drawer component. The main architectural change is that the Drawer component has been split into two components: HLDrawer and HLDrawerContent for better organization and flexibility.

Component Implementation Changes

Import Changes

diff
- import { UIDrawer } from '@gohighlevel/ghl-ui'
+ import { HLDrawer, HLDrawerContent } from '@platform-ui/highrise'
+ import { HLHeaderLite } from '@platform-ui/highrise'
+ import { HLSectionFooter, HLSectionFooterItem } from '@platform-ui/highrise'
+ import { HLButton } from '@platform-ui/highrise'

Basic Usage Changes

diff
- <UIDrawer
-   v-model="show"
-   title="Drawer Title"
-   description="Drawer description"
-   positiveText="Save"
-   negativeText="Cancel"
-   @positiveClick="handleSave"
-   @negativeClick="show = false"
- >
-   <p>Drawer content</p>
- </UIDrawer>

+ <HLDrawer
+   id="my-drawer"
+   v-model:show="show"
+   placement="right"
+ >
+   <HLDrawerContent
+     id="drawer-content"
+     class="px-4"
+     title="Drawer Title"
+     description="Drawer description"
+     show-header
+     closable
+     @update:show="show = $event"
+   >
+     <div class="p-4">Drawer content</div>
+     <template #footer>
+       <HLSectionFooter id="footer" size="md">
+         <HLSectionFooterItem justify="end">
+           <HLButton @click="show = false" color="gray" variant="secondary">Cancel</HLButton>
+           <HLButton color="blue" variant="primary" @click="handleSave">Save</HLButton>
+         </HLSectionFooterItem>
+       </HLSectionFooter>
+     </template>
+   </HLDrawerContent>
+ </HLDrawer>

TIP

The basic usage example uses the default header through props (title, description, show-header, closable). For more customized headers, you can use the header slot with HLHeaderLite component as shown in the "Drawer with Header and Footer" example.

Basic Usage with Icon

diff
- <UIDrawer
-   v-model:show="active"
-   :width="args.width"
-   :placement="args.placement"
-   :maskClosable="args.maskClosable"
-   :id="args.id"
-   :displayDirective="args.displayDirective"
-   :autoFocus="args.autoFocus"
- >
-   <UIDrawerContent
-     negativeText="Cancel"
-     positiveText="Confirm"
-     id="drawer-component"
-     :closable="args.closable"
-     title="Lorem Ipsum"
-     description="Lorem Ipsum is simply dummy text of the printing and typesetting industry."
-     :icon="CreditCardShieldIcon"
-   >
-     Content goes here
-   </UIDrawerContent>
- </UIDrawer>

+ <HLDrawer
+   id="drawer-with-icon"
+   v-model:show="show"
+   :width="width"
+   :placement="placement"
+   :maskClosable="maskClosable"
+   :displayDirective="displayDirective"
+   :autoFocus="autoFocus"
+ >
+   <HLDrawerContent
+     id="drawer-content"
+     title="Lorem Ipsum"
+     description="Lorem Ipsum is simply dummy text of the printing and typesetting industry."
+     :icon="CreditCardShieldIcon"
+     show-header
+     closable
+     @update:show="show = $event"
+   >
+     <div class="p-4">Content goes here</div>
+     <template #footer>
+       <HLSectionFooter id="footer" size="md">
+         <HLSectionFooterItem justify="end">
+           <HLButton @click="show = false" color="gray" variant="secondary">Cancel</HLButton>
+           <HLButton color="blue" variant="primary">Confirm</HLButton>
+         </HLSectionFooterItem>
+       </HLSectionFooter>
+     </template>
+   </HLDrawerContent>
+ </HLDrawer>
vue
<script setup>
import { ref } from 'vue'
import { CreditCardShieldIcon } from '@gohighlevel/ghl-icons/24/outline'

const show = ref(false)
const width = 502
const placement = 'right'
const maskClosable = true
const displayDirective = 'if'
const autoFocus = true
</script>

TIP

When using an icon in the default header:

  1. Pass the icon component directly to the icon prop
  2. Make sure to import the icon from @gohighlevel/ghl-icons
  3. The icon will be automatically positioned in the header

Props Changes

HLDrawer Props

ghl-ui PropHighRise PropNotes
showshowUsed with v-model:show in HighRise
widthwidthDrawer width (default: 502)
placementplacementValues: 'top', 'right', 'bottom', 'left'
ididRequired in both versions
maskClosablemaskClosableWhether clicking mask closes drawer (default: true)
autoFocusautoFocusWhether to auto focus drawer (default: true)
-blockScrollWhether to block page scroll (default: true)
-closeOnEscWhether ESC key closes drawer (default: true)
-defaultHeightDefault drawer height (default: 251)
-defaultWidthDefault drawer width (default: 502)
-contentClassCustom class for drawer content
-contentStyleCustom style for drawer content
-maxWidthMaximum drawer width
-maxHeightMaximum drawer height
-minWidthMinimum drawer width
-minHeightMinimum drawer height
-displayDirectiveValues: 'if' or 'show' (default: 'if')
-resizableWhether drawer is resizable (default: false)
-showMaskWhether to show mask (default: true)
-toTarget container (default: 'body')
-trapFocusWhether to trap focus in drawer (default: true)
-zIndexZ-index value (default: 1000)

HLDrawerContent Props

ghl-ui PropHighRise PropNotes
ididRequired in both versions
titletitleTitle for default header
descriptiondescriptionDescription/subtitle for default header
iconiconIcon component for default header
positiveText-Removed, use HLButton in footer slot
negativeText-Removed, use HLButton in footer slot
loading-Removed, apply to HLButton directly
disabled-Removed, apply to HLButton directly
closableclosableWhether to show close button in default header
disableNegativeBtn-Removed, apply disabled to cancel HLButton
showHeadershowHeaderWhether to show the default header
-bodyClassCustom class for drawer body
-bodyStyleCustom style for drawer body
-bodyContentClassCustom class for body content
-bodyContentStyleCustom style for body content
-footerClassCustom class for footer
-footerStyleCustom style for footer
-headerClassCustom class for header
-headerStyleCustom style for header
-nativeScrollbarWhether to use native scrollbar (default: true)
-scrollbarPropsProps for custom scrollbar

Event Changes

HLDrawer Events

ghl-ui EventHighRise EventNotes
update:showupdate:showEmitted when drawer visibility changes
-after-enterEmitted after drawer enter transition
-after-leaveEmitted after drawer leave transition
-escEmitted when ESC key is pressed
-mask-clickEmitted when mask is clicked
-update:heightEmitted when height changes (resizable)
-update:widthEmitted when width changes (resizable)

HLDrawerContent Events

ghl-ui EventHighRise EventNotes
negativeClick-Removed, handle through HLButton
positiveClick-Removed, handle through HLButton

Slot Changes

HLDrawerContent Slots

ghl-ui SlotHighRise SlotNotes
headerheaderUse HLHeaderLite component
defaultdefaultMain content
actionLeft-Removed, use HLSectionFooterItem
actionRight-Removed, use HLSectionFooterItem
-footerNew slot for footer content

Examples

Basic Drawer

vue
<template>
  <HLDrawer id="basic-drawer" v-model:show="show" placement="right">
    <HLDrawerContent id="drawer-content" class="px-4">
      <div class="p-4">Basic drawer content</div>
    </HLDrawerContent>
  </HLDrawer>
</template>

<script setup>
import { ref } from 'vue'

const show = ref(false)
</script>
vue
<template>
  <HLDrawer id="full-drawer" v-model:show="show" placement="right">
    <HLDrawerContent id="drawer-content" class="px-4">
      <template #header>
        <HLHeaderLite title="Drawer Title" subtitle="Last updated 2m ago" @update:close="show = false">
          <template #header-icons>
            <HLIcon>
              <Share01Icon />
            </HLIcon>
          </template>
        </HLHeaderLite>
      </template>

      <div class="p-4">Main content area</div>

      <template #footer>
        <HLSectionFooter id="footer" :top-padding="false" :bottom-padding="false" :horizontal-padding="false">
          <HLSectionFooterItem justify="end">
            <HLButton @click="show = false">Cancel</HLButton>
            <HLButton color="blue" variant="primary">Save</HLButton>
          </HLSectionFooterItem>
        </HLSectionFooter>
      </template>
    </HLDrawerContent>
  </HLDrawer>
</template>

Content Padding

The drawer component does not have any default padding. You must add padding to your content manually:

  1. Header: No default padding - the HLHeaderLite component handles its own internal padding
  2. Content: No default padding - you must add padding using Tailwind classes
  3. Footer: No default padding - you must add padding when using HLSectionFooter component

When adding content to the drawer, you should:

  1. Always wrap your content in a div with padding (e.g., class="p-4")
  2. Use consistent padding across your drawers for uniformity
  3. Consider different padding sizes for different content types:
    • Forms: Use p-4 or p-6 for comfortable spacing
    • Simple content: Use p-4 for standard spacing
    • Complex layouts: Consider different padding per section

WARNING

Remember to always add padding to your drawer content. The drawer does not provide any default padding for the content or footer slots. Content without padding will touch the edges of the drawer.

Note: While HLHeaderLite includes its own padding, other header content will need manual padding.

Drawer with Custom Header

vue
<template>
  <HLDrawer id="drawer-custom-header" v-model:show="show" placement="right">
    <HLDrawerContent id="drawer-content">
      <template #header>
        <HLHeaderLite title="Drawer Title" subtitle="Last updated 2m ago" @update:close="show = false">
          <template #header-icons>
            <HLIcon size="lg" color="black">
              <TrendUp01Icon />
            </HLIcon>
          </template>
          <template #header-content>
            <HLHeaderLiteItem justify="end" size="sm">
              <HLButton variant="ghost" size="xs" color="gray"> Action </HLButton>
            </HLHeaderLiteItem>
          </template>
        </HLHeaderLite>
      </template>
      <div class="p-4">Main content goes here</div>
      <template #footer>
        <HLSectionFooter id="footer" :top-padding="false" :bottom-padding="false" :horizontal-padding="false">
          <HLSectionFooterItem justify="end">
            <HLButton @click="show = false">Cancel</HLButton>
            <HLButton color="blue" variant="primary">Save</HLButton>
          </HLSectionFooterItem>
        </HLSectionFooter>
      </template>
    </HLDrawerContent>
  </HLDrawer>
</template>

<script setup>
import { ref } from 'vue'
import { TrendUp01Icon } from '@gohighlevel/ghl-icons/24/outline'

const show = ref(false)
</script>

TIP

When using a custom header with HLHeaderLite:

  1. Use the header slot to provide your custom header content
  2. HLHeaderLite provides built-in slots for icons and additional content
  3. Handle the close action using @update:close event
  4. You can customize the header with additional buttons and actions

Best Practices

  1. Always provide unique id props for accessibility
  2. Use appropriate placement based on context
  3. Consider content layout and scrolling behavior
  4. Handle loading states appropriately
  5. Implement proper error handling
  6. Use consistent drawer sizes
  7. Follow accessibility guidelines
  8. Keep drawer content focused and organized
  9. Consider mobile responsiveness
  10. Use appropriate animations and transitions

Additional Notes

  1. Enhanced styling with CSS variables
  2. Built-in animation system
  3. Improved accessibility features
  4. Better integration with other HighRise components
  5. RTL layout support
  6. Consistent styling through CSS variables
  7. Support for custom scrollbars
  8. Flexible content organization
  9. Performance optimizations
  10. Standardized dimensions

Breaking Changes

  1. Split into two components: HLDrawer and HLDrawerContent
  2. HLDrawerContent does not have any default padding. You must add padding to your content manually.
  3. New required id props for accessibility
  4. Changed v-model binding to v-model:show
  5. Modified header implementation using HLHeaderLite
  6. Changed footer implementation using HLSectionFooter
  7. New theme override system
  8. Modified animation timing
  9. Changed CSS variable names
  10. New accessibility attributes
  11. Modified DOM structure