[{"data":1,"prerenderedAt":3172},["ShallowReactive",2],{"locale-alternates":3,"docs-nav-en":124,"api-none":352,"page-en-\u002Fcomponents\u002Fbb-table":353,"pt-showcase-BbTable":2726,"bb-items:v-0-2-1-5-1-4":3118,"bb-items:v-0-2-1-54-1-4":3171},{"\u002Fit\u002Fcomponenti\u002Fbb-accordion":4,"\u002Fen\u002Fcomponents\u002Fbb-accordion":5,"\u002Fit\u002Fcomponenti\u002Fbb-alert":6,"\u002Fen\u002Fcomponents\u002Fbb-alert":7,"\u002Fit\u002Fcomponenti\u002Fbb-asterisk":8,"\u002Fen\u002Fcomponents\u002Fbb-asterisk":9,"\u002Fit\u002Fcomponenti\u002Fbb-avatar":10,"\u002Fen\u002Fcomponents\u002Fbb-avatar":11,"\u002Fit\u002Fcomponenti\u002Fbb-badge":12,"\u002Fen\u002Fcomponents\u002Fbb-badge":13,"\u002Fit\u002Fcomponenti\u002Fbb-base-button":14,"\u002Fen\u002Fcomponents\u002Fbb-base-button":15,"\u002Fit\u002Fcomponenti\u002Fbb-breadcrumbs":16,"\u002Fen\u002Fcomponents\u002Fbb-breadcrumbs":17,"\u002Fit\u002Fcomponenti\u002Fbb-button":18,"\u002Fen\u002Fcomponents\u002Fbb-button":19,"\u002Fit\u002Fcomponenti\u002Fbb-checkbox":20,"\u002Fen\u002Fcomponents\u002Fbb-checkbox":21,"\u002Fit\u002Fcomponenti\u002Fbb-checkbox-group":22,"\u002Fen\u002Fcomponents\u002Fbb-checkbox-group":23,"\u002Fit\u002Fcomponenti\u002Fbb-collapsible":24,"\u002Fen\u002Fcomponents\u002Fbb-collapsible":25,"\u002Fit\u002Fcomponenti\u002Fbb-color-input":26,"\u002Fen\u002Fcomponents\u002Fbb-color-input":27,"\u002Fit\u002Fcomponenti\u002Fbb-color-palette":28,"\u002Fen\u002Fcomponents\u002Fbb-color-palette":29,"\u002Fit\u002Fcomponenti\u002Fbb-confirm":30,"\u002Fen\u002Fcomponents\u002Fbb-confirm":31,"\u002Fit\u002Fcomponenti\u002Fbb-date-picker":32,"\u002Fen\u002Fcomponents\u002Fbb-date-picker":33,"\u002Fit\u002Fcomponenti\u002Fbb-date-picker-input":34,"\u002Fen\u002Fcomponents\u002Fbb-date-picker-input":35,"\u002Fit\u002Fcomponenti\u002Fbb-dialog":36,"\u002Fen\u002Fcomponents\u002Fbb-dialog":37,"\u002Fit\u002Fcomponenti\u002Fbb-dropdown":38,"\u002Fen\u002Fcomponents\u002Fbb-dropdown":39,"\u002Fit\u002Fcomponenti\u002Fbb-dropdown-button":40,"\u002Fen\u002Fcomponents\u002Fbb-dropdown-button":41,"\u002Fit\u002Fcomponenti\u002Fbb-dropzone":42,"\u002Fen\u002Fcomponents\u002Fbb-dropzone":43,"\u002Fit\u002Fcomponenti\u002Fbb-form":44,"\u002Fen\u002Fcomponents\u002Fbb-form":45,"\u002Fit\u002Fcomponenti\u002Fbb-icon":46,"\u002Fen\u002Fcomponents\u002Fbb-icon":47,"\u002Fit\u002Fcomponenti\u002Fbb-indicator":48,"\u002Fen\u002Fcomponents\u002Fbb-indicator":49,"\u002Fit\u002Fcomponenti\u002Fbb-number-input":50,"\u002Fen\u002Fcomponents\u002Fbb-number-input":51,"\u002Fit\u002Fcomponenti\u002Fbb-off-canvas":52,"\u002Fen\u002Fcomponents\u002Fbb-off-canvas":53,"\u002Fit\u002Fcomponenti\u002Fbb-pagination":54,"\u002Fen\u002Fcomponents\u002Fbb-pagination":55,"\u002Fit\u002Fcomponenti\u002Fbb-popover":56,"\u002Fen\u002Fcomponents\u002Fbb-popover":57,"\u002Fit\u002Fcomponenti\u002Fbb-progress":58,"\u002Fen\u002Fcomponents\u002Fbb-progress":59,"\u002Fit\u002Fcomponenti\u002Fbb-radio":60,"\u002Fen\u002Fcomponents\u002Fbb-radio":61,"\u002Fit\u002Fcomponenti\u002Fbb-radio-group":62,"\u002Fen\u002Fcomponents\u002Fbb-radio-group":63,"\u002Fit\u002Fcomponenti\u002Fbb-rating":64,"\u002Fen\u002Fcomponents\u002Fbb-rating":65,"\u002Fit\u002Fcomponenti\u002Fbb-select":66,"\u002Fen\u002Fcomponents\u002Fbb-select":67,"\u002Fit\u002Fcomponenti\u002Fbb-select-popover":68,"\u002Fen\u002Fcomponents\u002Fbb-select-popover":69,"\u002Fit\u002Fcomponenti\u002Fbb-slider":70,"\u002Fen\u002Fcomponents\u002Fbb-slider":71,"\u002Fit\u002Fcomponenti\u002Fbb-smooth-height":72,"\u002Fen\u002Fcomponents\u002Fbb-smooth-height":73,"\u002Fit\u002Fcomponenti\u002Fbb-spinner":74,"\u002Fen\u002Fcomponents\u002Fbb-spinner":75,"\u002Fit\u002Fcomponenti\u002Fbb-switch":76,"\u002Fen\u002Fcomponents\u002Fbb-switch":77,"\u002Fit\u002Fcomponenti\u002Fbb-switch-group":78,"\u002Fen\u002Fcomponents\u002Fbb-switch-group":79,"\u002Fit\u002Fcomponenti\u002Fbb-table":80,"\u002Fen\u002Fcomponents\u002Fbb-table":81,"\u002Fit\u002Fcomponenti\u002Fbb-tabs":82,"\u002Fen\u002Fcomponents\u002Fbb-tabs":83,"\u002Fit\u002Fcomponenti\u002Fbb-tag":84,"\u002Fen\u002Fcomponents\u002Fbb-tag":85,"\u002Fit\u002Fcomponenti\u002Fbb-text-input":86,"\u002Fen\u002Fcomponents\u002Fbb-text-input":87,"\u002Fit\u002Fcomponenti\u002Fbb-textarea":88,"\u002Fen\u002Fcomponents\u002Fbb-textarea":89,"\u002Fit\u002Fcomponenti\u002Fbb-time-picker":90,"\u002Fen\u002Fcomponents\u002Fbb-time-picker":91,"\u002Fit\u002Fcomponenti\u002Fbb-time-picker-input":92,"\u002Fen\u002Fcomponents\u002Fbb-time-picker-input":93,"\u002Fit\u002Fcomponenti\u002Fbb-toast":94,"\u002Fen\u002Fcomponents\u002Fbb-toast":95,"\u002Fit\u002Fcomponenti\u002Fbb-tooltip":96,"\u002Fen\u002Fcomponents\u002Fbb-tooltip":97,"\u002Fit\u002Fcomponenti\u002Fbb-tree":98,"\u002Fen\u002Fcomponents\u002Fbb-tree":99,"\u002Fit\u002Fguide\u002Fai-agents":100,"\u002Fen\u002Fguides\u002Fai-agents":101,"\u002Fit\u002Fguide\u002Fcoherence":102,"\u002Fen\u002Fguides\u002Fcoherence":103,"\u002Fit\u002Fguide\u002Fdesign-language":104,"\u002Fen\u002Fguides\u002Fdesign-language":105,"\u002Fit\u002Fguide\u002Fdesign-tokens":106,"\u002Fen\u002Fguides\u002Fdesign-tokens":107,"\u002Fit\u002Fguide\u002Ffetching-data":108,"\u002Fen\u002Fguides\u002Ffetching-data":109,"\u002Fit\u002Fguide\u002Ficons":110,"\u002Fen\u002Fguides\u002Ficons":111,"\u002Fit\u002Fguide\u002Finertia":112,"\u002Fen\u002Fguides\u002Finertia":113,"\u002Fit\u002Fguide\u002Finstallation":114,"\u002Fen\u002Fguides\u002Finstallation":115,"\u002Fit\u002Fguide\u002Fmigration":116,"\u002Fen\u002Fguides\u002Fmigration":117,"\u002Fit\u002Fguide\u002Fnuxt":118,"\u002Fen\u002Fguides\u002Fnuxt":119,"\u002Fit\u002Fguide\u002Foptions-and-items":120,"\u002Fen\u002Fguides\u002Foptions-and-items":121,"\u002Fit\u002Fguide\u002Fvalidated-forms":122,"\u002Fen\u002Fguides\u002Fvalidated-forms":123},"\u002Fen\u002Fcomponents\u002Fbb-accordion","\u002Fit\u002Fcomponenti\u002Fbb-accordion","\u002Fen\u002Fcomponents\u002Fbb-alert","\u002Fit\u002Fcomponenti\u002Fbb-alert","\u002Fen\u002Fcomponents\u002Fbb-asterisk","\u002Fit\u002Fcomponenti\u002Fbb-asterisk","\u002Fen\u002Fcomponents\u002Fbb-avatar","\u002Fit\u002Fcomponenti\u002Fbb-avatar","\u002Fen\u002Fcomponents\u002Fbb-badge","\u002Fit\u002Fcomponenti\u002Fbb-badge","\u002Fen\u002Fcomponents\u002Fbb-base-button","\u002Fit\u002Fcomponenti\u002Fbb-base-button","\u002Fen\u002Fcomponents\u002Fbb-breadcrumbs","\u002Fit\u002Fcomponenti\u002Fbb-breadcrumbs","\u002Fen\u002Fcomponents\u002Fbb-button","\u002Fit\u002Fcomponenti\u002Fbb-button","\u002Fen\u002Fcomponents\u002Fbb-checkbox","\u002Fit\u002Fcomponenti\u002Fbb-checkbox","\u002Fen\u002Fcomponents\u002Fbb-checkbox-group","\u002Fit\u002Fcomponenti\u002Fbb-checkbox-group","\u002Fen\u002Fcomponents\u002Fbb-collapsible","\u002Fit\u002Fcomponenti\u002Fbb-collapsible","\u002Fen\u002Fcomponents\u002Fbb-color-input","\u002Fit\u002Fcomponenti\u002Fbb-color-input","\u002Fen\u002Fcomponents\u002Fbb-color-palette","\u002Fit\u002Fcomponenti\u002Fbb-color-palette","\u002Fen\u002Fcomponents\u002Fbb-confirm","\u002Fit\u002Fcomponenti\u002Fbb-confirm","\u002Fen\u002Fcomponents\u002Fbb-date-picker","\u002Fit\u002Fcomponenti\u002Fbb-date-picker","\u002Fen\u002Fcomponents\u002Fbb-date-picker-input","\u002Fit\u002Fcomponenti\u002Fbb-date-picker-input","\u002Fen\u002Fcomponents\u002Fbb-dialog","\u002Fit\u002Fcomponenti\u002Fbb-dialog","\u002Fen\u002Fcomponents\u002Fbb-dropdown","\u002Fit\u002Fcomponenti\u002Fbb-dropdown","\u002Fen\u002Fcomponents\u002Fbb-dropdown-button","\u002Fit\u002Fcomponenti\u002Fbb-dropdown-button","\u002Fen\u002Fcomponents\u002Fbb-dropzone","\u002Fit\u002Fcomponenti\u002Fbb-dropzone","\u002Fen\u002Fcomponents\u002Fbb-form","\u002Fit\u002Fcomponenti\u002Fbb-form","\u002Fen\u002Fcomponents\u002Fbb-icon","\u002Fit\u002Fcomponenti\u002Fbb-icon","\u002Fen\u002Fcomponents\u002Fbb-indicator","\u002Fit\u002Fcomponenti\u002Fbb-indicator","\u002Fen\u002Fcomponents\u002Fbb-number-input","\u002Fit\u002Fcomponenti\u002Fbb-number-input","\u002Fen\u002Fcomponents\u002Fbb-off-canvas","\u002Fit\u002Fcomponenti\u002Fbb-off-canvas","\u002Fen\u002Fcomponents\u002Fbb-pagination","\u002Fit\u002Fcomponenti\u002Fbb-pagination","\u002Fen\u002Fcomponents\u002Fbb-popover","\u002Fit\u002Fcomponenti\u002Fbb-popover","\u002Fen\u002Fcomponents\u002Fbb-progress","\u002Fit\u002Fcomponenti\u002Fbb-progress","\u002Fen\u002Fcomponents\u002Fbb-radio","\u002Fit\u002Fcomponenti\u002Fbb-radio","\u002Fen\u002Fcomponents\u002Fbb-radio-group","\u002Fit\u002Fcomponenti\u002Fbb-radio-group","\u002Fen\u002Fcomponents\u002Fbb-rating","\u002Fit\u002Fcomponenti\u002Fbb-rating","\u002Fen\u002Fcomponents\u002Fbb-select","\u002Fit\u002Fcomponenti\u002Fbb-select","\u002Fen\u002Fcomponents\u002Fbb-select-popover","\u002Fit\u002Fcomponenti\u002Fbb-select-popover","\u002Fen\u002Fcomponents\u002Fbb-slider","\u002Fit\u002Fcomponenti\u002Fbb-slider","\u002Fen\u002Fcomponents\u002Fbb-smooth-height","\u002Fit\u002Fcomponenti\u002Fbb-smooth-height","\u002Fen\u002Fcomponents\u002Fbb-spinner","\u002Fit\u002Fcomponenti\u002Fbb-spinner","\u002Fen\u002Fcomponents\u002Fbb-switch","\u002Fit\u002Fcomponenti\u002Fbb-switch","\u002Fen\u002Fcomponents\u002Fbb-switch-group","\u002Fit\u002Fcomponenti\u002Fbb-switch-group","\u002Fen\u002Fcomponents\u002Fbb-table","\u002Fit\u002Fcomponenti\u002Fbb-table","\u002Fen\u002Fcomponents\u002Fbb-tabs","\u002Fit\u002Fcomponenti\u002Fbb-tabs","\u002Fen\u002Fcomponents\u002Fbb-tag","\u002Fit\u002Fcomponenti\u002Fbb-tag","\u002Fen\u002Fcomponents\u002Fbb-text-input","\u002Fit\u002Fcomponenti\u002Fbb-text-input","\u002Fen\u002Fcomponents\u002Fbb-textarea","\u002Fit\u002Fcomponenti\u002Fbb-textarea","\u002Fen\u002Fcomponents\u002Fbb-time-picker","\u002Fit\u002Fcomponenti\u002Fbb-time-picker","\u002Fen\u002Fcomponents\u002Fbb-time-picker-input","\u002Fit\u002Fcomponenti\u002Fbb-time-picker-input","\u002Fen\u002Fcomponents\u002Fbb-toast","\u002Fit\u002Fcomponenti\u002Fbb-toast","\u002Fen\u002Fcomponents\u002Fbb-tooltip","\u002Fit\u002Fcomponenti\u002Fbb-tooltip","\u002Fen\u002Fcomponents\u002Fbb-tree","\u002Fit\u002Fcomponenti\u002Fbb-tree","\u002Fen\u002Fguides\u002Fai-agents","\u002Fit\u002Fguide\u002Fai-agents","\u002Fen\u002Fguides\u002Fcoherence","\u002Fit\u002Fguide\u002Fcoherence","\u002Fen\u002Fguides\u002Fdesign-language","\u002Fit\u002Fguide\u002Fdesign-language","\u002Fen\u002Fguides\u002Fdesign-tokens","\u002Fit\u002Fguide\u002Fdesign-tokens","\u002Fen\u002Fguides\u002Ffetching-data","\u002Fit\u002Fguide\u002Ffetching-data","\u002Fen\u002Fguides\u002Ficons","\u002Fit\u002Fguide\u002Ficons","\u002Fen\u002Fguides\u002Finertia","\u002Fit\u002Fguide\u002Finertia","\u002Fen\u002Fguides\u002Finstallation","\u002Fit\u002Fguide\u002Finstallation","\u002Fen\u002Fguides\u002Fmigration","\u002Fit\u002Fguide\u002Fmigration","\u002Fen\u002Fguides\u002Fnuxt","\u002Fit\u002Fguide\u002Fnuxt","\u002Fen\u002Fguides\u002Foptions-and-items","\u002Fit\u002Fguide\u002Foptions-and-items","\u002Fen\u002Fguides\u002Fvalidated-forms","\u002Fit\u002Fguide\u002Fvalidated-forms",[125,136,145,166,178,220,253,286,307,328,340,346],{"label":126,"entries":127},"Getting started",[128,132],{"title":129,"path":130,"order":131},"Installation","\u002Fguides\u002Finstallation",1,{"title":133,"path":134,"order":135},"Migrating from v2","\u002Fguides\u002Fmigration",2,{"label":137,"entries":138},"Design system",[139,142],{"title":140,"path":141,"order":131},"Design tokens","\u002Fguides\u002Fdesign-tokens",{"title":143,"path":144,"order":135},"Design language","\u002Fguides\u002Fdesign-language",{"label":146,"entries":147},"Playbooks",[148,151,154,158,162],{"title":149,"path":150,"order":131},"Options and items","\u002Fguides\u002Foptions-and-items",{"title":152,"path":153,"order":135},"Fetching data","\u002Fguides\u002Ffetching-data",{"title":155,"path":156,"order":157},"Coherence","\u002Fguides\u002Fcoherence",3,{"title":159,"path":160,"order":161},"Validated forms","\u002Fguides\u002Fvalidated-forms",4,{"title":163,"path":164,"order":165},"Icons","\u002Fguides\u002Ficons",5,{"label":167,"entries":168},"Ecosystem",[169,172,175],{"title":170,"path":171,"order":131},"Inertia and Laravel","\u002Fguides\u002Finertia",{"title":173,"path":174,"order":135},"Nuxt","\u002Fguides\u002Fnuxt",{"title":176,"path":177,"order":157},"AI agents","\u002Fguides\u002Fai-agents",{"label":179,"entries":180},"Inputs",[181,184,187,190,193,196,200,204,208,212,216],{"title":182,"path":183,"component":182,"order":131},"BbBaseButton","\u002Fcomponents\u002Fbb-base-button",{"title":185,"path":186,"component":185,"order":135},"BbButton","\u002Fcomponents\u002Fbb-button",{"title":188,"path":189,"component":188,"order":157},"BbColorInput","\u002Fcomponents\u002Fbb-color-input",{"title":191,"path":192,"component":191,"order":161},"BbDatePickerInput","\u002Fcomponents\u002Fbb-date-picker-input",{"title":194,"path":195,"component":194,"order":165},"BbDropzone","\u002Fcomponents\u002Fbb-dropzone",{"title":197,"path":198,"component":197,"order":199},"BbForm","\u002Fcomponents\u002Fbb-form",6,{"title":201,"path":202,"component":201,"order":203},"BbNumberInput","\u002Fcomponents\u002Fbb-number-input",7,{"title":205,"path":206,"component":205,"order":207},"BbTag","\u002Fcomponents\u002Fbb-tag",8,{"title":209,"path":210,"component":209,"order":211},"BbTextarea","\u002Fcomponents\u002Fbb-textarea",9,{"title":213,"path":214,"component":213,"order":215},"BbTextInput","\u002Fcomponents\u002Fbb-text-input",10,{"title":217,"path":218,"component":217,"order":219},"BbTimePickerInput","\u002Fcomponents\u002Fbb-time-picker-input",11,{"label":221,"entries":222},"Selection",[223,226,229,232,235,238,241,244,247,250],{"title":224,"path":225,"component":224,"order":131},"BbCheckbox","\u002Fcomponents\u002Fbb-checkbox",{"title":227,"path":228,"component":227,"order":135},"BbCheckboxGroup","\u002Fcomponents\u002Fbb-checkbox-group",{"title":230,"path":231,"component":230,"order":157},"BbRadio","\u002Fcomponents\u002Fbb-radio",{"title":233,"path":234,"component":233,"order":161},"BbRadioGroup","\u002Fcomponents\u002Fbb-radio-group",{"title":236,"path":237,"component":236,"order":165},"BbRating","\u002Fcomponents\u002Fbb-rating",{"title":239,"path":240,"component":239,"order":199},"BbSelect","\u002Fcomponents\u002Fbb-select",{"title":242,"path":243,"component":242,"order":203},"BbSelectPopover","\u002Fcomponents\u002Fbb-select-popover",{"title":245,"path":246,"component":245,"order":207},"BbSlider","\u002Fcomponents\u002Fbb-slider",{"title":248,"path":249,"component":248,"order":211},"BbSwitch","\u002Fcomponents\u002Fbb-switch",{"title":251,"path":252,"component":251,"order":215},"BbSwitchGroup","\u002Fcomponents\u002Fbb-switch-group",{"label":254,"entries":255},"Overlay",[256,259,262,265,268,271,274,277,280,283],{"title":257,"path":258,"component":257,"order":131},"BbColorPalette","\u002Fcomponents\u002Fbb-color-palette",{"title":260,"path":261,"component":260,"order":135},"BbConfirm","\u002Fcomponents\u002Fbb-confirm",{"title":263,"path":264,"component":263,"order":157},"BbDatePicker","\u002Fcomponents\u002Fbb-date-picker",{"title":266,"path":267,"component":266,"order":161},"BbDialog","\u002Fcomponents\u002Fbb-dialog",{"title":269,"path":270,"component":269,"order":165},"BbDropdown","\u002Fcomponents\u002Fbb-dropdown",{"title":272,"path":273,"component":272,"order":199},"BbDropdownButton","\u002Fcomponents\u002Fbb-dropdown-button",{"title":275,"path":276,"component":275,"order":203},"BbOffCanvas","\u002Fcomponents\u002Fbb-off-canvas",{"title":278,"path":279,"component":278,"order":207},"BbPopover","\u002Fcomponents\u002Fbb-popover",{"title":281,"path":282,"component":281,"order":211},"BbTimePicker","\u002Fcomponents\u002Fbb-time-picker",{"title":284,"path":285,"component":284,"order":215},"BbTooltip","\u002Fcomponents\u002Fbb-tooltip",{"label":287,"entries":288},"Navigation",[289,292,295,298,301,304],{"title":290,"path":291,"component":290,"order":131},"BbAccordion","\u002Fcomponents\u002Fbb-accordion",{"title":293,"path":294,"component":293,"order":135},"BbBreadcrumbs","\u002Fcomponents\u002Fbb-breadcrumbs",{"title":296,"path":297,"component":296,"order":157},"BbCollapsible","\u002Fcomponents\u002Fbb-collapsible",{"title":299,"path":300,"component":299,"order":161},"BbPagination","\u002Fcomponents\u002Fbb-pagination",{"title":302,"path":303,"component":302,"order":165},"BbTabs","\u002Fcomponents\u002Fbb-tabs",{"title":305,"path":306,"component":305,"order":199},"BbTree","\u002Fcomponents\u002Fbb-tree",{"label":308,"entries":309},"Feedback",[310,313,316,319,322,325],{"title":311,"path":312,"component":311,"order":131},"BbAlert","\u002Fcomponents\u002Fbb-alert",{"title":314,"path":315,"component":314,"order":135},"BbBadge","\u002Fcomponents\u002Fbb-badge",{"title":317,"path":318,"component":317,"order":157},"BbIndicator","\u002Fcomponents\u002Fbb-indicator",{"title":320,"path":321,"component":320,"order":161},"BbProgress","\u002Fcomponents\u002Fbb-progress",{"title":323,"path":324,"component":323,"order":165},"BbSpinner","\u002Fcomponents\u002Fbb-spinner",{"title":326,"path":327,"component":326,"order":199},"BbToast","\u002Fcomponents\u002Fbb-toast",{"label":329,"entries":330},"Data Display",[331,334,337],{"title":332,"path":333,"component":332,"order":131},"BbAvatar","\u002Fcomponents\u002Fbb-avatar",{"title":335,"path":336,"component":335,"order":135},"BbIcon","\u002Fcomponents\u002Fbb-icon",{"title":338,"path":339,"component":338,"order":157},"BbTable","\u002Fcomponents\u002Fbb-table",{"label":341,"entries":342},"Layout & Utility",[343],{"title":344,"path":345,"component":344,"order":131},"BbSmoothHeight","\u002Fcomponents\u002Fbb-smooth-height",{"label":347,"entries":348},"Other",[349],{"title":350,"path":351,"component":350,"order":131},"BbAsterisk","\u002Fcomponents\u002Fbb-asterisk",null,{"id":354,"title":338,"body":355,"component":338,"description":2706,"extension":2707,"group":329,"meta":2708,"navigation":2709,"order":157,"path":339,"sections":2710,"seo":2723,"stem":2724,"__hash__":2725},"docs_en\u002Fcomponents\u002Fbb-table.md",{"type":356,"value":357,"toc":2688},"minimark",[358,416,428,450,458,461,465,480,487,497,500,503,516,522,525,528,579,612,648,651,678,683,694,700,718,721,724,740,788,821,840,850,856,869,872,908,940,981,1004,1019,1029,1032,1046,1052,1058,1061,1091,1116,1126,1137,1140,1161,1174,1179,1184,1186,1222,1250,1256,1259,1297,1306,1312,1319,1322,1375,1407,1418,1421,1448,1481,1487,1497,1500,1516,1547,1566,1572,1577,1580,1612,1630,1636,1665,1680,1711,1717,1731,1734,1757,1763,1780,1790,1803,1809,1812,1821,1838,1856,1862,1872,1875,1924,1933,1950,1967,1973,1976,2072,2090,2135,2214,2459,2478,2544,2561,2599,2603,2612,2615,2649,2668,2684],[359,360,361,369],"when",{},[362,363,364,365,368],"p",{},"Reach for ",[366,367,338],"code",{}," when you have rows of records with columns: an orders\nlisting, a members admin, an audit log. You declare the columns; the component\nowns extraction, formatting, sorting indicators, selection controls, skeletons,\nempty states, detail rows and keyboard navigation.",[370,371,373],"template",{"v-slot:else":372},"",[374,375,376,395,402,409],"ul",{},[377,378,379,384,385,389,390,394],"li",{},[380,381,382],"a",{"href":66},[366,383,239],{},",\n",[380,386,387],{"href":22},[366,388,227],{}," or\n",[380,391,392],{"href":62},[366,393,233],{}," — options are being picked\ninside a form; a selectable table is not a form field",[377,396,397,401],{},[380,398,399],{"href":98},[366,400,305],{}," — the data is genuinely recursive: a file\ntree, nested categories. Flat rows with one level of detail stay here",[377,403,404,408],{},[380,405,406],{"href":68},[366,407,242],{}," — it is a picker that\nopens from a cell",[377,410,411,415],{},[380,412,413],{"href":54},[366,414,299],{}," — you are after the paging\ncontrols",[362,417,418,419,423,424,427],{},"It ",[420,421,422],"strong",{},"reports intent",". Your application owns the rows. Sort, selection, page,\nexpansion and highlight arrive as v-models; apply them in a ",[366,425,426],{},"computed"," or send\nthem to your API.",[429,430,431],"migration",{},[362,432,433,444,445,449],{},[420,434,435,436,439,440,443],{},"In v3 the table is a CSS grid of ",[366,437,438],{},"\u003Cdiv>","s with ARIA roles, not a ",[366,441,442],{},"\u003Ctable>",".","\nThe migration details are collected in ",[380,446,448],{"href":447},"#styling","the styling section",", after\nthe first working application flow.",[451,452,454],"h2",{"id":453},"default",[455,456,457],"span",{},"An async orders list",[362,459,460],{},"Start with the shape most application screens need: an API-backed order list\nwith filtering and server ordering.",[462,463],"demo",{"name":464},"BbTable\u002FAsyncOrders",[362,466,467,468,471,472,475,476,479],{},"The provider forwards ",[366,469,470],{},"status"," and ",[366,473,474],{},"sort"," to the backend. Listing both in\n",[366,477,478],{},"dependencies"," gives the table the request lifecycle: debounce, loading state,\nrefetch and out-of-order response protection. Do not add a parallel watcher.",[362,481,482,483,486],{},"Set ",[366,484,485],{},"item-value"," before adding row state. It is the stable key used by selection,\nexpansion and highlight. Without it, those models compare object references and\nbreak after a refetch replaces the records.",[362,488,489,492,493,496],{},[366,490,491],{},"caption"," names the table for assistive technology. It is visually hidden by\ndefault; add ",[366,494,495],{},"display-caption"," when the page needs a visible title.",[362,498,499],{},"For a local array, the same contract is smaller:",[462,501],{"name":502},"BbTable\u002FBasic",[362,504,505,506,509,510,443],{},"Every row in ",[366,507,508],{},"items"," mounts. A few hundred rows on a client-only screen is fine;\npast roughly a thousand, either page it or add\n",[380,511,513],{"href":512},"#wide-tables",[366,514,515],{},"virtual",[451,517,519],{"id":518},"columns",[455,520,521],{},"The column definition",[362,523,524],{},"Everything a cell needs is declared in the column object, not in markup — which\nis why most tables need no cell slots at all.",[462,526],{"name":527},"BbTable\u002FOrderColumns",[362,529,530,533,534,537,538,541,542,545,546,548,549,552,553,556,557,560,561,564,565,568,569,568,572,575,576,578],{},[366,531,532],{},"key"," extracts the value, and dot paths reach nested fields\n(",[366,535,536],{},"customer.address.city","). ",[366,539,540],{},"formatter(content, key, item)"," transforms it, and it\nruns even when the extracted value is nullish — that is what makes a ",[420,543,544],{},"virtual\ncolumn"," work: give it a ",[366,547,532],{}," that matches no field and compute the cell from\n",[366,550,551],{},"item",". Pass ",[366,554,555],{},"formatOnNull: false"," when a formatter must only ever see real\nvalues. ",[366,558,559],{},"placeholder"," fills the cell when the pipeline still ends nullish, and\n",[366,562,563],{},"align"," (",[366,566,567],{},"left",", ",[366,570,571],{},"center",[366,573,574],{},"right",") sets the column's alignment; the table-level\n",[366,577,563],{}," prop sets the default for all of them.",[362,580,581,582,585,586,471,589,592,593,596,597,600,601,604,605,607,608,611],{},"Two things are ",[420,583,584],{},"not"," columns: ",[366,587,588],{},"actions",[366,590,591],{},"select",". The table renders both\nitself: the selection column from the ",[366,594,595],{},"selectable"," prop, the actions column from\nthe ",[366,598,599],{},"#actions"," slot. Providing the slot is what creates the column; there is no\nprop. Putting ",[366,602,603],{},"{ key: 'actions' }"," in ",[366,606,518],{}," adds an ordinary data column\nreading ",[366,609,610],{},"item.actions",", so you get a stray empty cell next to the real one. Dev\nbuilds warn.",[362,613,614,615,618,619,622,623,626,627,471,629,631,632,635,636,638,639,641,642,638,644,647],{},"Classes come from the same object. ",[366,616,617],{},"thClass"," styles the header cell, ",[366,620,621],{},"tdClass","\nthe data cells, ",[366,624,625],{},"rowClass"," the whole row; ",[366,628,621],{},[366,630,625],{}," may be\nfunctions of ",[366,633,634],{},"(content, key, item)",". The table-level ",[366,637,617],{}," \u002F ",[366,640,621],{}," \u002F\n",[366,643,625],{},[366,645,646],{},"headerRowClass"," props apply everywhere, and a row accumulates the\ntable's classes plus every column's.",[462,649],{"name":650},"BbTable\u002FStockRowClass",[362,652,653,658,659,661,662,665,666,669,670,677],{},[420,654,655,657],{},[366,656,625],{}," on a column is new in v3, and it collides."," In v2 an unknown field\non a column object was inert, so applications parked their own data there — a\nper-column width class named ",[366,660,625],{}," is the common one. ",[366,663,664],{},"ColumnClasses","\nalready accepts a string, so a leftover ",[366,667,668],{},"rowClass: 'w-40'"," still type-checks and\nis now merged onto the whole row instead of doing nothing. Grep your column\ndefinitions before you upgrade; ",[380,671,673,676],{"href":672},"#sorting",[366,674,675],{},"sortable"," has the same\nproblem",", with a type error on top.",[679,680,682],"h3",{"id":681},"column-widths","Column widths",[362,684,685,686,689,690,693],{},"Grid tracks are the width API. Numbers and numeric strings are pixels; values\nwith units pass through. Unspecified columns size to content and share the\nremaining space. Use ",[366,687,688],{},"fixed"," to split that space equally. Declare ",[366,691,692],{},"width"," when\nwrapping or proportions must stay predictable. The migration notes below cover\nthe sizing differences from v2.",[451,695,697],{"id":696},"sorting",[455,698,699],{},"Sortable columns",[362,701,702,703,705,706,709,710,713,714,717],{},"Mark a column ",[366,704,675],{}," and bind ",[366,707,708],{},"v-model:sort",". The model is an ordered array\nof ",[366,711,712],{},"[columnKey, direction]"," entries, and the array order ",[420,715,716],{},"is"," the priority.",[462,719],{"name":720},"BbTable\u002FSortableProducts",[362,722,723],{},"Clicking anywhere on a sortable header — its whitespace included — cycles that\ncolumn unsorted → ascending → descending → removed. A direction flip updates the\nentry in place, so a column keeps its priority in a multi-column sort and no\nother entry is touched. The indicator is one arrow: nothing at rest, faint while\nthe header is hovered or focused, solid once the column is sorted.",[362,725,726,727,729,730,733,734,739],{},"The table reports the model and stops there. Apply it yourself — with a\n",[366,728,426],{}," over your array, as above, or by forwarding it to the server as\n",[366,731,732],{},"orderBy"," and refetching through ",[380,735,737],{"href":736},"#fetching",[366,738,478],{},". Nothing sorts\nbehind your back, which is also why the extra sort button described below is\nvisible rather than dangerous.",[362,741,742,743,746,747,564,750,568,753,756,757,760,761,764,765,768,769,772,773,777,778,781,782,784,785,787],{},"For assistive technology, a sortable header renders a real ",[366,744,745],{},"\u003Cbutton>"," and its\ncell carries ",[366,748,749],{},"aria-sort",[366,751,752],{},"none",[366,754,755],{},"ascending"," or ",[366,758,759],{},"descending","). A custom\n",[366,762,763],{},"#header:\u003Ckey>"," slot ",[420,766,767],{},"replaces"," that button, so keep sorting reachable by\nrendering your own button and calling the scope's ",[366,770,771],{},"toggleSort","; to merely add\nsomething next to the control, use ",[380,774,776],{"href":775},"#cells","the affix slots"," instead. The\ncolumn-level ",[366,779,780],{},"sorted"," field only seeds ",[366,783,749],{}," when no live model entry\nexists — to open pre-sorted, seed ",[366,786,708],{},", as the demo does.",[362,789,790,795,796,799,800,803,804,807,808,811,812,815,816,820],{},[420,791,792,794],{},[366,793,675],{}," is new on the column type in v3, and it breaks in two directions at\nonce."," v2 had no such field, so an application that parked a backend sort key\nthere — ",[366,797,798],{},"type Column = BbTableColumn\u003COrder> & { sortable?: string }"," — now\nintersects ",[366,801,802],{},"boolean & string",", which is ",[366,805,806],{},"never","; every column literal fails with\na message that never mentions ",[366,809,810],{},"BbTableColumn",". And the table coerces the field\n(",[366,813,814],{},"!!column.sortable","), so a sort-key ",[817,818,819],"em",{},"string"," is truthy and turns the built-in\nsort UI on: an application with its own sortable headers draws two.",[822,823,827],"pre",{"className":824,"code":825,"language":826,"meta":372,"style":372},"language-diff shiki shiki-themes github-light-high-contrast github-dark-high-contrast","- type Column = BbTableColumn\u003COrder> & { sortable?: string };\n+ type Column = BbTableColumn\u003COrder> & { sortKey?: string };\n","diff",[366,828,829,835],{"__ignoreMap":372},[455,830,832],{"class":831,"line":131},"line",[455,833,834],{},"- type Column = BbTableColumn\u003COrder> & { sortable?: string };\n",[455,836,837],{"class":831,"line":135},[455,838,839],{},"+ type Column = BbTableColumn\u003COrder> & { sortKey?: string };\n",[362,841,842,845,846,849],{},[366,843,844],{},"Omit\u003CBbTableColumn\u003COrder>, 'sortable'>"," silences the compiler and keeps the\nsecond header. Rename the field, or strip it at the boundary\n(",[366,847,848],{},"columns.map(({ sortable, ...rest }) => rest)",").",[451,851,853],{"id":852},"selection",[455,854,855],{},"Selecting rows",[362,857,858,859,705,861,864,865,868],{},"Add ",[366,860,595],{},[366,862,863],{},"v-model",". Multiple is the default, and in multiple\nmode the model ",[420,866,867],{},"must"," already be an array — the table throws otherwise.",[462,870],{"name":871},"BbTable\u002FSelectableProducts",[362,873,874,875,878,879,882,883,885,886,888,889,892,893,896,897,900,901,904,905,907],{},"A selectable table renders as a ",[366,876,877],{},"\u003Cfieldset>",", so it needs an accessible name.\n",[366,880,881],{},"legend"," is that name; it falls back to ",[366,884,491],{},", then to a localized generic\nstring, so the grouping is never nameless — but a ",[366,887,881],{}," that says what the\nselection is ",[817,890,891],{},"for"," beats both fallbacks. Each row's control carries a visually\nhidden label built from the row's cell contents, prefixed with the localized\n\"select\" word; ",[366,894,895],{},"select-text"," changes that word and ",[366,898,899],{},"accessible-label"," replaces\nthe whole label with your own function of ",[366,902,903],{},"(columns, item)",". The cells arrive in\nrender order, so look them up by ",[366,906,532],{},", never by position.",[362,909,910,911,914,915,918,919,921,922,925,926,929,930,471,933,936,937,939],{},"With ",[366,912,913],{},"name"," set, every selected value renders a hidden input and the table\nsubmits inside a plain ",[366,916,917],{},"\u003Cform>",". ",[366,920,595],{}," also accepts a predicate\n",[366,923,924],{},"(item) => boolean"," to gate individual rows, and ",[366,927,928],{},"max"," caps the count — at the\ncap the unselected checkboxes disable, so a user can always trade one choice for\nanother. ",[366,931,932],{},"item:selected",[366,934,935],{},"item:unselected"," fire per toggle with the row's\nvalue; keep ",[366,938,863],{}," as the state and use the events for side effects.",[362,941,942,945,946,949,950,953,954,957,958,961,962,965,966,969,970,973,974,977,978,980],{},[420,943,944],{},"Select-all is designed for \"everything across every page\"."," The header\ncheckbox is bound with ",[366,947,948],{},"v-model:select-all","; while it is on, every row reads as\nselected and unchecking one ",[420,951,952],{},"adds"," its value to ",[366,955,956],{},"v-model:unselected-items",", so\nyour bulk endpoint receives ",[366,959,960],{},"{ all: true, except: [...] }"," rather than thousands\nof ids. Two consequences follow, and both bite quietly. Turning select-all on\ndoes not re-emit ",[366,963,964],{},"update:modelValue"," when the model is already empty, so never\ninfer \"everything is selected\" from ",[366,967,968],{},"modelValue"," — read ",[366,971,972],{},"select-all"," and\n",[366,975,976],{},"unselected-items",". And the hidden inputs serialize ",[366,979,968],{}," only, so\nall-mode posts nothing at all through a native form; submit it through a handler\ninstead.",[362,982,983,984,987,988,991,992,995,996,999,1000,1003],{},"In v3 the prop that hides the header checkbox inverted: v2's\n",[366,985,986],{},"allow-select-all"," (default ",[366,989,990],{},"true",") is now ",[366,993,994],{},"disable-select-all"," (default\n",[366,997,998],{},"false","). The old name lands in ",[366,1001,1002],{},"$attrs"," and does nothing, so this is silent.",[822,1005,1007],{"className":824,"code":1006,"language":826,"meta":372,"style":372},"- \u003CBbTable selectable :allow-select-all=\"false\" … \u002F>\n+ \u003CBbTable selectable disable-select-all … \u002F>\n",[366,1008,1009,1014],{"__ignoreMap":372},[455,1010,1011],{"class":831,"line":131},[455,1012,1013],{},"- \u003CBbTable selectable :allow-select-all=\"false\" … \u002F>\n",[455,1015,1016],{"class":831,"line":135},[455,1017,1018],{},"+ \u003CBbTable selectable disable-select-all … \u002F>\n",[362,1020,1021,1024,1025,1028],{},[366,1022,1023],{},":multiple=\"false\""," renders radios and the model becomes a single value or\n",[366,1026,1027],{},"null",":",[462,1030],{"name":1031},"BbTable\u002FSinglePlanChoice",[362,1033,1034,1035,1037,1038,1041,1042,1045],{},"Selection tracked by ",[366,1036,485],{}," survives a refetch, but stale ids do not prune\nthemselves. ",[366,1039,1040],{},"enforce-coherence"," drops values whose row is no longer in the result\nset after every load — see ",[380,1043,1044],{"href":736},"Server data and pages"," for the one case\nwhere you must leave it off.",[451,1047,1049],{"id":1048},"states",[455,1050,1051],{},"Loading and empty",[362,1053,1054,1057],{},[366,1055,1056],{},"loading"," means two different things and the table tells them apart.",[462,1059],{"name":1060},"BbTable\u002FLoadingStates",[362,1062,910,1063,1066,1067,1070,1071,568,1074,568,1077,568,1080,568,1083,1086,1087,1090],{},[420,1064,1065],{},"nothing to show yet"," — a first load, or a filter that emptied the table —\nit draws skeleton rows, between four and ten of them, shaped per column by the\n",[366,1068,1069],{},"skeleton"," field (",[366,1072,1073],{},"text",[366,1075,1076],{},"avatar",[366,1078,1079],{},"avatar-text",[366,1081,1082],{},"image",[366,1084,1085],{},"badge","). With ",[420,1088,1089],{},"rows\nalready on screen"," — a refetch, a poll, a save-then-reload — the rows stay put,\ndimmed, under an indeterminate bar along the header. Blanking a populated table\non every refetch loses the reader's place, so it does not happen any more. That\nis a v3 behaviour change: v2 replaced the rows with skeletons every time.",[362,1092,1093,1099,1100,1103,1104,1107,1108,1111,1112,1115],{},[420,1094,1095,1096,443],{},"While loading, the header and the rows are ",[366,1097,1098],{},"inert"," A refetch is about to\nreplace the rows, so editing, selecting or sorting them races the incoming data.\n",[366,1101,1102],{},"interactive-while-loading"," is the escape hatch for a table that must stay usable\nduring a background refresh. The loading announcement is never inert, so the busy\nstate is always conveyed: ",[366,1105,1106],{},"aria-busy"," goes on the table and ",[366,1109,1110],{},"loading-text"," is\nannounced through a polite live region. It is ",[366,1113,1114],{},"sr-only"," — never painted, the\nskeleton carries the visual signal — and it has a localized default, so omitting\nit still announces. Set it when a specific message beats the generic one.",[362,1117,1118,1119,1122,1123,1125],{},"The ",[366,1120,1121],{},"#loading"," slot replaces the ",[420,1124,1069],{},", so it follows the skeleton's rule:\nin v3 it renders on the first load only, never on a refetch. If you used it in v2\nto style refetches, that role is gone — the built-in dim and progress bar covers\nthem now.",[362,1127,1128,1129,1132,1133,1136],{},"When the result is empty, the table shows its no-data row. ",[366,1130,1131],{},"no-data-text","\nreplaces the localized default text; ",[366,1134,1135],{},"#no-data"," replaces the whole content.",[462,1138],{"name":1139},"BbTable\u002FEmptyResult",[362,1141,1142,1143,1146,1147,1150,1151,1154,1155,638,1157,1160],{},"That slot fills the table's ",[420,1144,1145],{},"own"," full-width cell — already centred, already\nspanning every column with an ",[366,1148,1149],{},"aria-colspan"," that counts the selection and\nactions columns. Pass content, not a row. In v2 the slot replaced the empty-state\n",[366,1152,1153],{},"\u003Ctr>",", so anything that was not a row rendered loose and left-aligned; that same\ncontent now centres correctly, and a hand-rolled ",[366,1156,1153],{},[366,1158,1159],{},"\u003Ctd>"," must be deleted\nrather than kept.",[362,1162,1163,1164,1167,1168,1170,1171,1173],{},"There is no ",[366,1165,1166],{},"error-text"," prop and no table-level error state. A failed server\nvisit is a full error page; a rejected ",[366,1169,508],{}," provider is logged, the previous\nrows are kept, and the failure is yours to surface — through ",[366,1172,1135],{}," if the\ntable should say why it is empty.",[451,1175,1177],{"id":1176},"fetching",[455,1178,1044],{},[362,1180,482,1181,1183],{},[366,1182,508],{}," to a function and the table calls it, tracks the loading state and\ndiscards out-of-order responses.",[462,1185],{"name":464},[362,1187,1188,1189,1192,1193,1196,1197,1199,1200,1202,1203,1206,1207,1209,1210,1213,1214,1217,1218,1221],{},"The provider receives ",[366,1190,1191],{},"(prefill, selected)",": ",[366,1194,1195],{},"prefill"," is ",[366,1198,990],{}," on mount and\n",[366,1201,998],{}," on a dependency-driven refetch, and ",[366,1204,1205],{},"selected"," is the current selection,\nwhich is where you reconcile it against the incoming rows. List your filters in\n",[366,1208,478],{}," and never write a ",[366,1211,1212],{},"watch(filter, refetch)"," — dependencies are\ncompared by value, not by reference, so ",[366,1215,1216],{},"[filters]"," refetches when the contents\nchange and not merely when the array identity does. ",[366,1219,1220],{},"deps-debounce-time"," throttles\nthe burst. A plain array bypasses all of this.",[362,1223,1224,1226,1227,384,1229,568,1231,568,1234,1237,1238,1240,1241,1246,1247,1249],{},[366,1225,1040],{}," prunes the row-keyed models — ",[366,1228,863],{},[366,1230,956],{},[366,1232,1233],{},"v-model:highlighted",[366,1235,1236],{},"v-model:expanded-items"," — of\nvalues whose row is gone after each load. Single-value models reset to ",[366,1239,1027],{},".\n",[420,1242,1243,1244,1028],{},"Never combine it with pagination fed through ",[366,1245,478],{}," every page turn\nis a refetch, so a cross-page selection, and the whole select-all plus\n",[366,1248,976],{}," pattern, would be pruned away. On a paginated table, reconcile\nin the provider instead, where both the new rows and the current selection are in\nhand.",[362,1251,1252,1253,1255],{},"The table never slices. Hand it the current page as ",[366,1254,508],{}," and give it the\npaging facts:",[462,1257],{"name":1258},"BbTable\u002FPagedProducts",[362,1260,1261,568,1264,471,1267,1270,1271,1274,1275,1278,1279,568,1281,1283,1284,1286,1287,1289,1290,1292,1293,1296],{},[366,1262,1263],{},"page",[366,1265,1266],{},"per-page",[366,1268,1269],{},"total-items"," are what let the table announce\n",[366,1272,1273],{},"aria-rowcount"," and each row's absolute ",[366,1276,1277],{},"aria-rowindex",", so a screen-reader user\nhears \"row 12 of 26\" rather than \"row 4 of 8\". With an array ",[366,1280,508],{},[366,1282,1266],{},"\nand ",[366,1285,1269],{}," default to its length, so a single-page table is accessible\nwith ",[366,1288,1263],{}," alone. Note that ",[366,1291,1273],{}," now counts the header row —\n",[366,1294,1295],{},"totalItems + 1"," — so a test asserting the old number needs one added.",[362,1298,1299,1300,1302,1303,1305],{},"On a server-driven screen the provider forwards the filters, the sort model and\nthe page, and returns the slice. Do ",[420,1301,584],{}," list the page in ",[366,1304,478],{},": a\nprovider table already refetches when the shared page moves, so list only your\nown filters and sort.",[451,1307,1309],{"id":1308},"cells",[455,1310,1311],{},"Custom cells and headers",[362,1313,1314,1315,1318],{},"Override a column's body with a ",[366,1316,1317],{},"#\u003Ckey>"," slot when the value needs markup rather\nthan a string.",[462,1320],{"name":1321},"BbTable\u002FStatusCells",[362,1323,1324,1325,1327,1328,1331,1332,1334,1335,1338,1339,1341,1342,1345,1346,638,1348,568,1351,638,1354,384,1357,638,1360,638,1363,1366,1367,1370,1371,1374],{},"Keep the column in ",[366,1326,518],{}," even when you fully slot it — its label, alignment\nand width still come from there, and so does the formatter, whose output reaches\nthe slot as ",[366,1329,1330],{},"content",". The scope also carries ",[366,1333,551],{}," (your raw record), ",[366,1336,1337],{},"value","\n(resolved through ",[366,1340,485],{},"), ",[366,1343,1344],{},"classes",", and the row's whole interaction\nsurface: ",[366,1347,1205],{},[366,1349,1350],{},"toggleSelected",[366,1352,1353],{},"highlighted",[366,1355,1356],{},"toggleHighlighted",[366,1358,1359],{},"expanded",[366,1361,1362],{},"toggleExpanded",[366,1364,1365],{},"expandProps",", and ",[366,1368,1369],{},"sortOrder",". The flags are\none-way state; the ",[366,1372,1373],{},"toggle*"," callbacks are the write path.",[362,1376,1377,1383,1384,1196,1387,384,1390,1196,1393,1366,1396,1196,1399,1402,1403,1406],{},[420,1378,1379,1380],{},"The slot name is the key, lowercased, with every run of non-word characters\nturned into ",[366,1381,1382],{},"_",", dashes included. So ",[366,1385,1386],{},"address.city",[366,1388,1389],{},"#address_city",[366,1391,1392],{},"issued-at",[366,1394,1395],{},"#issued_at",[366,1397,1398],{},"issuedAt",[366,1400,1401],{},"#issuedat",", which is why\nsnake_case keys read better here. Building slot names in code? Import the\nnormalizer, ",[366,1404,1405],{},"slotKey",", rather than restating the rule: a hand copy that differs\nby one character makes the slot silently never match.",[362,1408,1409,1411,1412,973,1415,1028],{},[366,1410,763],{}," replaces a header, but that takes the built-in sort button with\nit. To add beside the header instead, use ",[366,1413,1414],{},"#header:\u003Ckey>:prepend",[366,1416,1417],{},"#header:\u003Ckey>:append",[462,1419],{"name":1420},"BbTable\u002FHeaderAffix",[362,1422,1423,1424,638,1427,1430,1431,1434,1435,384,1438,568,1440,568,1442,568,1444,471,1446,443],{},"The table-wide ",[366,1425,1426],{},"#header:prepend",[366,1428,1429],{},"#header:append"," apply one template to every\ndata column's header, never to the structural select and actions cells, and\nreceive ",[366,1432,1433],{},"columnKey"," so they can branch. A per-column affix wins over the\ntable-wide one for that column; they never stack. Header scope is ",[366,1436,1437],{},"label",[366,1439,508],{},[366,1441,675],{},[366,1443,1369],{},[366,1445,771],{},[366,1447,1344],{},[362,1449,1450,1451,568,1454,1457,1458,1461,1462,568,1464,384,1466,568,1469,568,1472,568,1475,568,1478,1480],{},"The structural regions have their own slots: ",[366,1452,1453],{},"#header:select",[366,1455,1456],{},"#header:actions",",\nand ",[366,1459,1460],{},"#select"," to replace a row's checkbox or radio (scope: ",[366,1463,551],{},[366,1465,1337],{},[366,1467,1468],{},"checked",[366,1470,1471],{},"disabled",[366,1473,1474],{},"readonly",[366,1476,1477],{},"inputName",[366,1479,1350],{},"). Replacing the\nselection control is the supported way to change it — rebuilding selection with\nyour own checkbox in a cell slot is not.",[451,1482,1484],{"id":1483},"expand",[455,1485,1486],{},"Detail rows",[362,1488,1489,1490,1492,1493,1496],{},"Track the open rows in ",[366,1491,1236],{}," and render their detail in\n",[366,1494,1495],{},"#expand",", a full-width row below the record it belongs to.",[462,1498],{"name":1499},"BbTable\u002FExpandableOrders",[362,1501,1502,1503,1505,1506,1509,1510,1512,1513,1515],{},"The trigger here is the actions column, created by the ",[366,1504,599],{}," slot and\nlabelled with ",[366,1507,1508],{},"actions-text"," (visually hidden, and localized by default). Its scope hands you\n",[366,1511,1362],{}," — a callback — plus the read-only ",[366,1514,1359],{}," flag. Drive\nopen and close through the callback; mutating the flag does nothing.",[362,1517,1518,1519,1522,1523,1525,1526,471,1529,1532,1533,568,1535,973,1537,1539,1540,1543,1544,1546],{},"For a control that is not a plain button, ",[366,1520,1521],{},"v-bind"," the scope's ",[366,1524,1365],{}," onto\nit: you get ",[366,1527,1528],{},"aria-expanded",[366,1530,1531],{},"aria-controls"," kept in sync, a click handler\nthat stops propagation so the row underneath does not also toggle its highlight,\nand Enter\u002FSpace handling for non-button elements. ",[366,1534,1365],{},[366,1536,1359],{},[366,1538,1362],{}," reach ",[420,1541,1542],{},"every"," cell slot, not just ",[366,1545,599],{},", so a drill-down\ncan put its chevron in the identity column where the eye already is; keep the\nactions column for actions.",[362,1548,482,1549,1551,1552,1554,1555,1557,1558,1561,1562,1565],{},[366,1550,485],{}," so expansion is keyed by id and survives a refetch. A ",[366,1553,338],{},"\ninside ",[366,1556,1495],{}," is independent by default; ",[366,1559,1560],{},"inherit-column-widths"," snaps its\ncolumns onto the parent's tracks so a breakdown reads as a continuation of the\nrow above it, with a column's ",[366,1563,1564],{},"snap"," remapping individual tracks. An inheriting\nchild never scrolls on its own — the parent's scrollport is the only one, which\nis what keeps the two grids locked together.",[451,1567,1569],{"id":1568},"row-interaction",[455,1570,1571],{},"Opening a record",[362,1573,1574,1576],{},[366,1575,1233],{}," marks the row whose details are open. It is parallel to\nselection, not part of it, and it is single by design: one row is \"the open one\".",[462,1578],{"name":1579},"BbTable\u002FMasterDetailOrders",[362,1581,1582,1585,1586,1589,1590,1592,1593,1596,1597,1600,1601,1603,1604,1607,1608,1611],{},[420,1583,1584],{},"Highlight is opt-in, and the model's value is the switch."," ",[366,1587,1588],{},"undefined"," means\n\"never initialised\" and leaves the mechanic off; ",[366,1591,1027],{}," means \"initialised and\ncurrently empty\" and turns it on. So write ",[366,1594,1595],{},"ref(null)",", never ",[366,1598,1599],{},"ref()"," — a\nbound-but-",[366,1602,1588],{}," model warns in dev and stays inert. Unbound, a row click\nemits ",[366,1605,1606],{},"click:row"," and does nothing else: no class, no ",[366,1609,1610],{},"aria-current",", no state.\nThat is deliberate. A table has nowhere to put a highlight it invented, and in v2\nit drove one anyway, into a state the application could neither read nor clear.",[362,1613,1614,1615,1618,1619,1622,1623,1626,1627,1629],{},"A highlighted row carries ",[366,1616,1617],{},"aria-current=\"true\""," and the\n",[366,1620,1621],{},"bb-table-data__row--highlighted"," class, which the shipped stylesheet paints with\na neutral fill and a brand accent bar. ",[366,1624,1625],{},"row-class"," replaces that look, as the demo\ndoes. Clicking the highlighted row again clears it back to ",[366,1628,1027],{},"; clicks inside\ninteractive elements and clicks that end a text selection are ignored, so\ndragging to copy a cell never mutates state.",[362,1631,1632,1635],{},[366,1633,1634],{},"keyboard-navigation"," makes the body a single tab stop with a roving tabindex:\nArrow keys move the focused row, PageUp\u002FPageDown stride ten, Home\u002FEnd jump, and\nEnter or Space activate through the same path as a click. Focus and highlight\nstay independent — arrowing over rows opens nothing until the reader commits.\nScreen readers in browse mode intercept the arrows, so the reader takes the usual\nfocus-mode step first.",[362,1637,1638,1639,1642,1643,1648,1649,1652,1653,1655,1656,1658,1659,1661,1662,1664],{},"Row events fire with ",[366,1640,1641],{},"(event, item)",": the native event and ",[420,1644,1645,1646],{},"your record exactly\nas you passed it in ",[366,1647,508],{},". In v2 the second argument was the table's internal\nrow wrapper, with your record buried at ",[366,1650,1651],{},"row.item",", and a third ",[366,1654,1205],{},"\nboolean followed it. Both are gone. ",[366,1657,1651],{}," is now ",[366,1660,1588],{},", the third\nparameter is ",[366,1663,1588],{},", and a handler typed with three parameters is a type\nerror.",[822,1666,1668],{"className":824,"code":1667,"language":826,"meta":372,"style":372},"- \u003CBbTable @click:row=\"(event, row, selected) => open(row.item, selected)\" \u002F>\n+ \u003CBbTable @click:row=\"(event, item) => open(item, selectedIds.includes(item.id))\" \u002F>\n",[366,1669,1670,1675],{"__ignoreMap":372},[455,1671,1672],{"class":831,"line":131},[455,1673,1674],{},"- \u003CBbTable @click:row=\"(event, row, selected) => open(row.item, selected)\" \u002F>\n",[455,1676,1677],{"class":831,"line":135},[455,1678,1679],{},"+ \u003CBbTable @click:row=\"(event, item) => open(item, selectedIds.includes(item.id))\" \u002F>\n",[362,1681,1682,1683,568,1685,471,1688,1691,1692,1695,1696,1698,1699,1702,1703,1706,1707,1710],{},"Reserve ",[366,1684,1606],{},[366,1686,1687],{},"dblclick:row",[366,1689,1690],{},"contextmenu:row"," for side effects that\nare not navigation. ",[420,1693,1694],{},"Row navigation goes through a real link",", never a row\nhandler: render a ",[366,1697,185],{}," with ",[366,1700,1701],{},"href"," (or ",[366,1704,1705],{},"to"," in a router app) in a cell or\nthe actions column, and the reader gets middle-click and open-in-new-tab for\nfree. Overlays opened from inside a row — a popover, a dropdown, a picker, a\ndialog — swallow their own clicks, so no ",[366,1708,1709],{},"@click.stop"," wrapper is needed around\nthem.",[451,1712,1714],{"id":1713},"wide-tables",[455,1715,1716],{},"Wide, long and dense tables",[362,1718,1719,1722,1723,1726,1727,1730],{},[366,1720,1721],{},"compact"," tightens the row padding. ",[366,1724,1725],{},"fixed-headers"," sticks the header row group\nto the top of the scrollport, and ",[366,1728,1729],{},"fixed: 'left' | 'right'"," on a column definition\npins that column while the rest scrolls horizontally.",[462,1732],{"name":1733},"BbTable\u002FStickyAndPinned",[362,1735,1736,1585,1739,1742,1743,973,1746,1749,1750,1753,1754,1756],{},[420,1737,1738],{},"The table is its own scroll box.",[366,1740,1741],{},".bb-table"," ships ",[366,1744,1745],{},"overflow-x: auto",[366,1747,1748],{},"min-width: 0",", so a table wider than its container scrolls without a wrapper —\nand once you cap its height, it is also the vertical scrollport the stuck header\nand the pinned cells resolve against. Put the ",[366,1751,1752],{},"max-height"," on the table, as the\ndemo does, rather than on a ",[366,1755,438],{}," around it.",[362,1758,1759,1760,1762],{},"What that still cannot do is make room for itself. Inside a flex row an item's\nautomatic minimum size is its own content, so an unconstrained ancestor between\nthe page and the table widens the row instead of letting the table scroll. Give\nthat ancestor ",[366,1761,1748],{}," — and only on the flex row axis; a cross-axis child\nof a column-direction flex parent already has a definite width.",[362,1764,1765,1766,471,1769,1772,1773,1776,1777,443],{},"The pin belongs to the column, so it follows the column through a reorder and a\nhidden pinned column pins nothing. Pin a run from the edge and the offsets add\nup, the second left-pinned column sticking right after the first. The selection\nand actions columns have no definition to carry the field, so they pin through\nthe table with ",[366,1767,1768],{},"fixed-select",[366,1770,1771],{},"fixed-actions",". Pinned cells and the stuck header band are opaque and paint the table's ",[366,1774,1775],{},"--bg","\nlocal, so on a surface that is not the panel colour, ",[380,1778,1779],{"href":447},"set that one\nknob",[362,1781,1782,1783,1786,1787,1789],{},"When content cannot fit, the table keeps every column at its measured minimum —\nits header label included — and overflows rather than clipping. That is by\ndesign. Truncating cells yourself with ",[366,1784,1785],{},"overflow: hidden"," removes that column's\ncontent floor, so declare a ",[366,1788,692],{}," on any column you truncate.",[362,1791,1792,1793,1795,1796,1798,1799,1802],{},"On a phone, collapse rather than scroll: a ten-column ops table as a horizontal\nscroller loses the identity column first, which is the one thing the reader is\nlooking for. Drop the secondary keys from ",[366,1794,518],{}," at the breakpoint and stack\nwhat survives into the identity cell. Do ",[420,1797,584],{}," hide cells with ",[366,1800,1801],{},"display: none","\n— a hidden grid item leaves its track in place and every following cell shifts\none column over.",[362,1804,1805,1806,1808],{},"Once the list is long, ",[366,1807,515],{}," windows the body:",[462,1810],{"name":1811},"BbTable\u002FVirtualRows",[362,1813,1814,1815,1817,1818,1820],{},"Only the rows in the scrollport plus a few on each side are mounted; two spacer\nrows hold the scrollport at the full height. Give it a scroller by bounding the\nheight, as above; left unbounded, the page becomes the scroller. ",[366,1816,515],{},"\nimplies a stuck header, because a windowed body without column names is a\nscroller rather than a table. Rows keep their absolute ",[366,1819,1277],{},", focus is\nnever lost to an unmount, and row heights stay dynamic.",[362,1822,1823,1824,1827,1828,1830,1831,1833,1834,1837],{},"One constraint is worth designing around: ",[420,1825,1826],{},"columns are sized once",". A windowed\nbody only ever holds a few rows, so the first rendered batch is measured and\nthose widths become floors. The cells of those columns then clip with an ellipsis\ninstead of wrapping, so a longer value arriving later never spills into its\nneighbour. A column that must wrap — prose, notes — needs a declared ",[366,1829,692],{},",\nwhich wins as always. Nested tables inside expand rows are never windowed, and\n",[366,1832,515],{}," is ignored on a table that inherits its widths or that replaces\n",[366,1835,1836],{},"#tbody",". Browser find only reaches mounted rows, which was a deliberate call.",[362,1839,1840,1841,1844,1845,1366,1848,1851,1852,1855],{},"If the reader needs to move or size the columns themselves, ",[366,1842,1843],{},"reorderable"," makes\neach header a drag handle writing ",[366,1846,1847],{},"v-model:order",[366,1849,1850],{},"resizable"," puts a grip on\neach header's trailing edge reporting through ",[366,1853,1854],{},"@resize:column",". Both are\ndocumented on the API page.",[451,1857,1859],{"id":1858},"external-control",[455,1860,1861],{},"Driving the table from outside",[362,1863,1864,1865,471,1868,1871],{},"Give the table an ",[366,1866,1867],{},"id",[366,1869,1870],{},"useBbTableContext(id)"," hands you a live, two-way\nhandle on its state from anywhere on the page — no prop drilling, no template\nrefs.",[462,1873],{"name":1874},"BbTable\u002FBulkActionBar",[362,1876,1877,1878,568,1880,568,1883,568,1886,568,1888,384,1890,568,1892,568,1895,471,1898,1901,1902,1905,1906,1908,1909,1912,1913,384,1916,568,1918,568,1920,1923],{},"The handle mirrors ",[366,1879,1205],{},[366,1881,1882],{},"unselected",[366,1884,1885],{},"all",[366,1887,1353],{},[366,1889,474],{},[366,1891,1263],{},[366,1893,1894],{},"perPage",[366,1896,1897],{},"totalItems",[366,1899,1900],{},"totalPages",", each a writable computed: read\n",[366,1903,1904],{},".value",", assign ",[366,1907,1904],{}," to drive the table. It works ",[817,1910,1911],{},"alongside"," the v-models\nrather than instead of them, so a table can be bound normally and still be\nreadable from a toolbar. Every field returns a stable empty baseline — ",[366,1914,1915],{},"[]",[366,1917,998],{},[366,1919,1027],{},[366,1921,1922],{},"0"," — even before the table mounts, so nothing needs a guard.",[362,1925,1926,1928,1929,1932],{},[366,1927,299],{}," joins the same context through its ",[366,1930,1931],{},"table-id"," prop, which is the\nzero-wiring alternative to sharing a page ref: the paging props are symmetric\nacross the pair, so the server's numbers can go to whichever component is\nconvenient.",[362,1934,1935,1936,1941,1942,1945,1946,1949],{},"Two things to know before you debug it. ",[420,1937,1118,1938,1940],{},[366,1939,1867],{}," is a rendezvous key and a typo\ndoes not error"," — it silently creates a second state node, so your toolbar looks\nalive while nothing reaches the table. If a bulk bar \"works\" but the table never\nreacts, check the spelling first; ",[366,1943,1944],{},"isReady"," only tells you whether paging data is\nreal, not whether a table is attached. And the context is ",[420,1947,1948],{},"client-side only",":\nduring SSR the handle operates on detached state, and cross-component wiring\nstarts at hydration.",[362,1951,1952,1953,1658,1956,1959,1960,1963,1964,1966],{},"If you wrote against the v3 alphas, the row count on the handle was renamed:\n",[366,1954,1955],{},"ctx.total",[366,1957,1958],{},"ctx.totalItems",", everywhere including the ",[366,1961,1962],{},"initial"," seed.\nReading the old name yields ",[366,1965,1588],{}," and assigning to it throws.",[451,1968,1970],{"id":1969},"styling",[455,1971,1972],{},"The grid substrate and its styling hooks",[362,1974,1975],{},"Style the table through its classes and its ARIA roles. Element names match\nnothing.",[429,1977,1978,1986,2061],{},[362,1979,1980,1982,1983,1985],{},[366,1981,338],{}," now renders role-complete ",[366,1984,438],{}," elements as a CSS grid. Props,\nslots, events and models did not change, but markup-dependent behavior did:",[374,1987,1988,2010,2027,2032,2035,2043,2046,2053,2056],{},[377,1989,1990,1991,568,1994,568,1997,568,2000,568,2003,568,2006,2009],{},"Element selectors (",[366,1992,1993],{},"table",[366,1995,1996],{},"thead",[366,1998,1999],{},"tbody",[366,2001,2002],{},"tr",[366,2004,2005],{},"th",[366,2007,2008],{},"td",") and global\ntable CSS no longer match.",[377,2011,2012,568,2015,471,2017,2020,2021,2023,2024,2026],{},[366,2013,2014],{},"#thead",[366,2016,1836],{},[366,2018,2019],{},"#tfoot"," require ",[366,2022,438],{}," rows with the correct ARIA\nroles. A ",[366,2025,1153],{}," inside the grid cannot land on its tracks.",[377,2028,2029,2030,443],{},"Browser copy produces one value per line. Build “copy as TSV” from ",[366,2031,508],{},[377,2033,2034],{},"Printed grids do not repeat their header. Use a print-specific report view.",[377,2036,2037,2039,2040,2042],{},[366,2038,491],{}," is now a ",[366,2041,438],{}," before the grid root, with the same accessible\nname.",[377,2044,2045],{},"Flexible surplus is shared equally, not by content. The measured 748px\u002F52px\npair becomes 544px\u002F256px. In narrow containers, the longest flexible column\ncan be about 22% narrower; mixing fixed and flexible tracks can move a column\nby about 19px.",[377,2047,2048,2049,2052],{},"A cell that scrolls no longer floors its track. Ellipsis works, but the old\n",[366,2050,2051],{},"max-width: 0"," trick collapses the cell to its padding.",[377,2054,2055],{},"Percent widths in overflow resolve against the grid's min-content width. The\nmeasured 30% column changes from 181px to 303px. Non-overflowing tables do\nnot change.",[377,2057,910,2058,2060],{},[366,2059,688],{},", undeclared widths split the available space equally. If every\ncolumn has a width, remaining space follows those proportions; selection and\nactions stay at content width.",[362,2062,2063,2064,2067,2068,2071],{},"The layout requires subgrid (Chrome\u002FEdge 117, Firefox 71, Safari 16). Vertical\ncentering through block ",[366,2065,2066],{},"align-content"," requires Chrome 123, Safari 17.4 or\nFirefox 125; older versions top-align cell content. There is no ",[366,2069,2070],{},"@supports","\nfallback.",[362,2073,2074,2079,2080,2082,2083,2086,2087,2089],{},[420,2075,2076,2077],{},"The surface is ",[366,2078,1775],{},", a local on ",[366,2081,1741],{}," defaulting to\n",[366,2084,2085],{},"var(--bb-panel)",". Cells are transparent at rest so the row can tint them, but\nanything that slides over scrolled content — the stuck header band, pinned cells\n— is opaque and paints ",[366,2088,1775],{},". Set it once when the table sits on another\nsurface and everything pinned follows:",[822,2091,2095],{"className":2092,"code":2093,"language":2094,"meta":372,"style":372},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast",".my-card .bb-table {\n    --bg: var(--card-bg);\n}\n","css",[366,2096,2097,2110,2130],{"__ignoreMap":372},[455,2098,2099,2103,2106],{"class":831,"line":131},[455,2100,2102],{"class":2101},"s-5SL",".my-card",[455,2104,2105],{"class":2101}," .bb-table",[455,2107,2109],{"class":2108},"suds8"," {\n",[455,2111,2112,2116,2118,2121,2124,2127],{"class":831,"line":135},[455,2113,2115],{"class":2114},"soyes","    --bg",[455,2117,1192],{"class":2108},[455,2119,2120],{"class":2101},"var",[455,2122,2123],{"class":2108},"(",[455,2125,2126],{"class":2114},"--card-bg",[455,2128,2129],{"class":2108},");\n",[455,2131,2132],{"class":831,"line":157},[455,2133,2134],{"class":2108},"}\n",[362,2136,2137,2138,2140,2141,564,2144,568,2147,2150,2151,1341,2153,564,2156,568,2159,1341,2162,564,2165,568,2168,2171,2172,564,2175,2177,2178,641,2181,638,2183,2186,2187,2190,2191,2194,2195,2198,2199,2202,2203,973,2206,2209,2210,2213],{},"The other locals on ",[366,2139,1741],{}," are ",[366,2142,2143],{},"--padding-x",[366,2145,2146],{},"12px",[366,2148,2149],{},"8px"," when\n",[366,2152,1721],{},[366,2154,2155],{},"--padding-y",[366,2157,2158],{},"6px",[366,2160,2161],{},"4px",[366,2163,2164],{},"--cell-h",[366,2166,2167],{},"36px",[366,2169,2170],{},"32px",") and\n",[366,2173,2174],{},"--actions-spacing",[366,2176,2149],{},"). Note that these tightened in v3 from v2's ",[366,2179,2180],{},"16px",[366,2182,2149],{},[366,2184,2185],{},"42px",". Everything the table ",[817,2188,2189],{},"publishes"," — the per-track bridge a nested\ntable reads, the edge offsets — lost its ",[366,2192,2193],{},"bb-"," prefix in v3\n(",[366,2196,2197],{},"--bb-table-offset-start"," → ",[366,2200,2201],{},"--offset-start",", and so on), and ",[366,2204,2205],{},"--fill",[366,2207,2208],{},"--natural-width"," were removed outright. All of them fail silently, so grep your\nCSS and any style-scanning JavaScript for ",[366,2211,2212],{},"--bb-table-","; no name with that prefix\nexists any more.",[1993,2215,2216,2229],{},[1996,2217,2218],{},[2002,2219,2220,2223,2226],{},[2005,2221,2222],{},"Region",[2005,2224,2225],{},"Class",[2005,2227,2228],{},"Role",[1999,2230,2231,2243,2257,2269,2284,2299,2322,2336,2353,2370,2384,2404,2423,2442],{},[2002,2232,2233,2236,2240],{},[2008,2234,2235],{},"container",[2008,2237,2238],{},[366,2239,1741],{},[2008,2241,2242],{},"—",[2002,2244,2245,2248,2253],{},[2008,2246,2247],{},"grid root",[2008,2249,2250],{},[366,2251,2252],{},".bb-table__table",[2008,2254,2255],{},[366,2256,1993],{},[2002,2258,2259,2261,2266],{},[2008,2260,491],{},[2008,2262,2263],{},[366,2264,2265],{},".bb-table-caption",[2008,2267,2268],{},"— (before the root)",[2002,2270,2271,2274,2279],{},[2008,2272,2273],{},"header group",[2008,2275,2276],{},[366,2277,2278],{},".bb-table__head",[2008,2280,2281],{},[366,2282,2283],{},"rowgroup",[2002,2285,2286,2289,2294],{},[2008,2287,2288],{},"header row",[2008,2290,2291],{},[366,2292,2293],{},".bb-table-header-row",[2008,2295,2296],{},[366,2297,2298],{},"row",[2002,2300,2301,2304,2317],{},[2008,2302,2303],{},"header cell",[2008,2305,2306,2309,2310,568,2313,2316],{},[366,2307,2308],{},".bb-table-header"," (+ ",[366,2311,2312],{},"--select",[366,2314,2315],{},"--actions",")",[2008,2318,2319],{},[366,2320,2321],{},"columnheader",[2002,2323,2324,2327,2332],{},[2008,2325,2326],{},"body group",[2008,2328,2329],{},[366,2330,2331],{},".bb-table__body",[2008,2333,2334],{},[366,2335,2283],{},[2002,2337,2338,2341,2349],{},[2008,2339,2340],{},"data row",[2008,2342,2343,2309,2346,2316],{},[366,2344,2345],{},".bb-table-data__row",[366,2347,2348],{},"--highlighted",[2008,2350,2351],{},[366,2352,2298],{},[2002,2354,2355,2358,2365],{},[2008,2356,2357],{},"data cell",[2008,2359,2360,2309,2363,2316],{},[366,2361,2362],{},".bb-table-data__cell",[366,2364,2312],{},[2008,2366,2367],{},[366,2368,2369],{},"cell",[2002,2371,2372,2375,2380],{},[2008,2373,2374],{},"actions cell",[2008,2376,2377],{},[366,2378,2379],{},".bb-table__cell--actions",[2008,2381,2382],{},[366,2383,2369],{},[2002,2385,2386,2389,2398],{},[2008,2387,2388],{},"expand row",[2008,2390,2391,2394,2395],{},[366,2392,2393],{},".bb-table-expand__row"," > ",[366,2396,2397],{},".bb-table-expand__cell",[2008,2399,2400,2394,2402],{},[366,2401,2298],{},[366,2403,2369],{},[2002,2405,2406,2409,2417],{},[2008,2407,2408],{},"empty state",[2008,2410,2411,2394,2414],{},[366,2412,2413],{},".bb-table-no-data__row",[366,2415,2416],{},".bb-table-no-data__cell",[2008,2418,2419,2394,2421],{},[366,2420,2298],{},[366,2422,2369],{},[2002,2424,2425,2428,2436],{},[2008,2426,2427],{},"skeleton row",[2008,2429,2430,2394,2433],{},[366,2431,2432],{},".bb-table-skeleton__row",[366,2434,2435],{},".bb-table-skeleton__cell",[2008,2437,2438,2394,2440],{},[366,2439,2298],{},[366,2441,2369],{},[2002,2443,2444,2447,2452],{},[2008,2445,2446],{},"footer group",[2008,2448,2449],{},[366,2450,2451],{},".bb-table__foot",[2008,2453,2454,2456,2457],{},[366,2455,2283],{}," only with ",[366,2458,2019],{},[362,2460,2461,568,2464,471,2467,2470,2471,1283,2474,2477],{},[366,2462,2463],{},"[role='row']",[366,2465,2466],{},"[role='cell']",[366,2468,2469],{},"[role='columnheader']"," are supported hooks,\nnot incidental markup — use them when you mean \"every row kind\", and the classes\nwhen you mean one kind. Cells are direct children of their row, so ",[366,2472,2473],{},":first-child",[366,2475,2476],{},":nth-child(n)"," address columns.",[362,2479,2480,2481,2198,2483,568,2485,2487,2488,568,2490,2198,2492,568,2494,2198,2497,384,2499,2198,2501,568,2503,2198,2505,1702,2507,2509,2510,2512,2513,2487,2515,568,2517,2198,2519,918,2521,973,2523,2526,2527,2530,2531,2533,2534,638,2537,2540,2541,2543],{},"Translating a v2 stylesheet: ",[366,2482,1993],{},[366,2484,2252],{},[366,2486,1996],{}," →\n",[366,2489,2278],{},[366,2491,1999],{},[366,2493,2331],{},[366,2495,2496],{},"tfoot",[366,2498,2451],{},[366,2500,491],{},[366,2502,2265],{},[366,2504,2002],{},[366,2506,2463],{},[366,2508,2345],{},"\nwhen you meant data rows only — a bare ",[366,2511,2002],{}," matched every row kind), ",[366,2514,2005],{},[366,2516,2308],{},[366,2518,2008],{},[366,2520,2362],{},[366,2522,2473],{},[366,2524,2525],{},":last-child"," carry over verbatim, ",[366,2528,2529],{},"td:nth-of-type(n)"," becomes ",[366,2532,2476],{},"\nsince the children are type-uniform now, and ",[366,2535,2536],{},"colgroup",[366,2538,2539],{},"col"," are gone —\ndeclare ",[366,2542,692],{}," on the column instead.",[362,2545,2546,2547,2549,2550,2552,2553,2556,2557,2560],{},"Watch the specificity while you translate. ",[366,2548,2466],{}," is an attribute\nselector, ",[366,2551,2008],{}," was a type selector, so the translated rule is ",[817,2554,2555],{},"stronger"," than the\none it replaces and an override that used to lose by one point can now win. The\nlibrary holds its own body-cell rules at two classes deliberately, so an override\nthat beat ",[366,2558,2559],{},".bb-table tbody tr td"," at that weight still wins; the one band that\nloses ground is a rule of exactly one class plus type selectors. Give it one more\nclass.",[362,2562,2563,2564,471,2567,2570,2571,1585,2574,1585,2577,2580,2581,2584,2585,2588,2589,2592,2593,2595,2596,2598],{},"Some geometry is not yours to change: ",[366,2565,2566],{},"display: grid",[366,2568,2569],{},"gap: 0"," on the root,\nthe row groups and the rows; ",[366,2572,2573],{},"grid-column: 1 \u002F -1",[420,2575,2576],{},"and",[366,2578,2579],{},"contain: inline-size","\non the full-width cells, without which expand-row content resizes the parent's\ncolumns; ",[366,2582,2583],{},"white-space: nowrap"," on the actions cell, which is what makes its\n",[366,2586,2587],{},"max-content"," track the width of the controls side by side; and ",[366,2590,2591],{},"position: sticky"," on ",[366,2594,2278],{}," under ",[366,2597,1725],{}," — sticky lives on the row\ngroup, because a sticky cell inside a subgrid cannot stick in any engine.",[679,2600,2602],{"id":2601},"replacing-a-whole-row-group","Replacing a whole row group",[362,2604,2605,568,2607,471,2609,2611],{},[366,2606,2014],{},[366,2608,1836],{},[366,2610,2019],{}," hand you a region, and the markup you pass is\ngrid markup:",[462,2613],{"name":2614},"BbTable\u002FFooterTotals",[362,2616,2617,2618,2621,2622,2625,2626,2629,2630,2633,2634,2636,2637,918,2640,2642,2643,2646,2647,443],{},"One ",[366,2619,2620],{},"\u003Cdiv role=\"row\">"," per row, holding one ",[366,2623,2624],{},"\u003Cdiv role=\"cell\">"," — or\n",[366,2627,2628],{},"role=\"columnheader\""," in the head — per column. Rows are subgrid rows, so a cell\ntakes its column track without a width of its own, and a spanning cell uses\n",[366,2631,2632],{},"grid-column"," plus ",[366,2635,1149],{}," rather than ",[366,2638,2639],{},"colspan",[366,2641,2019],{}," receives\n",[366,2644,2645],{},"columnCount",", the total rendered columns with the selection and actions columns\nincluded. A full-width row is ",[366,2648,2573],{},[362,2650,2651,2654,2655,2657,2658,2660,2661,2663,2664,2667],{},[420,2652,2653],{},"Nothing lints this."," A slot ported from ",[366,2656,1153],{},"\u002F",[366,2659,1159],{}," to plain ",[366,2662,438],{},"s\nwithout roles renders perfectly and ships a table that a screen reader reads as a\npile of generic boxes. The role chain ",[366,2665,2666],{},"table → rowgroup → row → columnheader | cell"," is the whole of the table semantics here; if you replace a region, you own\nit.",[362,2669,2670,2671,2673,2674,2677,2678,2680,2681,2683],{},"Two side effects of replacing the header specifically: the table measures its\ncolumn tracks off the header cells, so with a custom ",[366,2672,2014],{}," it falls back to\nthe first row that has one child per track — which means ",[420,2675,2676],{},"a custom header over\nan empty table publishes no tracks",", and a nested table cannot inherit from it\nuntil rows arrive. And under ",[366,2679,1725],{}," a multi-row ",[366,2682,2014],{}," now sticks as a\nblock, where the old cell-level sticky stacked its rows on top of each other.",[2685,2686,2687],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .soyes, html code.shiki .soyes{--shiki-default:#702C00;--shiki-dark:#FFB757}",{"title":372,"searchDepth":157,"depth":157,"links":2689},[2690,2691,2694,2695,2696,2697,2698,2699,2700,2701,2702,2703],{"id":453,"depth":135,"text":457},{"id":518,"depth":135,"text":521,"children":2692},[2693],{"id":681,"depth":157,"text":682},{"id":696,"depth":135,"text":699},{"id":852,"depth":135,"text":855},{"id":1048,"depth":135,"text":1051},{"id":1176,"depth":135,"text":1044},{"id":1308,"depth":135,"text":1311},{"id":1483,"depth":135,"text":1486},{"id":1568,"depth":135,"text":1571},{"id":1713,"depth":135,"text":1716},{"id":1858,"depth":135,"text":1861},{"id":1969,"depth":135,"text":1972,"children":2704},[2705],{"id":2601,"depth":157,"text":2602},"The column-driven data table — sorting, selection, detail rows, server data and virtual scrolling, rendered as a CSS grid with ARIA roles.","md",{},true,[2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722],{"id":453,"title":457},{"id":518,"title":521},{"id":696,"title":699},{"id":852,"title":855},{"id":1048,"title":1051},{"id":1176,"title":1044},{"id":1308,"title":1311},{"id":1483,"title":1486},{"id":1568,"title":1571},{"id":1713,"title":1716},{"id":1858,"title":1861},{"id":1969,"title":1972},{"title":338,"description":2706},"components\u002Fbb-table","oHfRc0X33kvvFXNNjSE-FQ6SeMrl4vIDV2LT8iFWCgE",{"name":338,"slug":2727,"group":329,"description":2728,"entrypoint":2729,"docs":2730,"props":2733,"models":2952,"events":2965,"slots":3006,"exposed":3068,"pt":3069,"validated":352,"migration":3093},"bb-table","Displays tabular data, configurable columns and data mapper.","bitboss-ui",{"contract":2731,"source":2732},"ai\u002FBbTable.md","ai\u002Fsource\u002FBbTable.md",[2734,2740,2744,2748,2751,2755,2758,2761,2765,2767,2771,2774,2778,2782,2784,2787,2790,2794,2797,2800,2803,2807,2810,2814,2818,2822,2825,2828,2832,2835,2837,2840,2842,2847,2851,2854,2856,2860,2863,2865,2867,2869,2871,2873,2875,2877,2879,2881,2883,2885,2887,2889,2891,2893,2896,2898,2900,2902,2904,2906,2908,2910,2912,2914,2916,2920,2923,2926,2930,2933,2936,2939,2941,2944,2946,2949],{"name":2735,"type":2736,"required":2737,"default":352,"description":2738,"note":2739,"demo":852},"accessibleLabel","((columns: MappedCell[], item: any) => string) | undefined",false,"Function that accepts the columns and the current item as\narguments and returns a label to be used for accessibility purposes.\nThe cells arrive in RENDER order (they follow `order`, so the\nlabel reads like the row) — look a cell up by `key`, never by position.","Called with the mapped cells in render order, so look a cell up by `key` rather than by position — `order` and `reorderable` both move them.",{"name":2741,"type":2742,"required":2737,"default":352,"description":2743,"note":352,"demo":352},"actionsText","string | undefined","Label used in the header of the actions column.",{"name":563,"type":2745,"required":2737,"default":2746,"description":2747,"note":352,"demo":352},"\"left\" | \"center\" | \"right\" | undefined","\"left\"","Text alignment of the columns.",{"name":491,"type":2742,"required":2737,"default":352,"description":2749,"note":2750,"demo":453},"Caption that describes the content of the table. Used for accessibility purposes.","The table's accessible name, and the fallback name of the `\u003Cfieldset>` a selectable table renders. Visually hidden unless `display-caption` is set. In v3 it is a `\u003Cdiv>` before the grid root rather than a `\u003Ccaption>` inside it.",{"name":518,"type":2752,"required":2737,"default":1915,"description":2753,"note":2754,"demo":518},"BbTableColumn\u003CT>[] | undefined","Array of definitions of how the columns should be rendered.","Write these as `BbTableColumn\u003CYourItem>[]`. A column carries extraction (`key`, dot paths allowed), formatting (`formatter`, `placeholder`, `formatOnNull`), presentation (`label`, `align`, `width`, `skeleton`) and styling (`thClass`, `tdClass`, `rowClass`). `actions` and `select` are not columns: the `#actions` slot creates the actions column and `selectable` the selection one, so a column with either key only adds a stray data cell. Pin a column with `fixed: 'left' | 'right'` on its definition.",{"name":1721,"type":2756,"required":2737,"default":998,"description":2757,"note":352,"demo":352},"boolean | undefined","Adds a CSS class that applies a compact style to the component.",{"name":478,"type":2759,"required":2737,"default":1915,"description":2760,"note":352,"demo":352},"unknown[] | undefined","Defines an array of dependencies that will trigger actions in the component upon change.",{"name":2762,"type":2763,"required":2737,"default":1922,"description":2764,"note":352,"demo":352},"depsDebounceTime","number | undefined","Timeout used to debounce response to changes to dependencies.",{"name":1471,"type":2756,"required":2737,"default":998,"description":2766,"note":352,"demo":352},"Disables the component",{"name":2768,"type":2756,"required":2737,"default":998,"description":2769,"note":2770,"demo":852},"disableSelectAll","Hides the \"Select all\" checkbox that selectable multi-row tables\ndisplay by default.","Replaces v2's `allow-select-all`, with the polarity inverted: `allow-select-all=\"false\"` becomes `disable-select-all`. The old name lands in `$attrs` and does nothing, so the change is silent.",{"name":2772,"type":2756,"required":2737,"default":998,"description":2773,"note":352,"demo":352},"displayCaption","Boolean that defines whether to display or hide the caption.\nBy default is true and the caption is hidden.",{"name":2775,"type":2756,"required":2737,"default":998,"description":2776,"note":2777,"demo":1176},"enforceCoherence","After every load (initial, `dependencies` refetch or a change of the\n`items` array) prunes the row-keyed models of values whose row is no\nlonger in the result set: `modelValue`, `unselected-items`,\n`highlighted` and `expanded-items`. Values whose rows are still present\nsurvive. Single-value models (`modelValue` without `multiple`, and\n`highlighted`, which is always single) reset to `null`.\n\nDo **not** enable it on paginated tables where the page feeds\n`dependencies`: every page turn is a refetch, so state held on rows of\nother pages (the `select-all` + `unselected-items` pattern, cross-page\nselections) would be pruned. Reconcile in the items provider instead.","Leave it off on any table whose page turn goes through `dependencies` — every page is a refetch, so a cross-page selection would be pruned away. Reconcile in the provider instead, which receives the current selection for exactly this reason.",{"name":2779,"type":2780,"required":2737,"default":1915,"description":2781,"note":352,"demo":352},"expandedItems","any[] | undefined","Used by `v-model:expandedItems`. Array of the currently expanded items —\ntoggled by the row expand control and by external writes (mirrors the\n`highlighted`\u002F`sort` v-model surfaces). Drives the `#expand` slot rows and\ntheir `aria-expanded`\u002F`aria-controls` wiring.",{"name":688,"type":2756,"required":2737,"default":998,"description":2783,"note":352,"demo":352},"Splits the width equally among the columns that declare no `width`\n(each undeclared column becomes a `minmax(0, 1fr)` track)\nmaking each column take up the same amount of space.",{"name":2785,"type":2756,"required":2737,"default":998,"description":2786,"note":352,"demo":352},"fixedActions","Pins the actions column (the one the `#actions` slot creates) to the\nright edge, `position: sticky`, in place. Data columns pin through\n`column.fixed`; this is the same feature for the structural column that\nhas no definition to carry it. No effect without an `#actions` slot.",{"name":2788,"type":2756,"required":2737,"default":998,"description":2789,"note":352,"demo":352},"fixedHeaders","Boolean that sets the headers as sticky to the top of the table.",{"name":2791,"type":2756,"required":2737,"default":998,"description":2792,"note":2793,"demo":1713},"fixedSelect","Pins the selection column to the left edge, `position: sticky`, in\nplace. Data columns pin through `column.fixed`; this is the same feature\nfor the structural column that has no definition to carry it. No effect\nunless the table is `selectable`.","Pinned cells are opaque and paint the table's `--bg` local, so a table on a surface that is not `--bb-panel` needs that one custom property set or the pinned column reads as a white hole. The same applies to `fixed-actions` and to any `column.fixed`.",{"name":646,"type":2795,"required":2737,"default":352,"description":2796,"note":352,"demo":352},"Classes | undefined","Defines the classes to be passed to the header row.",{"name":1353,"type":2798,"required":2737,"default":352,"description":2799,"note":352,"demo":352},"any","Used by `v-model:highlighted`. A parallel, UI-intent state to selection —\ntypically \"the row whose details are open\". A single item value (or\n`null`) — highlight is single by design.\n\n**Opt-in, and `undefined` is the opt-out.** Leave it unbound and the whole\nmechanic is off: clicking a row emits `click:row` and nothing else — no\nclass, no `aria-current`, no internal state. Bind it and clicking a row\ntoggles it. The value itself is the switch: `undefined` means \"never\ninitialised\", `null` means \"initialised and currently empty\", so bind\n`ref(null)` rather than `ref()` — a bound-but-`undefined` model warns in\ndev and stays off. A value seeded through\n`useBbTableContext(id, { highlighted })` counts as bound the same way.\n\nA highlighted row gets `aria-current=\"true\"` and the\n`bb-table-data__row--highlighted` class, which the shipped stylesheet\npaints with a neutral fill plus a brand accent bar; override the whole\nlook with `rowClass`.\nHighlight: a parallel, UI-intent state to selection (\"the row whose details\nare open\"). Always a single value or `null`. Purely\nmechanical — highlighted rows only get a class and `aria-current`, no\nshipped styling.",{"name":1867,"type":2742,"required":2737,"default":352,"description":2801,"note":2802,"demo":1858},"Stable id for this table's width context. When omitted a unique id is\ngenerated. Nested tables use the nearest ancestor id to inherit widths.","The rendezvous key for `useBbTableContext(id)` and for a `BbPagination` with a matching `table-id`. A typo does not error — it creates a second, unattached state node, so a toolbar that \"works\" while the table ignores it is almost always a misspelled id.",{"name":2804,"type":2805,"required":2737,"default":352,"description":2806,"note":352,"demo":352},"inheritColumnWidths","string | boolean | undefined","Opt a nested table into inheriting its column widths from an ancestor\ntable's matching tracks (accounting for `select`\u002F`actions` columns). This\nalso makes the parent's tracks authoritative, so it is **off by default** — a nested\ntable renders independently unless you ask for alignment.\n- `false` (the default): do not inherit; size independently.\n- `true`: inherit from the nearest ancestor table.\n- a table id (string): inherit from the specific ancestor in the chain with\n  that id rather than the immediate parent. Use this when an intermediate\n  table has a different column count, so the extra columns would otherwise\n  misalign against it.",{"name":2808,"type":2756,"required":2737,"default":998,"description":2809,"note":352,"demo":352},"interactiveWhileLoading","Keeps the table interactive while it is loading. The header and the rows are\n`inert` while loading by default — a refetch is about to replace the rows,\nso editing, selecting or sorting them races the incoming data. This escape\nhatch exists for tables that must stay usable during background refreshes\n(e.g. a poll that must not interrupt an open editor).\n\nThe loading announcement is never inert, so the busy state is always\nconveyed.",{"name":508,"type":2811,"required":2709,"default":1915,"description":2812,"note":2813,"demo":453},"Item[] | ((prefill: boolean, modelValue?: any) => Item[] | Promise\u003CItem[]>)","Rows to render, or a fetcher that returns them.","Pass rows or a provider. Put filters and sort in `dependencies`; the table debounces, reports loading and discards stale responses.",{"name":2815,"type":2816,"required":2737,"default":352,"description":352,"note":2817,"demo":453},"itemValue","ItemAccessor\u003CItem> | undefined","Stable row identity as a path or function. Set it before adding selection, expansion or highlight so those models survive refetches.",{"name":2819,"type":2756,"required":2737,"default":998,"description":2820,"note":2821,"demo":1568},"keyboardNavigation","Opt-in keyboard navigation with a roving tabindex: the body is one tab\nstop, ArrowUp\u002FArrowDown move the focused row (Home\u002FEnd jump), and\nEnter\u002FSpace activate it through the same path as a mouse click (highlight\ntoggle + `click:row`). Focus and highlight stay independent — moving does\nnot highlight until committed. Focused rows show the standard focus ring.","Screen readers in browse mode intercept the arrow keys, so a reader takes the usual focus-mode step before the roving tabindex responds. Pair it with a bound `highlighted` (or a `row-class`) so the cursor is visible as well as announced.",{"name":881,"type":2742,"required":2737,"default":352,"description":2823,"note":2824,"demo":852},"Text content of the `\u003Clegend>` a `selectable` table renders (it becomes\na `\u003Cfieldset>`, and the legend is that fieldset's accessible name).\nOmit it and the table falls back to `caption`, then to a localized\ndefault — the fieldset always ends up with SOME accessible name — but\na specific `legend` describes the selection better than either fallback.","Only rendered by a `selectable` table. Say what the selection is for (\"select invoices to export\") — that is what makes it worth more than the `caption` fallback.",{"name":1056,"type":2756,"required":2737,"default":998,"description":2826,"note":2827,"demo":1048},"Sets the component in a loading state, usually triggering some visual styles.\n\nWith no rows yet this renders skeletons; over existing rows the rows stay\non screen (dimmed, with an indeterminate bar) rather than being replaced —\na refetch should not blank a table the user is reading.","With rows already on screen this no longer blanks the table: the rows stay, dimmed, under a progress bar, and the header and rows go `inert` unless you set `interactive-while-loading`. Skeletons appear only when there is nothing to keep.",{"name":2829,"type":2742,"required":2737,"default":2830,"description":2831,"note":352,"demo":352},"loadingText","the localized `common.loadingText` (\"Loading...\")","Screen-reader announcement for the loading row's `aria-live` status.\nVisually hidden — the skeleton (or the `#loading` slot) is the visible\nsignal.",{"name":928,"type":2763,"required":2737,"default":2833,"description":2834,"note":352,"demo":352},"Infinity","Maximum number of items that can be selected.",{"name":968,"type":2798,"required":2737,"default":1915,"description":2836,"note":352,"demo":352},"Used by v-model. Can be any serializable type.",{"name":2838,"type":2756,"required":2737,"default":990,"description":2839,"note":352,"demo":352},"multiple","Allows the selection of multiple items.",{"name":913,"type":2742,"required":2737,"default":352,"description":2841,"note":352,"demo":352},"Defines the name of the input.",{"name":2843,"type":2742,"required":2737,"default":2844,"description":2845,"note":2846,"demo":1048},"noDataText","the localized `common.noDataText` (\"No data to display\")","String displayed when there are no items to display.","Also the place to explain a failed fetch: there is no `error-text` prop and no table-level error state, so a rejected provider is yours to surface — through this text or the `#no-data` slot.",{"name":2848,"type":2849,"required":2737,"default":1915,"description":2850,"note":352,"demo":352},"order","string[] | undefined","Used by `v-model:order`. Ordered array of column keys — the render\norder of the data columns. Keys listed here render first, in this order;\ndeclared columns it omits follow, in declaration order (so a column added\nto `columns` later renders last); a `hidden` column keeps its slot\nwithout rendering, and keys that match no declared column render\nnothing but are PRESERVED in place on every write. The header drag \u002F\nkeyboard reorder of `reorderable` writes it back complete (every\ndeclared key present, hidden ones included, duplicates dropped — first\noccurrence wins) with exactly the moved column relocated: every other\nkey keeps its relative order, and a drop that changes nothing emits\nnothing. Works uncontrolled when unbound, exactly like `sort`. The\n`select` and `actions` columns are structural and never part of it.",{"name":1263,"type":2852,"required":2737,"default":352,"description":2853,"note":352,"demo":352},"string | number | undefined","Current page number starting from 1, used for accessibility purposes.\nAlso flows into the shared table context, so a `BbPagination` paired\nthrough `id` reads it as the current page. Numeric strings are coerced\n(server pagination fields often arrive as strings), exactly like\n`BbPagination`'s equivalent props.",{"name":1894,"type":2852,"required":2737,"default":352,"description":2855,"note":352,"demo":352},"Number of items per page, used for accessibility purposes. Also flows\ninto the shared table context read by a `BbPagination` paired through\n`id`. When omitted, an array `items` table infers it from\n`items.length`; an explicit value (or a context write) always wins over\nthat inference. Numeric strings are coerced, exactly like\n`BbPagination`'s `per-page`.",{"name":2857,"type":2858,"required":2737,"default":352,"description":2859,"note":352,"demo":352},"pt","PtItemMap\u003CBbTablePtPart, \"row\", BbTablePtState, Item> | undefined","Passthrough, object form: the same keys as the `pt:*` attributes\nwithout the prefix. See the `pt:\u003Cpart>` row.",{"name":2861,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:body","PtValue | undefined",{"name":2864,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:body:highlighted",{"name":2866,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:body:loading",{"name":2868,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:body:selected",{"name":2870,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:cell",{"name":2872,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:cell:highlighted",{"name":2874,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:cell:loading",{"name":2876,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:cell:selected",{"name":2878,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:head",{"name":2880,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:head:highlighted",{"name":2882,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:head:loading",{"name":2884,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:head:selected",{"name":2886,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:root",{"name":2888,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:root:highlighted",{"name":2890,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:root:loading",{"name":2892,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:root:selected",{"name":2894,"type":2895,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:row","PtValue | ((ctx: PtItemCtx\u003CItem, BbTablePtState>) => PtItemResult) | undefined",{"name":2897,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:row:highlighted",{"name":2899,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:row:loading",{"name":2901,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:row:selected",{"name":2903,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:table",{"name":2905,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:table:highlighted",{"name":2907,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:table:loading",{"name":2909,"type":2862,"required":2737,"default":352,"description":352,"note":352,"demo":352},"pt:table:selected",{"name":1474,"type":2756,"required":2737,"default":998,"description":2911,"note":352,"demo":352},"Sets the input in a readonly state.",{"name":1843,"type":2756,"required":2737,"default":998,"description":2913,"note":352,"demo":352},"Lets the user reorder the data columns: drag a header cell (AG Grid style —\nthe column moves live under the pointer and a chip with its label follows)\nor, from the keyboard, use each header's reorder handle (ArrowLeft \u002F\nArrowRight move the column one slot, Home \u002F End to the ends). Every move\nwrites `v-model:order`. Not needed by an external control (a column\npanel) that only writes `order`. The `select` \u002F `actions` columns and\na custom `#thead` are never draggable.",{"name":1850,"type":2756,"required":2737,"default":998,"description":2915,"note":352,"demo":352},"Lets the user resize the data columns of a root table: drag the handle on\na header's trailing edge (the column follows live, the width commits on\nrelease), or press Alt + ArrowLeft \u002F ArrowRight on the focused header;\ndouble-click the handle to go back to the declared width. Each commit\nfires `resize:column(key, width)` once. `column.width` stays the single declared\ntruth: a resized width is an override the table keeps until that\ncolumn's `width` changes — write the reported width back into your\ncolumn definition to persist it. Ignored on a table that inherits its\nwidths from a parent.",{"name":625,"type":2917,"required":2737,"default":352,"description":2918,"note":2919,"demo":518},"BbTableRowClasses\u003CItem> | undefined","Defines the classes to be passed to each data row. Can also be a\nfunction of the row's item for dynamic values.","The column-level `rowClass` field is new in v3 and accepts a plain string, so a leftover per-column class of that name now type-checks and lands on the whole row. Check your column definitions when you upgrade.",{"name":595,"type":2921,"required":2737,"default":352,"description":2922,"note":352,"demo":352},"boolean | ((item: Item) => boolean) | undefined","Defines whether the table is selectable.\nCan be a global boolean that affects all rows or a function\nthat accepts an item and returns a boolean that only affects that item.",{"name":2924,"type":2756,"required":2737,"default":998,"description":2925,"note":352,"demo":352},"selectAll","Defines whether the \"Select all\" checkbox is checked.",{"name":2927,"type":2742,"required":2737,"default":352,"description":2928,"note":2929,"demo":852},"selectAllLabel","Text of the label used by the \"Select all\" boolean.","Select-all is the \"everything across every page\" affordance: while it is on, `modelValue` stays empty and the exclusions accumulate in `unselected-items`. Read those two, never infer the selection from `modelValue`.",{"name":2931,"type":2742,"required":2737,"default":352,"description":2932,"note":352,"demo":352},"selectText","Text of the header used for the radio inputs when the table is not `multiple`.",{"name":474,"type":2934,"required":2737,"default":1915,"description":2935,"note":352,"demo":352},"BbTableSortEntry[] | undefined","Used by `v-model:sort`. Ordered array of `[columnKey, direction]`\nentries, one per actively sorted column. Bidirectional: the header\nbuttons of `sortable` columns update it, and external writes update the\nheader indicators. The table does not sort its items — apply the model\nto your own data source.",{"name":621,"type":2937,"required":2737,"default":352,"description":2938,"note":352,"demo":352},"ColumnClasses\u003CItem> | undefined","Defines the classes to be passed to every data cell. Can also be a function for dynamic values.",{"name":617,"type":2795,"required":2737,"default":352,"description":2940,"note":352,"demo":352},"Defines the classes to be passed to every header cell.",{"name":1897,"type":2852,"required":2737,"default":352,"description":2942,"note":2943,"demo":1176},"Total number of items there is. Also flows into the shared table\ncontext, where a `BbPagination` paired through `id` derives its page\ncount from it. When omitted, an array `items` table infers it from\n`items.length`; an explicit value (or a context write) always wins over\nthat inference. Numeric strings are coerced, exactly like\n`BbPagination`'s `total-items`.","Pass it with `page` and `per-page` so the table can announce the whole result set: `aria-rowcount` (now `totalItems + 1`, the header row counts) and each row's absolute `aria-rowindex`.",{"name":1900,"type":2852,"required":2737,"default":352,"description":2945,"note":352,"demo":352},"Seeds the page count shown by a `BbPagination` paired through `id`. A\nshortcut for when the server reports a page count rather than a row\ncount: the table renders nothing from it, it only flows into the shared\ntable context. A known total always wins — when `totalItems` (or a\ncontext write) provides one, the page count is derived from it and this\nseed is ignored. Numeric strings are coerced, exactly like\n`BbPagination`'s `total-pages`.",{"name":2947,"type":2780,"required":2737,"default":1915,"description":2948,"note":352,"demo":352},"unselectedItems","Items that are not selected.",{"name":515,"type":2756,"required":2737,"default":998,"description":2950,"note":2951,"demo":1713},"Windows the body: only the rows in (and just around) the vertical\nscrollport are mounted, so a client-side dataset of any size scrolls at\na constant cost. The table itself is the scroller as soon as you bound\nits height (`max-height` \u002F `height`, or a flex item with\n`min-height: 0`); left unbounded, the nearest scrolling ancestor or the\npage scrolls it. The header sticks to that scroller. Column widths are\nmeasured once from the first rendered batch and then hold — later rows\nnever widen them. Expand rows and nested tables stay fully rendered\ninside their row (a nested table is never windowed); the row that owns\nfocus stays mounted even when scrolled out of view. Ignored by a table\nthat inherits its widths from a parent, and under a `#tbody` slot.","Bound the height of the table or of an ancestor, or the page becomes the scroller. Columns are measured once from the first batch and then hold, and their cells clip with an ellipsis instead of wrapping — a column that must wrap needs a declared `width`.",[2953,2955,2957,2959,2961,2962,2964],{"name":2779,"type":2780,"note":2954,"demo":1483},"Holds the open rows by `item-value`. Without `item-value` expansion is keyed by object identity and every refetch closes every row.",{"name":1353,"type":2798,"note":2956,"demo":1568},"Bind `ref(null)`, not `ref()`. The value is the switch: `undefined` leaves the whole highlight mechanic off (and warns in dev), `null` turns it on with nothing highlighted.",{"name":968,"type":2798,"note":2958,"demo":852},"Holds row values resolved through `item-value`, or whole records without it. In multiple mode it must already be an array on the first render, or the table throws.",{"name":2848,"type":2849,"note":2960,"demo":352},"Bind it without `reorderable` when a column panel owns the order. Keys matching no declared column render nothing but keep their position, so hide a column by filtering `columns` — never the order array — and it returns exactly where it was.",{"name":2924,"type":2756,"note":352,"demo":352},{"name":474,"type":2934,"note":2963,"demo":453},"The array order is the sort priority. The table reports it and never applies it: sort your own array, or forward it to the server as `orderBy` and refetch through `dependencies`.",{"name":2947,"type":2780,"note":352,"demo":352},[2966,2969,2971,2973,2977,2979,2981,2986,2989,2992,2994,2997,3000,3003],{"name":1606,"signature":2967,"description":352,"note":2968,"demo":1568},"(e: \"click:row\", event: MouseEvent, item: any): void","The payload is `(event, item)` — your raw record. v2 passed the table's internal row wrapper plus a trailing `selected` boolean; both are gone. Use it for side effects, not for navigation: a row that opens a record should contain a real link.",{"name":1690,"signature":2970,"description":352,"note":352,"demo":352},"(e: \"contextmenu:row\", event: MouseEvent, item: any): void",{"name":1687,"signature":2972,"description":352,"note":352,"demo":352},"(e: \"dblclick:row\", event: MouseEvent, item: any): void",{"name":2974,"signature":2975,"description":2976,"note":352,"demo":352},"hide:column","(e: \"hide:column\", key: string): void","A column was hidden from its header (a `#header:\u003Ckey>` \u002F\n`#header:\u003Ckey>:append` control calling the slot's `hideColumn()`). Fired once;\nthe table keeps the column hidden for the mount, or until the column's\n`hidden` flag changes — write `hidden: true` into the definition to\npersist it, `hidden: false` (a column panel) to show it again.",{"name":932,"signature":2978,"description":352,"note":352,"demo":352},"(e: \"item:selected\", value: any): void",{"name":935,"signature":2980,"description":352,"note":352,"demo":352},"(e: \"item:unselected\", value: any): void",{"name":2982,"signature":2983,"description":2984,"note":2985,"demo":352},"resize:column","(e: \"resize:column\", key: string, width: number | null): void","A column was resized by the user (`resizable`): the new width in\npx, or `null` when the handle was double-clicked to reset the column to\nits declared width.","Fires once per committed resize, with `null` after a double-click reset. There is no width model on purpose: write the reported width back into your column definition, which always outranks a user override.",{"name":2987,"signature":2988,"description":352,"note":352,"demo":352},"update:expandedItems","(e: \"update:expandedItems\", value: any[]): void",{"name":2990,"signature":2991,"description":352,"note":352,"demo":352},"update:highlighted","(e: \"update:highlighted\", value: any): void",{"name":964,"signature":2993,"description":352,"note":352,"demo":352},"(e: \"update:modelValue\", value: any): void",{"name":2995,"signature":2996,"description":352,"note":352,"demo":352},"update:order","(e: \"update:order\", value: string[]): void",{"name":2998,"signature":2999,"description":352,"note":352,"demo":352},"update:selectAll","(e: \"update:selectAll\", value: boolean): void",{"name":3001,"signature":3002,"description":352,"note":352,"demo":352},"update:sort","(e: \"update:sort\", value: BbTableSortEntry[]): void",{"name":3004,"signature":3005,"description":352,"note":352,"demo":352},"update:unselectedItems","(e: \"update:unselectedItems\", value: any[]): void",[3007,3012,3015,3019,3023,3027,3030,3034,3038,3042,3046,3050,3054,3058,3061,3065],{"name":3008,"type":3009,"description":3010,"note":3011,"demo":1308},"\u003Ckey>","object","One column's body cell in every row, by the column `key` through `slotKey`. Scope: `{ item, value, content, selected, expanded, highlighted, classes, sortOrder, toggleSelected, toggleExpanded, toggleHighlighted, expandProps }`.","The name is the column `key` normalized — lowercased, every run of non-word characters folded to `_` — so `unitPrice` is `#unitprice`. Build names in code with `slotKey`, never a hand copy of the rule. Keep the column in `columns`: it still supplies the label, alignment and width.",{"name":588,"type":3013,"description":3014,"note":352,"demo":352},"{ expanded?: boolean | undefined; expandProps?: ExpandControllerProps | undefined; toggleExpanded?: (() => void) | undefined; highlighted?: boolean | undefined; toggleHighlighted?: (() => void) | undefined; selected?: boolean | undefined; toggleSelected?: (() => void) | undefined; item: Item; value: any; }","Content rendered in the actions cell for each row. Providing this slot\nis what CREATES the actions column (there is no prop): the header cell\n(labelled by `actions-text`, replaceable through `#header:actions`) and\none cell per row appear with it, and go away with it. Pin it with\n`fixed-actions`.",{"name":1483,"type":3016,"description":3017,"note":3018,"demo":1483},"{ expanded: boolean; expandProps?: ExpandControllerProps | undefined; toggleExpanded: () => void; highlighted?: boolean | undefined; toggleHighlighted?: (() => void) | undefined; selected?: boolean | undefined; toggleSelected?: (() => void) | undefined; item: Item; value: any; }","Full-width expandable content row rendered below each main row when expanded.","One full-width row below its record. `expandProps`, `expanded` and `toggleExpanded` also reach every per-column cell slot, so the toggle can live in the identity column instead of the actions column.",{"name":3020,"type":3009,"description":3021,"note":3022,"demo":696},"header:\u003Ckey>","One column's header content, replacing its label and the built-in sort button. Scope: `{ label, items, sortable, sortOrder, toggleSort, hideColumn, classes }`.","Replaces the header and the built-in sort button with it. To add beside the label and keep sorting, use `header:\u003Ckey>:prepend` \u002F `:append`.",{"name":3024,"type":3025,"description":3026,"note":352,"demo":1308},"header:\u003Ckey>:append","BbTableHeaderAffixSlotProps\u003CItem>","Content after one column's header, keeping the sort button; beats `header:append` (they never stack).",{"name":3028,"type":3025,"description":3029,"note":352,"demo":1308},"header:\u003Ckey>:prepend","Content before one column's header, keeping the sort button; beats `header:prepend` (they never stack).",{"name":3031,"type":3032,"description":3033,"note":352,"demo":352},"header:actions","{ text: string; }","Replaces the default actions header cell content.",{"name":3035,"type":3025,"description":3036,"note":3037,"demo":1308},"header:append","Content rendered after every data column's header cell content — the\nlabel + sort control, or the column's own `header:\u003Ckey>` replacement.\nA column's `header:\u003Ckey>:append` slot wins over this one for that\ncolumn; they never stack. Branch on `columnKey` for per-column output.","Renders after the column's existing header content, so the built-in sort button survives — which a full `#header:\u003Ckey>` replacement does not. The table-wide form applies to every data column and never to the select or actions cells; a per-column affix wins over it and the two never stack.",{"name":3039,"type":3025,"description":3040,"note":3041,"demo":1308},"header:prepend","Content rendered before every data column's header cell content — the\nlabel + sort control, or the column's own `header:\u003Ckey>` replacement.\nA column's `header:\u003Ckey>:prepend` slot wins over this one for that\ncolumn; they never stack. Branch on `columnKey` for per-column output.","The mirror of `header:append`, rendered before the column's existing header content. A column key that normalizes to `prepend` or `append` shadows these table-wide names: the table-wide reading wins, and dev builds warn.",{"name":3043,"type":3044,"description":3045,"note":352,"demo":352},"header:select","{ multiple: boolean; selectAll: boolean; text: string; }","Replaces the default selection header cell content (checkbox or radio label).",{"name":1056,"type":3047,"description":3048,"note":3049,"demo":1048},"{ items: Item[]; }","Content shown while table rows are loading (replaces the skeleton rows).","Replaces the skeleton, so it follows the skeleton's rule: first load only. A refetch over existing rows keeps them and shows the built-in progress bar instead, which this slot cannot change.",{"name":3051,"type":3009,"description":3052,"note":3053,"demo":1048},"no-data","Content shown when the items list is empty and not loading. It fills the\ntable's own full-width empty-state cell (it already spans the\nselection\u002Factions columns), so provide the *content* — a message, an\nillustration, a \"clear filters\" button — never a row\u002Fcell of your own.","Fills the table's own full-width cell, already centred and already spanning every column. Pass content, not a row — v2 handed this slot the whole `\u003Ctr>`, and a hand-rolled row here is now table markup inside a grid.",{"name":591,"type":3055,"description":3056,"note":3057,"demo":852},"{ item: Item; value: any; checked: boolean; disabled: boolean; inputName: string; readonly: boolean; toggleSelected?: (() => void) | undefined; }","Replaces the default checkbox\u002Fradio in the selection cell for each row.","Replaces a row's checkbox or radio while keeping the table's selection path. This is the supported way to change the control — rebuilding selection with your own checkbox in a cell slot is not.",{"name":1999,"type":3009,"description":3059,"note":3060,"demo":1969},"Replaces the content of the body row group (`.bb-table__body`). Use when\nyou need full control over the body markup. Provide role-complete rows —\n`\u003Cdiv role=\"row\">` holding one `\u003Cdiv role=\"cell\">` per column — never a\n`\u003Ctr>`\u002F`\u003Ctd>`. A full-width cell spans with `grid-column: 1 \u002F -1`.","Role-complete `\u003Cdiv role=\"row\">` rows of `\u003Cdiv role=\"cell\">`. Taking over the body switches off `virtual`, which has no rows of its own to window.",{"name":2496,"type":3062,"description":3063,"note":3064,"demo":1969},"{ columnCount: number; }","Fills the footer row group (`.bb-table__foot`). Use when you need a\nfooter. Provide role-complete rows — `\u003Cdiv role=\"row\">` holding\n`\u003Cdiv role=\"cell\">` elements — never a `\u003Ctr>`\u002F`\u003Ctd>`.","The markup you pass is grid markup: `\u003Cdiv role=\"row\">` holding `\u003Cdiv role=\"cell\">`, spanning with `grid-column` and `aria-colspan` rather than `colspan`. Nothing lints the roles — a row group of plain `\u003Cdiv>`s renders correctly and is invisible to a screen reader.",{"name":1996,"type":3009,"description":3066,"note":3067,"demo":1969},"Replaces the content of the header row group (`.bb-table__head`). Use when\nyou need full control over the header markup. The table is a CSS grid,\nnot a `\u003Ctable>`: provide role-complete rows — `\u003Cdiv role=\"row\">` holding\none `\u003Cdiv role=\"columnheader\">` per column — and never a `\u003Ctr>`\u002F`\u003Cth>`.\nRows are subgrid rows, so each cell lands on the matching column track.","Role-complete rows of `\u003Cdiv role=\"columnheader\">`. The table measures its tracks off the header cells, so a custom header over an empty table publishes no tracks and a nested table cannot inherit from it until rows arrive.",[],{"parts":3070,"states":3086},[3071,3074,3076,3079,3082,3084],{"name":3072,"description":3073},"root","The table's container.",{"name":1993,"description":3075},"The grid (`role=\"table\"`).",{"name":3077,"description":3078},"head","The header row group. Header cells are not a part — they keep `thClass`.",{"name":3080,"description":3081},"body","The body row group.",{"name":2298,"description":3083},"Every DATA row — a broadcast resolved per row. Expand rows and the skeleton are not parts. Also takes a per-item function, called with the row's raw item, once per rendered row: keep it cheap.",{"name":2369,"description":3085},"Every data cell, the select and actions cells included — a broadcast resolved with its row's states. Takes no function: use `tdClass` for a per-cell hook.",[3087,3089,3091],{"name":1353,"description":3088},"Per node, on `row` and its cells: the highlighted row.",{"name":1056,"description":3090},"Component-wide: the table is `loading`.",{"name":1205,"description":3092},"Per node, on `row` and its cells: a checked row.",{"removed":3094,"renamed":3113},[3095,3100,3105,3109],{"name":588,"replacedBy":352,"since":3096,"migration":3097,"silent":2709,"fix":3098},"3.0.0-beta.21","ai\u002Fguides\u002Fmigration\u002Fcomponents\u002Fbb-table.md",{"kind":3099},"remove",{"name":3101,"replacedBy":2768,"since":3102,"migration":3097,"silent":2709,"fix":3103},"allowSelectAll","3.0.0-unreleased",{"kind":3104},"invert",{"name":3106,"replacedBy":2808,"since":3102,"migration":3097,"silent":2709,"fix":3107},"enabledWhileLoading",{"kind":3108},"rename",{"name":3110,"replacedBy":352,"since":3096,"migration":3097,"silent":2709,"fix":3111},"fixedColumns",{"kind":3112},"manual",[3114,3116],{"from":3101,"to":2768,"since":3102,"migration":3097,"fix":3115},{"kind":3104},{"from":3106,"to":2808,"since":3102,"migration":3097,"fix":3117},{"kind":3108},[3119,3134,3144,3160],{"id":3120,"reference":3121,"customerId":199,"total":3122,"currency":3123,"status":3124,"channel":3125,"placedAt":3126,"lines":3127},9016,"ORD-2026-0491",958.9,"EUR","shipped","web","2026-08-18T14:07:00.000Z",[3128,3131],{"productId":3129,"quantity":131,"unitPrice":3130},106,899,{"productId":3132,"quantity":131,"unitPrice":3133},103,59.9,{"id":3135,"reference":3136,"customerId":3137,"total":3138,"currency":3123,"status":3124,"channel":3125,"placedAt":3139,"lines":3140},9011,"ORD-2026-0463",14,318,"2026-07-29T08:26:00.000Z",[3141],{"productId":3142,"quantity":135,"unitPrice":3143},124,159,{"id":3145,"reference":3146,"customerId":215,"total":3147,"currency":3123,"status":3124,"channel":3148,"placedAt":3149,"lines":3150},9010,"ORD-2026-0458",1046,"phone","2026-07-23T15:12:00.000Z",[3151,3154,3157],{"productId":3152,"quantity":135,"unitPrice":3153},118,349,{"productId":3155,"quantity":131,"unitPrice":3156},123,279,{"productId":3158,"quantity":131,"unitPrice":3159},110,69,{"id":3161,"reference":3162,"customerId":3163,"total":3164,"currency":3123,"status":3124,"channel":3165,"placedAt":3166,"lines":3167},9008,"ORD-2026-0447",19,458,"marketplace","2026-07-14T10:31:00.000Z",[3168],{"productId":3169,"quantity":135,"unitPrice":3170},121,229,[3119,3134,3144,3160],1790005165826]