Loading...
Loading...
Add JavaScript behavior to a Bootstrap 6 component. Use when writing a component's TypeScript source, extending BaseComponent, wiring the data API, adding events or config options, or integrating Floating UI or a third-party library.
npx skill4agent add twbs/bootstrap bootstrap-component-jsjs/src/BaseComponentgetInstance()getOrCreateInstance()data-bs-*dispose()@types/bootstrapbootstrap-componentjs/src/<name>.tsjs/src/alert.ts/**
* --------------------------------------------------------------------------
* Bootstrap widget.ts
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import BaseComponent from './base-component.js'
import EventHandler from './dom/event-handler.js'
/**
* Constants
*/
const NAME = 'widget'
const DATA_KEY = 'bs.widget'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const EVENT_SHOW = `show${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const CLASS_NAME_SHOW = 'show'
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="widget"]'
/**
* Class definition
*/
class Widget extends BaseComponent {
// Getters
static override get NAME(): string {
return NAME
}
}
export default WidgetNAMEBaseComponentDATA_KEYbs.<name>EVENT_KEY.bs.<name>Data.set()ConstantsClass definitionData API implementationconstructor// Getters// Public// Private// Staticjs/src/overrideBaseComponentConfig.js.tstsconfig.jsonmoduleResolution: nodenext.tsverbatimModuleSyntaximport EventHandler, { type BootstrapEvent } from './dom/event-handler.js'erasableSyntaxOnlyprotected declare _foo: Typetoast.tsdeclare_foo = undefineduseDefineForClassFieldsdefineJQueryPluginjs/src/util.tsjs/src/util/js/src/dom/event-handlerselector-enginemanipulatordatatype WidgetConfig = {
animation: boolean
delay: number
}
const Default: WidgetConfig = {
animation: true,
delay: 5000
}
const DefaultType = {
animation: 'boolean',
delay: 'number'
}
class Widget extends BaseComponent {
protected declare _config: WidgetConfig
protected declare _timeout: number | null
constructor(element?: string | Element | null, config?: Partial<WidgetConfig> | null) {
super(element, config)
this._timeout = null
}
// Getters
static override get Default(): WidgetConfig {
return Default
}
static override get DefaultType(): Record<string, string> {
return DefaultType
}
static override get NAME(): string {
return NAME
}
}
export default Widget
export type { WidgetConfig }DefaultPartial<>protected declare _config: WidgetConfigBaseComponentthis._config.delaynumberDefaultTypeConfig._mergeConfigObj()Defaultdata-bs-configdata-bs-*data-bs-*data-bs-auto-hide="false"autoHide: falseDefaultTypeTypeError'boolean''(number|string)''(string|element|function)'_configAfterMerge(config)class Widget extends BaseComponent {
// Public
show(): void {
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)
if (showEvent.defaultPrevented) {
return
}
this._element.classList.add(CLASS_NAME_SHOW)
this._queueCallback(() => {
EventHandler.trigger(this._element, EVENT_SHOWN)
}, this._element, this._config.animation)
}
}show.bs.widgetshown.bs.widgetdefaultPrevented_queueCallback(callback, element, isAnimated)elementEventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })trigger()BootstrapEventEventSelectorEnginefindOnefindnextprevgetElementFromSelectorquerySelectorManipulatorEventHandler.on(this._element, EVENT_MOUSEOVER, …)dispose()/**
* Data API implementation
*/
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
Widget.getOrCreateInstance(this).toggle()
})document.data-apifunctionEventHandlerthisthisSELECTOR_DATA_TOGGLEevent.targetjs/src/util/component-functions.tsenableDismissTrigger(Widget)[data-bs-dismiss="widget"]hide()enableDismissTrigger(Alert, 'close')eventActionOnPlugin(Widget, 'click', SELECTOR_DATA_TOGGLE, 'toggle')data-bs-target@floating-ui/domsuper()import { autoUpdate, computePosition } from '@floating-ui/dom'
class Widget extends BaseComponent {
protected declare _floatingCleanup: (() => void) | null
constructor(element?: string | Element | null, config?: Partial<WidgetConfig> | null) {
if (typeof computePosition === 'undefined') {
throw new TypeError('Bootstrap\'s widgets require Floating UI (https://floating-ui.com)')
}
super(element, config)
this._floatingCleanup = null
}
}class Widget extends BaseComponent {
// Private
protected _createFloating(): void {
this._updateFloatingPosition()
this._floatingCleanup = autoUpdate(this._element, this._floatingEl, () => this._updateFloatingPosition())
}
protected _disposeFloating(): void {
if (this._floatingCleanup) {
this._floatingCleanup()
this._floatingCleanup = null
}
}
}js/src/util/floating-ui.tsgetDefaultPlacement()-start-endparseResponsivePlacement()getResponsivePlacement()data-bs-placement="bottom-start md:top-end"createBreakpointListeners()disposeBreakpointListeners()js/src/datepicker.tsvanilla-calendar-prodata-bs-*_buildCalendarOptions()protected declare _calendar: Calendar | nulldispose()super.dispose()peerDependenciespackage.jsonclass Widget extends BaseComponent {
// Public
override dispose(): void {
clearTimeout(this._timeout!)
this._observer?.disconnect()
this._disposeFloating()
super.dispose()
}
}super.dispose()Datathis._elementEVENT_KEYMutationObserverResizeObserverdocumentwindowjs/src/index.tsexport { default as Widget } from './widget.js'dist/js/bootstrap.jsjs/src/index.tsbuild/build-plugins.mjsjs/src/**/*.tsjs/dist/js/tests/unit/**/*.spec.jsjs/tests/types/api.tsjs/tests/types/consumer.tsjs/dist/*.d.tsjs/tests/unit/<name>.spec.jsimport Widget from '../../src/widget.js'
import { clearFixture, getFixture } from '../helpers/fixture.js'
describe('Widget', () => {
let fixtureEl
beforeAll(() => {
fixtureEl = getFixture()
})
afterEach(() => {
clearFixture()
})
it('should expose the plugin name and data key', () => {
expect(Widget.NAME).toEqual('widget')
expect(Widget.DATA_KEY).toEqual('bs.widget')
})
})describeitexpectglobals: truejs/tests/vitest.config.mtsvivitestjs/tests/vitest-setup.jsspyOnjasmine.clock()toHaveClasstoBeTruetoBeFalsetoHaveSizespyOn.and.callThrough()donedata-bs-*dispose()js/srcjs/tests/vitest.config.mtsjs: optionaljs: required<JsDataAttributes />### Options<BsTable>site/src/assets/partials/snippets.js<JsDocs name="live-widget" file="site/src/assets/partials/snippets.js" />npm run js-lintnpm run js-typechecktsc --noEmitjs/srcnpm run js-test-unitnpm run js-testnpx playwright install chromiumnpm run js-debugnpm run jsdist/jsjs/disttsc.d.tsnpm run bundlewatchnpm startpackage.jsonbootstrap/js/src/*.jsjs/dist/*.jsimport BaseComponent from 'bootstrap/js/src/base-component.js'
import EventHandler from 'bootstrap/js/src/dom/event-handler.js'
class Widget extends BaseComponent {
static override get NAME(): string {
return 'widget'
}
}DATA_KEYbs.<name>NAME