Skip to content
Docs version
@hungpvq/vue-map@1.1.0@hungpvq/vue-map-core@1.1.0@hungpvq/vue-map-dataset@1.1.0@hungpvq/vue-map-draw@1.1.0@hungpvq/map-draw@1.1.0@hungpvq/react-map@1.1.0@hungpvq/react-map-core@1.1.0@hungpvq/react-map-dataset@1.1.0@hungpvq/react-map-draw@1.1.0

ModuleContainer

Usecase

  • Wrap custom controls with consistent draggable/toggleable behavior.
  • Standardize control chrome (button, header) across modules.

Props

PropDescriptionTypeRequiredDefault Value
mapIdstringfalse--
dragIdstringfalse--
btnWidthnumberfalse40
controlOrderCSS flex order for the standalone buttonnumberfalse0
position'top-left', 'top-right', 'bottom-left', 'bottom-right'false'bottom-right'
controlLayout'standalone' (corner), 'toolbar' (always in toolbar), 'button' (always corner; not auto-promoted on mobile)'standalone' | 'toolbar' | 'button'false'standalone'
controlVisiblebooleanfalsetrue

Map also accepts buttonInMobile ('button' | 'toolbar' | 'menu', default 'button'). On viewports ≤640px:

  • 'button' — leave corner buttons unchanged
  • 'toolbar' — move declared control buttons into a single ToolbarControl host (except controlLayout="button"). Mount one ToolbarControl in the map slot
  • 'menu' — hide per-control corner buttons; fan out intact clusters by position into corner stacks with outside-in More. Mount one ToolbarControl.

See ToolbarControl.

Events

Slots

NameDescription
btnControl chrome inside .btn-module-container (flex order applies here)
btnOutsideSame corner Teleport target as btn, but sibling outside .btn-module-container — use for absolute panels that must pin to the map corner host (e.g. toolbar/menu More). React: btnOutside prop
draggable

Usage

Vue

vue
<script setup lang="ts">
import { MapControlButton, ModuleContainer, withMapProps } from '@hungpvq/vue-map-core';
const props = defineProps({
  ...withMapProps,
  title: {
    type: String,
    default: '',
  },
});
const { moduleContainerProps } = useMap(props);
</script>
<template>
  <ModuleContainer v-bind="moduleContainerProps">
    <template #btn>
      <MapControlButton>
        <SvgIcon :size="18" type="mdi" :path="mdiHome" />
      </MapControlButton>
    </template>
    <slot />
  </ModuleContainer>
</template>
vue
<script setup lang="ts">
import type { WithMapPropType } from '@hungpvq/map-core';
import { MapControlButton, ModuleContainer, defaultMapProps } from '@hungpvq/vue-map-core';
const props = withDefaults(
  defineProps<
    WithMapPropType & {
      title: string;
    }
  >(),
  {
    ...defaultMapProps,
    title: '',
  },
);
const { moduleContainerProps } = useMap(props);
</script>
<template>
  <ModuleContainer v-bind="moduleContainerProps">
    <template #btn>
      <MapControlButton>
        <SvgIcon :size="18" type="mdi" :path="mdiHome" />
      </MapControlButton>
    </template>
    <slot />
  </ModuleContainer>
</template>

React

tsx
import {
  MapControlButton,
  ModuleContainer,
  defaultMapProps,
  useMap,
} from '@hungpvq/react-map-core';
import type { WithMapPropType } from '@hungpvq/map-core';
import { Icon } from '@mdi/react';
import { mdiHome } from '@mdi/js';
import type { ReactNode } from 'react';

type Props = WithMapPropType & {
  title?: string;
  children?: ReactNode;
};

function HomeModule(props: Props) {
  const merged = { ...defaultMapProps, title: '', ...props };
  const { moduleContainerProps } = useMap(merged);

  return (
    <ModuleContainer
      {...moduleContainerProps}
      btn={
        <MapControlButton>
          <Icon path={mdiHome} size="18px" />
        </MapControlButton>
      }
    >
      {props.children}
    </ModuleContainer>
  );
}