grid-plan
v1.1.3
Published
A Vue3 dynamic 2d grid component ideal to view and arrange elements on a room, datacenter or rack blueprint.
Downloads
128
Maintainers
Readme
grid-plan
grid-plan is a Vue3 component to create blueprints for rooms, datacenters, racks, etc.
Create available component types, and place, resize or delete them from the blueprint.
grid-plan ships with:
- config options to customize the looks of your blueprint
- slots to customize icons related to component types
- slots to create your available components menu and your inventory
Installation
npm i grid-plan
You can declare the component globally in your main.js:
import { createApp } from "vue";
import App from "./App.vue";
import { GridPlan } from "grid-plan";
const app = createApp(App);
app.component("GridPlan", GridPlan);
app.mount("#app");
Or you can import it directly in your Vue file:
<script setup>
import { GridPlan } from "grid-plan";
</script>
Props
| Prop name | TS type | Required | Description | | -------------- | ------------------ | ----------------------------------- | ----------------------------------------------------------- | | availableTypes | GridPlanItemType[] | YES | The types of components that can be placed on the blueprint | | placedItems | GridPlanItem[] | YES (can be empty) | Components already placed on the blueprint | | radonly | boolean | NO (default: false) | Blueprint will be readonly if true | | config | GridPlanConfig | NO (default config will be applied) | Configuration object to customize looks |
Example
- Script:
import { ref } from "vue";
import { GridPlan } from "grid-plan";
const availableTypes = ref([
{
typeId: 1,
color: "#3366DD",
description: "server",
icon: "server",
iconColor: "#FFFFFF",
},
{
typeId: 2,
color: "#DD6633",
description: "power",
icon: "bolt",
iconColor: "#FFFFFF",
},
{
typeId: 3,
color: "#71a4a8",
description: "monitor",
icon: "deviceLaptop",
iconColor: "#1A1A1A",
},
]);
const placedItems = ref([
{ x: 0, y: 0, h: 1, w: 12, typeId: 1 }, // it's a server component
{ x: 0, y: 1, h: 4, w: 12, typeId: 3 }, // it's a monitor component
]);
// Config is optional
// You can provide a partial config, as missing attributes will use defaults
const config = ref({
abscissaType: "alphabetic",
accordionMenuTitle: "Menu",
coordinatesBackground: "#2A2A2A",
coordinatesColor: "#8A8A8A",
crosshairBackground: "#4A4A4A",
fontFamily: "Arial",
gridFill: "#3A3A3A",
gridHeight: 42,
gridHighlightColor: "#00FF00",
gridStroke: "#1A1A1A",
gridStrokeWidth: 0.02,
gridWidth: 12,
handleFill: "#FFFFFF",
handleSize: 0.3,
iconColor: "#1A1A1A",
nonSelectedOpacity: 0.3
ordinatesType: "numeric",
showCrosshair: true,
tooltipColor: "#FFFFFF",
useAccordionMenu: true,
useGradient: true,
useShadow: true,
});
// Events
function selectType(menuItem) {
// Triggered when a menu item is selected
console.log("SELECT TYPE", menuItem);
}
function change(item) {
// Triggered whenever an item is changed
console.log("CHANGED", item);
}
function deleteItem(item) {
// Triggered whenever an item is deleted
console.log("DELETED", item);
}
function selectItem(item) {
// Triggered whenever an item is selected
console.log("SELECTED", item);
}
function createdItem(item) {
// Triggered whenever an item is created
console.log("CREATED", item);
}
function unselected() {
// Triggered when an item is unselected
// Pressing ESC will treigger unselect
// Selecting an already selected item will trigger unselect
console.log("BLUEPRINT IS NOW UNSELECTED");
}
- Template:
<template>
<GridPlan
:availableTypes="availableTypes"
ref="plan"
:config="config"
:placedItems="placedItems"
@change="change"
@delete="deleteItem"
@select="selectItem"
@created="createdItem"
@unselect="unselected"
@selectType="selectType"
>
<!-- Create your available types menu -->
<template #availableType="{ availableType }">
<!-- The click event is managed by the component, that will select the type to be used when adding a component to the blueprint -->
<button>{{ availableType.description }}</button>
</template>
<!-- Create your inventory, which will be displayed inside a details element (target the .grid-plan-inventory css class to style) -->
<template #inventory="{ item, deleteItem, focusItem, isFocused }">
<div
:style="`display: flex; flex-direction:row; flex-wrap: wrap; border: 1px solid ${item.color};width: fit-content; padding: 6px 12px; gap:6px; ${isFocused ? 'background: #FFFFFF20' : ''}`"
>
<span>{{ item.description }}</span>
<span>x:{{ item.x }}</span>
<span>y:{{ item.y }}</span>
<span>h:{{ item.h }}</span>
<span>w:{{ item.w }}</span>
<button @click="deleteItem">DELETE</button>
<button @click="focusItem">
{{ isFocused ? 'UNFOCUS' : 'FOCUS' }}
</button>
</div>
</template>
<!-- Use your own svg icons for component types (not necessary if the icon provided is part of the available icons) -->
<template #componentIcon="{ placedItem, maxSize }">
<svg
v-if="placedItem.description === 'server'"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="#FFFFFF"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
:style="`width:${maxSize}px; position: absolute; transform: scale(0.8, 0.8)`"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M3 4m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z"
/>
<path
d="M3 12m0 3a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v2a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3z"
/>
<path d="M7 8l0 .01" />
<path d="M7 16l0 .01" />
<path d="M11 8h6" />
<path d="M11 16h6" />
</svg>
</template>
<!-- Or use this slot to display a single letter or an icon font -->
<template #componentText="{ placedItem }"> {{ placedItem.icon }} </template>
</GridPlan>
</template>
Config details
| Attribute | TS type | Default | Description | | --------------------- | ------------------------- | ------------ | ------------------------------------------------------------------- | | abscissaType | "alphabetic" OR "numeric" | "alphabetic" | Display abscissa coordinates as letters or numbers | | accordionMenuTitle | string | "Menu" | Text content of detail summary | | coordinatesBackground | string | "#2A2A2A" | Background color of the coordinates cells | | coordinatesColor | string | "#8A8A8A" | Text color of the coordinates cells | | crosshairBackground | string | "#4A4A4A" | Background color of the crosshair | | fontFamily | string | "Arial" | Font used for all elements in the component | | gridFill | string | "#3A3A3A" | Background color of unused blueprint cells | | gridHeight | number | 20 | The height of the blueprint in cell units | | gridHighlightColor | string | "#FFFFFF" | The contour of available cells on hover | | gridStroke | string | "#1A1A1A" | The color of grid lines | | gridWidth | number | 20 | The width of the blueprint in cell units | | handleFill | string | "#FFFFFF" | The color of resize handles | | handleSize | number | 0.3 | The handle size | | iconColor | string | "#1A1A1A" | The text color when using the #componentText slot | | inventoryTitle | string | "Inventory" | The text content of the inventory details summary element | | nonSelectedOpacity | number | 0.3 | The opacity of non selected components when a component is selected | | ordinatesType | "alphabetic" OR "numeric" | "numeric" | Display ordinate coordinates as letters or numbers | | showCrosshair | boolean | true | Show crosshair when hovering available cells | | showInventory | boolean | true | Show inventory of placed components inside a details HTML element | | tooltipColor | string | "#FFFFFF" | The tooltip text color | | useAccordionMenu | boolean | true | Display the menu inside a details HTML element | | useGradient | boolean | true | Shows components with a subtle gradient | | useShadow | boolean | true | Show selected item with a drop shadow |
CSS classes
Grid Plan does not ship css. To customize the styling of the menu and inventory, target the following css classes:
.grid-plan-menu {
}
.grid-plan-menu__summary {
} /* If useAccordionMenu is true */
.grid-plan-menu__body {
} /* If useAccordionMenu is true */
.grid-plan-inventory {
}
.grid-plan-inventory__summary {
}
.grid-plan-inventory__body {
}
Icons
A set of icons is provided by grid-plan. These icons are adapted from the great Tabler icons open source icon library.
Icons are used in availableTypes:
const availableTypes = ref([
{
color: '#6376DD',
description: 'router',
icon: 'router',
typeId: 1,
iconColor: '#FFFFFF'
},
{...}
])
| Icon name | | ------------------- | | airConditioning | | alertTriangle | | analyze | | archive | | armchair | | award | | bath | | battery | | bed | | bell | | bellSchool | | bolt | | boltOff | | books | | bulb | | bulfOff | | burger | | calculator | | camera | | cctv | | chefHat | | circleKey | | circuitCapacitor | | circuitCell | | circuitGround | | circuitSwitchClosed | | circuitSwitchOpen | | clock | | cloud | | cloudComputing | | coffee | | cpu | | cricuitLoop | | database | | deviceDesktop | | deviceDesktopOff | | deviceDualScreen | | deviceImac | | deviceImacOff | | deviceLaptop | | deviceLaptopOff | | deviceTablet | | deviceTabletOff | | deviceTv | | deviceTvOff | | deviceUsb | | devicesPc | | devicesPcOff | | disabled | | door | | doorEnter | | doorExit | | elevator | | elevatorOff | | escalator | | escalatorDown | | escalatorUp | | fingerprint | | firstAidKit | | folder | | folders | | headphones | | headset | | hexagon | | home | | key | | keyboard | | leaf | | lock | | lockAccess | | man | | microphone | | microscope | | network | | networkOff | | package | | packages | | paperclip | | phone | | plant | | plugConnected | | power | | printer | | printerOff | | prism | | propeller | | propellerOff | | reportAnalytics | | robot | | router | | salad | | server | | serverBolt | | serverCog | | serverOff | | shredder | | sofa | | solarPanel | | soup | | squareKey | | stack | | toilet | | toiletPaper | | toolsKitchen | | trafficCone | | trash | | trolley | | volume | | wall | | washMachine | | wave | | wifi | | windMill | | windmillOff | | window | | world |