{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "grid-virtual-scrolling",
  "framework": "vue",
  "type": "registry:component",
  "component": "Grid",
  "variant": "virtual-scrolling",
  "dependencies": [
    "@syncfusion/ej2-data",
    "@syncfusion/ej2-vue-buttons",
    "@syncfusion/ej2-vue-grids",
    "@syncfusion/ej2-vue-inputs"
  ],
  "description": "Data grid handles large datasets efficiently with row and column virtualization.",
  "meta": {
    "essentialStudioRelease": "2026 Volume 2 (v34.1.29)",
    "license": "commercial-or-community",
    "licenseNote": "The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md",
    "requiresLicenseKey": true,
    "requiresServerEndpoint": false,
    "platformIndex": "https://ai.syncfusion.com/vue/llms.txt",
    "skillPack": "syncfusion/vue-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/vue/grid-virtual-scrolling.md"
  },
  "files": [
    {
      "target": "src/components/grid-virtual-scrolling/Grid.vue",
      "content": "<template>\n<div class=\"col-lg-12 control-section\">\n    <div>\n        <div class='div-button'>\n            <ejs-button ref=\"loadbtn\" @click='onClick' cssClass='e-info'>Load 100K Data</ejs-button>\n            <span id=\"popup\" :style=\"display\">\n                <span id=\"gif\" class=\"imagepop\"></span>\n            </span>\n            <span id=\"performanceTime\">{{timeTaken}}</span>\n        </div>\n        <ejs-grid id=\"VirtualScroll\" ref='grid' :dataSource=\"virtualData\" :enableVirtualization='true' :enableColumnVirtualization='true' height=400 :rowHeight='50' :dataBound='hide' :load='load' :editSettings='editSettings' :toolbar='toolbar' :clipMode=\"'EllipsisWithTooltip'\">\n            <e-columns>\n              <e-column field='OrderID' headerText='Order ID' width='110' :isPrimaryKey='true' :validationRules='validationRule'></e-column>\n              <e-column field='OrderDate' headerText='Order Date' width='140' format='yMd' textAlign='Right' editType='datepickeredit'></e-column>\n              <e-column field='ShipDate' headerText='Ship Date' width='140' format='yMd' textAlign='Right' editType='datepickeredit'></e-column>\n              <e-column field='OrderStatus' headerText='Order Status' width='140' textAlign='Center' editType='dropdownedit' :template=\"'orderStatusTemplate'\" :validationRules='validationRule'></e-column>\n              <e-column field='Priority' headerText='Priority' width='120' textAlign='Center' editType='dropdownedit' :template=\"'priorityTemplate'\"></e-column>\n              <e-column field='CustomerName' headerText='Customer Name' width='190' :validationRules='validationRule'></e-column>\n              <e-column field='CustomerID' headerText='Customer ID' width='110' visible='false'></e-column>\n              <e-column field='Email' headerText='Email' width='200'></e-column>\n              <e-column field='Phone' headerText='Phone Number' width='140' textAlign='Right'></e-column>\n              <e-column field='ShipAddress' headerText='Ship Address' width='180'></e-column>\n              <e-column field='ShipCity' headerText='Ship City' width='120'></e-column>\n              <e-column field='ShipState' headerText='Ship State Code' width='130'></e-column>\n              <e-column field='ShipPostalCode' headerText='Ship Postal Code' width='130' textAlign='Right'></e-column>\n              <e-column field='ShipCountry' headerText='Ship Country' width='150'></e-column>\n              <e-column field='ProductName' headerText='Product Name' width='250'></e-column>\n              <e-column field='ProductID' headerText='Product ID' width='110' visible='false'></e-column>\n              <e-column field='Category' headerText='Category' width='120'></e-column>\n              <e-column field='Warehouse' headerText='Ware house' width='110' visible='false' editType='dropdownedit'></e-column>\n              <e-column field='InventoryCount' headerText='Inventory Count' width='150' textAlign='Right' visible='false'></e-column>\n              <e-column field='Quantity' headerText='Quantity' width='100' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='UnitPrice' headerText='Unit Price' width='110' format='C2' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='Discount' headerText='Discount (%)' width='120' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='Tax' headerText='Tax (%)' width='100' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='SubTotal' headerText='Sub Total' width='110' format='C2' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='TaxAmount' headerText='Tax Amount' width='110' format='C2' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='ShipFee' headerText='Ship Fee' width='120' format='C2' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='TotalAmount' headerText='Total Amount' width='120' format='C2' textAlign='Right' editType='numericedit' :editParams='{ showSpinButton: false }'></e-column>\n              <e-column field='PaymentMethod' headerText='Payment Method' width='140' editType='dropdownedit' :validationRules='validationRule' :template=\"'paymentMethodTemplate'\"></e-column>\n              <e-column field='PaymentStatus' headerText='Payment Status' width='140' textAlign='Center' editType='dropdownedit' :template=\"'paymentStatusTemplate'\" :validationRules='validationRule'></e-column>\n              <e-column field='Rating' headerText='Delivery Rating' width='160' textAlign='Center' editType='dropdownedit' :template=\"'ratingTemplate'\" :visible='false'></e-column>\n            </e-columns>\n            <template v-slot:ratingTemplate=\"{data}\">\n              <div>\n                <ejs-rating :value=\"data.Rating\" cssClass=\"custom-rating\" readOnly=true></ejs-rating>\n              </div>\n            </template>\n            <template v-slot:paymentMethodTemplate=\"{data}\">\n              <div class=\"e-payment-info\">\n                <img :src=\"`src/grid/images/payment/${data.PaymentMethod}.svg`\" :alt=\"data.PaymentMethod\"/>\n                <span>{{ data.PaymentMethod }}</span>\n              </div>\n            </template>\n            <template v-slot:orderStatusTemplate=\"{data}\">\n              <div>\n                <div v-if=\"data.OrderStatus === 'Delivered'\" class=\"virtual-statustemp e-deliveredcolor\">\n                  <span class=\"virtual-statustxt e-deliveredcolor\">Delivered</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Shipped'\" class=\"virtual-statustemp e-shippedcolor\">\n                  <span class=\"virtual-statustxt e-shippedcolor\">Shipped</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Packed'\" class=\"virtual-statustemp e-packedcolor\">\n                  <span class=\"virtual-statustxt e-packedcolor\">Packed</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Processing'\" class=\"virtual-statustemp e-processingcolor\">\n                  <span class=\"virtual-statustxt e-processingcolor\">Processing</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Canceled'\" class=\"virtual-statustemp e-cancelcolor\">\n                  <span class=\"virtual-statustxt e-cancelcolor\">Canceled</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Returned'\" class=\"virtual-statustemp e-returnedcolor\">\n                  <span class=\"virtual-statustxt e-returnedcolor\">Returned</span>\n                </div>\n                <div v-else-if=\"data.OrderStatus === 'Ordered'\" class=\"virtual-statustemp e-orderedcolor\">\n                  <span class=\"virtual-statustxt e-orderedcolor\">Ordered</span>\n                </div>\n              </div>\n            </template>\n            <template v-slot:paymentStatusTemplate=\"{data}\">\n              <div>\n                <div v-if=\"data.PaymentStatus === 'Paid'\" class=\"virtual-statustemp e-paidcolor\">\n                  <span class=\"virtual-statustxt e-paidcolor\">Paid</span>\n                </div>\n                <div v-else-if=\"data.PaymentStatus === 'Pending'\" class=\"virtual-statustemp e-pendingcolor\">\n                  <span class=\"virtual-statustxt e-pendingcolor\">Pending</span>\n                </div>\n                <div v-else-if=\"data.PaymentStatus === 'Refunded'\" class=\"virtual-statustemp e-refundcolor\">\n                  <span class=\"virtual-statustxt e-refundcolor\">Refunded</span>\n                </div>\n                <div v-else-if=\"data.PaymentStatus === 'Failed'\" class=\"virtual-statustemp e-failedcolor\">\n                  <span class=\"virtual-statustxt e-failedcolor\">Failed</span>\n                </div>\n              </div>\n            </template>\n            <template v-slot:priorityTemplate=\"{data}\">\n              <div>\n                <div v-if=\"data.Priority === 'High'\" class=\"virtual-statustemp e-highcolor\">\n                  <span class=\"virtual-statustxt e-highcolor\">High</span>\n                </div>\n                <div v-else-if=\"data.Priority === 'Low'\" class=\"virtual-statustemp e-lowcolor\">\n                  <span class=\"virtual-statustxt e-lowcolor\">Low</span>\n                </div>\n                <div v-else-if=\"data.Priority === 'Medium'\" class=\"virtual-statustemp e-mediumcolor\">\n                  <span class=\"virtual-statustxt e-mediumcolor\">Medium</span>\n                </div>\n                <div v-else-if=\"data.Priority === 'Critical'\" class=\"virtual-statustemp e-criticalcolor\">\n                  <span class=\"virtual-statustxt e-criticalcolor\">Critical</span>\n                </div>\n              </div>\n            </template>\n        </ejs-grid>\n    </div>\n\n</div>\n</template>\n<script lang=\"ts\">\nimport { GridComponent, ColumnsDirective, ColumnDirective, VirtualScroll, Edit, Toolbar } from \"@syncfusion/ej2-vue-grids\";\nimport { DataManager, JsonAdaptor } from '@syncfusion/ej2-data'; \nimport { ButtonComponent } from \"@syncfusion/ej2-vue-buttons\";\nimport { RatingComponent } from '@syncfusion/ej2-vue-inputs';\n\nconst virtualOrderData = []; // or define proper interface if needed\nfunction createVirtualOrderData() {\n    function pmRandom(seed) {\n        var t = (seed % 2147483647);\n        if (t <= 0)\n            t += 2147483646;\n        return function () {\n            t = (t * 16807) % 2147483647;\n            return (t - 1) / 2147483646; // [0,1)\n        };\n    }\n    var seed = 123456789;\n    var rand = pmRandom(seed);\n    function randInt(min, max) {\n        return Math.floor(rand() * (max - min + 1)) + min;\n    }\n    function randChoice(arr) {\n        return arr[Math.floor(rand() * arr.length)];\n    }\n    function pickAvoidTriplet(arr, fieldName) {\n        var v = randChoice(arr);\n        if (virtualOrderData.length >= 2) {\n            var prevItems = virtualOrderData;\n            var a = prevItems[virtualOrderData.length - 1][fieldName];\n            var b = prevItems[virtualOrderData.length - 2][fieldName];\n            if (a === b && a === v) {\n                var alt = arr.filter(function (s) { return s !== v; });\n                if (alt.length > 0) {\n                    v = randChoice(alt);\n                }\n            }\n        }\n        return v;\n    }\n    var names = [\n        'Maria', 'Ana Trujillo', 'Antonio Moreno', 'Thomas Hardy', 'Christina Berglund', 'Hanna Moos'\n    ];\n    var products = [\n        'Chai', 'Chang', 'Aniseed Syrup', \"Chef Anton's Cajun Seasoning\",\n        \"Grandma's Boysenberry Spread\", \"Uncle Bob's Organic Dried Pears\",\n        'Mishi Kobe Niku', 'Ikura', 'Queso Cabrales', 'Pavlova'\n    ];\n    var categories = [\n        'Beverages', 'Condiments', 'Confections', 'Dairy Products',\n        'Grains/Cereals', 'Meat/Poultry', 'Seafood'\n    ];\n    var paymentMethods = ['Card', 'Digital', 'Cash'];\n    var orderStatuses = ['Ordered', 'Processing', 'Packed', 'Shipped', 'Delivered', 'Canceled', 'Returned'];\n    var priorities = ['Low', 'Medium', 'High', 'Critical'];\n    var cities = ['Seattle', 'Austin', 'Boston', 'Chicago', 'San Francisco', 'New York'];\n    var states = ['WA', 'TX', 'MA', 'IL', 'CA', 'NY'];\n    var countries = ['USA', 'Canada', 'Mexico', 'UK', 'Germany', 'France'];\n    var warehouses = ['WH-A', 'WH-B', 'WH-C', 'WH-D'];\n    var productToCategory = {};\n    for (var k = 0; k < products.length; k++) {\n        productToCategory[products[k]] = categories[k % categories.length];\n    }\n    function computeAmounts(qty, unitPrice, discountPct, taxPct, shippingFee) {\n        var gross = qty * unitPrice;\n        var discount = gross * (discountPct / 100);\n        var subtotal = gross - discount;\n        var tax = subtotal * (taxPct / 100);\n        var total = subtotal + tax + shippingFee;\n        return {\n            subtotal: Math.round(subtotal * 100) / 100,\n            taxAmount: Math.round(tax * 100) / 100,\n            totalAmount: Math.round(total * 100) / 100\n        };\n    }\n    var baseTime = new Date(2025, 0, 1).getTime();\n    for (var i = 1; i <= 100000; i++) {\n        var qty = randInt(1, 10);\n        var unitPrice = Math.round((rand() * 500 + 5) * 100) / 100;\n        var discountPct = randInt(0, 20);\n        var taxPct = randInt(0, 18);\n        var shippingFee = Math.round((rand() * 20) * 100) / 100;\n        var amounts = computeAmounts(qty, unitPrice, discountPct, taxPct, shippingFee);\n        var orderDate = new Date(baseTime - randInt(0, 90) * 24 * 3600 * 1000);\n        var shippedDate = new Date(orderDate.getTime() + randInt(1, 14) * 24 * 3600 * 1000);\n        var customerId = randInt(1000, 9999);\n        var custName = randChoice(names);\n        var email = custName.toLowerCase().replace(/\\s+/g, '.') + '@example.com';\n        var paymentMethod = pickAvoidTriplet(paymentMethods, 'PaymentMethod');\n        var rating = randInt(1, 5);\n        var orderStatusVal = pickAvoidTriplet(orderStatuses, 'OrderStatus');\n        var priorityVal = pickAvoidTriplet(priorities, 'Priority');\n        var productName = randChoice(products);\n        var derivedCategory = productToCategory[productName] || randChoice(categories);\n        var warehouse = randChoice(warehouses);\n        var inventoryCount = randInt(0, 500);\n        var paymentStatus = 'Pending';\n        if (orderStatusVal === 'Delivered' || orderStatusVal === 'Shipped') {\n            paymentStatus = 'Paid';\n        }\n        else if (orderStatusVal === 'Canceled' || orderStatusVal === 'Returned') {\n            if (rating <= 1) {\n                paymentStatus = 'Failed';\n            }\n            else {\n                paymentStatus = (paymentMethod === 'Cash') ? 'Pending' : 'Refunded'; // assuming 'Cash' ≈ COD\n            }\n        }\n        else if (orderStatusVal === 'Packed') {\n            paymentStatus = (paymentMethod === 'Cash') ? 'Pending' : 'Paid';\n        }\n        else if (orderStatusVal === 'Ordered' || orderStatusVal === 'Processing') {\n            paymentStatus = 'Pending';\n        }\n        virtualOrderData.push({\n            OrderID: \"ORD-\".concat(1000 + i),\n            OrderDate: orderDate,\n            ShipDate: shippedDate,\n            CustomerID: \"CUS-\".concat(customerId),\n            CustomerName: custName,\n            Email: email,\n            Phone: \"+1-\".concat(randInt(200, 999), \"-\").concat(randInt(1000, 9999)),\n            ShipAddress: \"\".concat(randInt(10, 999), \" \").concat(randChoice(['Main St', 'Market St', '1st Ave', 'Broadway'])),\n            ShipCity: randChoice(cities),\n            ShipState: randChoice(states),\n            ShipPostalCode: String(randInt(10000, 99999)),\n            ShipCountry: randChoice(countries),\n            ProductID: \"PROD-\".concat(randInt(10000, 99999)),\n            ProductName: productName,\n            Category: derivedCategory,\n            Quantity: qty,\n            UnitPrice: unitPrice,\n            Discount: discountPct,\n            Tax: taxPct,\n            SubTotal: amounts.subtotal,\n            TaxAmount: amounts.taxAmount,\n            ShipFee: shippingFee,\n            TotalAmount: amounts.totalAmount,\n            PaymentMethod: paymentMethod,\n            PaymentStatus: paymentStatus,\n            Warehouse: warehouse,\n            InventoryCount: inventoryCount,\n            Priority: priorityVal,\n            OrderStatus: orderStatusVal,\n            Rating: rating,\n        });\n    }\n}\n\nexport default {\n  components: {\n    'ejs-grid': GridComponent,\n    'e-columns': ColumnsDirective,\n    'e-column': ColumnDirective,\n    'ejs-button': ButtonComponent,\n    'ejs-rating': RatingComponent\n  },\n  data: function() {\n    return {\n        flag: true, date1: 0, date2: 0, virtualData: [], timeTaken: 'Time Taken: 0 ms',\n        display: {'display': 'none'},\n        editSettings: { allowEditing: true, allowDeleting: true, newRowPosition: 'Top' },\n        toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],\n        validationRule: { required: true },\n    };\n  },\n  methods: {\n    show: function() {\n        (this as any).display = {'display': 'inline-block'};\n    },\n    hide: function() {\n      if ((this as any).flag && (this as any).date1) {\n        (this as any).date2 = new Date().getTime();\n        (this as any).timeTaken = \"Time Taken: \" + ((this as any).date2 - (this as any).date1) + \"ms\";\n        ((this as any).$refs.grid).ej2Instances.editSettings.allowAdding= true;\n        (this as any).flag = false;\n      }\n      (this as any).display = {'display': 'none'};\n    },\n    onClick: function (args: any) {\n      const loadButton = (((this as any).$refs.loadbtn) as any)?.ej2Instances;           \n      loadButton.disabled = true;    \n      if (!virtualOrderData.length) {\n        (this as any).show();      \n        createVirtualOrderData();\n        (this as any).virtualData = virtualOrderData;\n        (this as any).date1 = new Date().getTime();\n        (this as any).flag = true;\n      }\n    },\n    load: function (args: LoadEventArgs) {\n      if (((this as any).$refs.grid).ej2Instances.enableVirtualization) {\n        args.enableSeamlessScrolling = true;\n      }\n    }\n  },\n  provide: {\n      grid: [VirtualScroll, Toolbar, Edit]\n  }\n};\n</script>"
    },
    {
      "target": "src/components/grid-virtual-scrolling/GridView.vue",
      "content": "<template>\n  <Grid />\n</template>\n\n<script setup>\nimport Grid from '../../components/Grid.vue'\n</script>"
    }
  ]
}