@krollins/blueprint 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/README.npm.md +9 -3
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/badge/badge.d.ts.map +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/breadcrumb.js.map +1 -1
- package/dist/components/card.js.map +1 -1
- package/dist/components/checkbox.js +0 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/code-block/code-block.d.ts +143 -0
- package/dist/components/code-block/code-block.d.ts.map +1 -0
- package/dist/components/code-block/code-block.style.d.ts +2 -0
- package/dist/components/code-block/code-block.style.d.ts.map +1 -0
- package/dist/components/code-block.js +587 -0
- package/dist/components/code-block.js.map +1 -0
- package/dist/components/color-picker/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker.js.map +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/divider.js.map +1 -1
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/file-upload.js.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/menu.js.map +1 -1
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/notification.js.map +1 -1
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js.map +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/skeleton.js.map +1 -1
- package/dist/components/stepper.js.map +1 -1
- package/dist/components/switch.js +0 -1
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag/tag.d.ts.map +1 -1
- package/dist/components/tag.js.map +1 -1
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/time-picker.js.map +1 -1
- package/dist/components/tree.js.map +1 -1
- package/dist/index.js +31 -28
- package/dist/index.js.map +1 -1
- package/dist/shared/boolean-converter-XDGfS9LC.js.map +1 -1
- package/dist/shared/debounce-BckY30Sf.js.map +1 -1
- package/dist/shared/memoize-DlOFy-92.js.map +1 -1
- package/dist/shared/slider-BNt5TITl.js.map +1 -1
- package/dist/utilities/memoize.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,10 +18,16 @@ npm install @krollins/blueprint
|
|
|
18
18
|
<bp-button variant="primary">Click me</bp-button>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Or import individual components:
|
|
21
|
+
Or import individual components for smaller bundles:
|
|
22
22
|
|
|
23
|
-
```
|
|
24
|
-
|
|
23
|
+
```javascript
|
|
24
|
+
// Import the theme CSS (design tokens, fonts, colors)
|
|
25
|
+
import '@krollins/blueprint/dist/index.css';
|
|
26
|
+
|
|
27
|
+
// Import only the components you need
|
|
28
|
+
import '@krollins/blueprint/button';
|
|
29
|
+
import '@krollins/blueprint/card';
|
|
30
|
+
import '@krollins/blueprint/heading';
|
|
25
31
|
```
|
|
26
32
|
|
|
27
33
|
## Components
|
package/README.npm.md
CHANGED
|
@@ -18,10 +18,16 @@ npm install @krollins/blueprint
|
|
|
18
18
|
<bp-button variant="primary">Click me</bp-button>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Or import individual components:
|
|
21
|
+
Or import individual components for smaller bundles:
|
|
22
22
|
|
|
23
|
-
```
|
|
24
|
-
|
|
23
|
+
```javascript
|
|
24
|
+
// Import the theme CSS (design tokens, fonts, colors)
|
|
25
|
+
import '@krollins/blueprint/dist/index.css';
|
|
26
|
+
|
|
27
|
+
// Import only the components you need
|
|
28
|
+
import '@krollins/blueprint/button';
|
|
29
|
+
import '@krollins/blueprint/card';
|
|
30
|
+
import '@krollins/blueprint/heading';
|
|
25
31
|
```
|
|
26
32
|
|
|
27
33
|
## Components
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.js","sources":["../../source/components/accordion/accordion.style.ts","../../source/components/accordion/accordion.ts"],"sourcesContent":["import { css } from 'lit';\r\n\r\nexport const accordionStyles = css`\r\n /* ===== ACCORDION CONTAINER ===== */\r\n\r\n :host {\r\n display: block;\r\n }\r\n\r\n .accordion {\r\n font-family: var(--bp-font-family);\r\n display: flex;\r\n flex-direction: column;\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n border-radius: var(--bp-border-radius);\r\n overflow: hidden;\r\n }\r\n\r\n /* Disabled state */\r\n .accordion--disabled {\r\n opacity: var(--bp-opacity-disabled);\r\n pointer-events: none;\r\n }\r\n\r\n /* ===== ACCORDION ITEM ===== */\r\n\r\n /* Separators between items */\r\n :host(:not(:first-of-type)) {\r\n border-top: var(--bp-border-width) solid var(--bp-color-border);\r\n }\r\n\r\n .item {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n /* Header button */\r\n .item__header {\r\n /* Reset */\r\n appearance: none;\r\n border: none;\r\n background: transparent;\r\n margin: 0;\r\n\r\n /* Layout */\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: 100%;\r\n padding: var(--bp-spacing-4) var(--bp-spacing-4);\r\n gap: var(--bp-spacing-3);\r\n\r\n /* Typography */\r\n font-family: var(--bp-font-family);\r\n font-size: var(--bp-font-size-base);\r\n font-weight: var(--bp-font-weight-medium);\r\n text-align: left;\r\n color: var(--bp-color-text);\r\n line-height: var(--bp-line-height-normal);\r\n\r\n /* Interaction */\r\n cursor: pointer;\r\n transition: background-color var(--bp-transition-fast);\r\n }\r\n\r\n .item__header:hover:not(:disabled) {\r\n background-color: var(--bp-color-surface);\r\n }\r\n\r\n .item__header:focus {\r\n outline: none;\r\n }\r\n\r\n .item__header:focus-visible {\r\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\r\n outline-offset: var(--bp-focus-offset);\r\n }\r\n .item__header:active:not(:disabled) {\r\n background-color: var(--bp-color-surface-hover);\r\n transform: translateY(1px);\r\n }\r\n .item__header-content {\r\n display: flex;\r\n align-items: center;\r\n gap: var(--bp-spacing-3);\r\n flex: 1;\r\n }\r\n\r\n /* Expand/collapse icon */\r\n .item__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n color: var(--bp-color-text-muted);\r\n transition: transform var(--bp-transition-fast);\r\n }\r\n\r\n /* Icon is sized by bp-icon component */\r\n\r\n /* Rotate icon when expanded */\r\n .item--expanded .item__icon {\r\n transform: rotate(180deg);\r\n }\r\n\r\n /* Collapsible content */\r\n .item__content {\r\n display: grid;\r\n grid-template-rows: 0fr;\r\n overflow: hidden;\r\n transition: grid-template-rows var(--bp-transition-base);\r\n content-visibility: hidden;\r\n }\r\n\r\n .item--expanded .item__content {\r\n grid-template-rows: 1fr;\r\n content-visibility: visible;\r\n }\r\n\r\n .item__body {\r\n min-height: 0;\r\n padding: 0 var(--bp-spacing-4) var(--bp-spacing-4) var(--bp-spacing-4);\r\n color: var(--bp-color-text);\r\n font-size: var(--bp-font-size-sm);\r\n line-height: var(--bp-line-height-relaxed);\r\n overflow: hidden;\r\n opacity: 0;\r\n transition: opacity var(--bp-transition-fast);\r\n }\r\n\r\n .item--expanded .item__body {\r\n opacity: 1;\r\n transition-delay: 100ms;\r\n }\r\n\r\n .item:not(.item--expanded) .item__body {\r\n padding-top: 0;\r\n padding-bottom: 0;\r\n opacity: 0;\r\n transition-delay: 0ms;\r\n }\r\n\r\n /* Disabled state */\r\n .item--disabled .item__header {\r\n cursor: not-allowed;\r\n opacity: var(--bp-opacity-disabled);\r\n }\r\n\r\n .item--disabled .item__icon {\r\n opacity: 1;\r\n }\r\n\r\n .item--disabled .item__header:hover {\r\n background-color: transparent;\r\n }\r\n\r\n /* Reduced motion */\r\n @media (prefers-reduced-motion: reduce) {\r\n .item__icon {\r\n transition: none;\r\n }\r\n\r\n .item__content {\r\n transition: none;\r\n }\r\n\r\n .item__body {\r\n transition: none;\r\n opacity: 1;\r\n }\r\n\r\n .item__header:active:not(:disabled) {\r\n transform: none;\r\n }\r\n }\r\n`;\r\n","import { LitElement, html } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { accordionStyles } from './accordion.style.js';\r\nimport '../icon/icon.js';\r\n\r\n/**\r\n * A container component that groups accordion items.\r\n * Controls single or multiple expansion behavior.\r\n *\r\n * @element bp-accordion\r\n *\r\n * @property {boolean} multiple - Whether multiple items can be expanded simultaneously\r\n * @property {string[]} expandedItems - Array of expanded item IDs\r\n * @property {boolean} disabled - Whether all items are disabled\r\n *\r\n * @fires bp-expand - Fired when an item is expanded\r\n * @fires bp-collapse - Fired when an item is collapsed\r\n *\r\n * @slot - Default slot for bp-accordion-item elements\r\n *\r\n * @csspart accordion - The main accordion container\r\n */\r\n@customElement('bp-accordion')\r\nexport class BpAccordion extends LitElement {\r\n /** Whether multiple items can be expanded simultaneously */\r\n @property({ type: Boolean, reflect: true }) declare multiple: boolean;\r\n\r\n /** Array of expanded item IDs */\r\n @property({ type: Array }) declare expandedItems: string[];\r\n\r\n /** Whether all items are disabled */\r\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\r\n\r\n static styles = [accordionStyles];\r\n\r\n constructor() {\r\n super();\r\n this.multiple = false;\r\n this.expandedItems = [];\r\n this.disabled = false;\r\n }\r\n\r\n connectedCallback(): void {\r\n super.connectedCallback();\r\n this.addEventListener('bp-item-toggle', this.handleItemToggle);\r\n }\r\n\r\n disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.removeEventListener('bp-item-toggle', this.handleItemToggle);\r\n }\r\n\r\n /**\r\n * Handles item toggle events from child accordion items.\r\n * Updates expandedItems array based on multiple mode and dispatches expand/collapse events.\r\n */\r\n private handleItemToggle = (event: Event) => {\r\n const customEvent = event as CustomEvent<{ id: string; expanded: boolean }>;\r\n const { id, expanded } = customEvent.detail;\r\n\r\n if (expanded) {\r\n if (this.multiple) {\r\n this.expandedItems = [...this.expandedItems, id];\r\n } else {\r\n // Close other items when not in multiple mode\r\n this.expandedItems = [id];\r\n }\r\n this.dispatchEvent(\r\n new CustomEvent('bp-expand', {\r\n detail: { id },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n } else {\r\n this.expandedItems = this.expandedItems.filter((itemId) => itemId !== id);\r\n this.dispatchEvent(\r\n new CustomEvent('bp-collapse', {\r\n detail: { id },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n\r\n this.updateChildItems();\r\n };\r\n\r\n /**\r\n * Synchronizes child accordion items with the expandedItems state.\r\n * Also applies disabled state to all items when accordion is disabled.\r\n */\r\n private updateChildItems() {\r\n const items = this.querySelectorAll('bp-accordion-item');\r\n items.forEach((item) => {\r\n const accordionItem = item as BpAccordionItem;\r\n const isExpanded = this.expandedItems.includes(accordionItem.itemId);\r\n accordionItem.expanded = isExpanded;\r\n if (this.disabled) {\r\n accordionItem.disabled = true;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Initializes expandedItems array from children with expanded attribute.\r\n * Called on first render to respect items marked as expanded in HTML.\r\n */\r\n private initializeExpandedItems() {\r\n const items = this.querySelectorAll('bp-accordion-item');\r\n const expandedIds: string[] = [];\r\n\r\n items.forEach((item) => {\r\n const accordionItem = item as BpAccordionItem;\r\n if (accordionItem.expanded && accordionItem.itemId) {\r\n expandedIds.push(accordionItem.itemId);\r\n }\r\n });\r\n\r\n if (expandedIds.length > 0) {\r\n // In single mode, only keep the first expanded item\r\n this.expandedItems = this.multiple ? expandedIds : [expandedIds[0]];\r\n }\r\n }\r\n\r\n firstUpdated(): void {\r\n // Initialize expanded items from children on first render\r\n this.initializeExpandedItems();\r\n this.updateChildItems();\r\n }\r\n\r\n updated(changedProperties: Map<string, unknown>): void {\r\n if (\r\n changedProperties.has('expandedItems') ||\r\n changedProperties.has('disabled')\r\n ) {\r\n this.updateChildItems();\r\n }\r\n }\r\n\r\n /** Expand an item by ID */\r\n expand(id: string) {\r\n if (!this.expandedItems.includes(id)) {\r\n if (this.multiple) {\r\n this.expandedItems = [...this.expandedItems, id];\r\n } else {\r\n this.expandedItems = [id];\r\n }\r\n this.updateChildItems();\r\n this.dispatchEvent(\r\n new CustomEvent('bp-expand', {\r\n detail: { id },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n }\r\n\r\n /** Collapse an item by ID */\r\n collapse(id: string) {\r\n if (this.expandedItems.includes(id)) {\r\n this.expandedItems = this.expandedItems.filter((itemId) => itemId !== id);\r\n this.updateChildItems();\r\n this.dispatchEvent(\r\n new CustomEvent('bp-collapse', {\r\n detail: { id },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n }\r\n\r\n /** Expand all items (only works in multiple mode) */\r\n expandAll() {\r\n if (!this.multiple) return;\r\n const items = this.querySelectorAll('bp-accordion-item');\r\n const ids: string[] = [];\r\n items.forEach((item) => {\r\n const accordionItem = item as BpAccordionItem;\r\n if (!accordionItem.disabled) {\r\n ids.push(accordionItem.itemId);\r\n }\r\n });\r\n this.expandedItems = ids;\r\n this.updateChildItems();\r\n }\r\n\r\n /** Collapse all items */\r\n collapseAll() {\r\n this.expandedItems = [];\r\n this.updateChildItems();\r\n }\r\n\r\n /**\r\n * Handles slot changes - when children are added or removed.\r\n * Initializes expanded state from new children.\r\n */\r\n private handleSlotChange() {\r\n // Only initialize from children if expandedItems is empty\r\n // Otherwise respect the parent's state\r\n if (this.expandedItems.length === 0) {\r\n this.initializeExpandedItems();\r\n }\r\n this.updateChildItems();\r\n }\r\n\r\n render() {\r\n const classes = {\r\n accordion: true,\r\n 'accordion--disabled': this.disabled,\r\n };\r\n\r\n return html`\r\n <div class=${classMap(classes)} part=\"accordion\" role=\"presentation\">\r\n <slot @slotchange=${this.handleSlotChange}></slot>\r\n </div>\r\n `;\r\n }\r\n}\r\n\r\n/**\r\n * An individual accordion item with header and collapsible content.\r\n *\r\n * @element bp-accordion-item\r\n *\r\n * @property {string} itemId - Unique identifier for this item\r\n * @property {string} header - Header text displayed in the trigger button\r\n * @property {boolean} expanded - Whether the content is expanded\r\n * @property {boolean} disabled - Whether this item is disabled\r\n *\r\n * @slot - Default slot for the collapsible content\r\n * @slot header - Custom header content (overrides header property)\r\n * @slot icon - Custom icon for the header\r\n *\r\n * @csspart item - The accordion item container\r\n * @csspart header - The header/trigger button\r\n * @csspart icon - The expand/collapse icon\r\n * @csspart content - The collapsible content wrapper\r\n * @csspart body - The inner content container\r\n */\r\n@customElement('bp-accordion-item')\r\nexport class BpAccordionItem extends LitElement {\r\n /** Unique identifier for this item */\r\n @property({ type: String, attribute: 'item-id', reflect: true })\r\n declare itemId: string;\r\n\r\n /** Header text displayed in the trigger button */\r\n @property({ type: String }) declare header: string;\r\n\r\n /** Whether the content is expanded */\r\n @property({ type: Boolean, reflect: true }) declare expanded: boolean;\r\n\r\n /** Whether this item is disabled */\r\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\r\n\r\n static styles = [accordionStyles];\r\n\r\n constructor() {\r\n super();\r\n this.itemId = '';\r\n this.header = '';\r\n this.expanded = false;\r\n this.disabled = false;\r\n }\r\n\r\n connectedCallback(): void {\r\n super.connectedCallback();\r\n // Generate ID if not provided\r\n if (!this.itemId) {\r\n this.itemId = `accordion-item-${Math.random().toString(36).slice(2, 9)}`;\r\n }\r\n }\r\n\r\n /**\r\n * Handles toggle action and dispatches bp-item-toggle event.\r\n * Also manages focus on the header button after expansion.\r\n */\r\n private handleToggle() {\r\n if (this.disabled) return;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent('bp-item-toggle', {\r\n detail: { id: this.itemId, expanded: !this.expanded },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n\r\n // Focus management: focus header after toggle completes\r\n this.updateComplete.then(() => {\r\n const header = this.shadowRoot?.querySelector(\r\n '.item__header'\r\n ) as HTMLElement;\r\n header?.focus();\r\n });\r\n }\r\n\r\n /**\r\n * Handles keyboard navigation.\r\n * Triggers toggle on Enter or Space key press.\r\n */\r\n private handleKeyDown(event: KeyboardEvent) {\r\n if (this.disabled) return;\r\n\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n this.handleToggle();\r\n }\r\n }\r\n\r\n render() {\r\n const itemClasses = {\r\n item: true,\r\n 'item--expanded': this.expanded,\r\n 'item--disabled': this.disabled,\r\n };\r\n\r\n const headerId = `${this.itemId}-header`;\r\n const contentId = `${this.itemId}-content`;\r\n\r\n return html`\r\n <div class=${classMap(itemClasses)} part=\"item\">\r\n <button\r\n class=\"item__header\"\r\n part=\"header\"\r\n id=${headerId}\r\n aria-expanded=${this.expanded}\r\n aria-controls=${contentId}\r\n aria-disabled=${this.disabled}\r\n ?disabled=${this.disabled}\r\n @click=${this.handleToggle}\r\n @keydown=${this.handleKeyDown}\r\n >\r\n <span class=\"item__header-content\">\r\n <slot name=\"icon\"></slot>\r\n <slot name=\"header\">${this.header}</slot>\r\n </span>\r\n <span class=\"item__icon\" part=\"icon\" aria-hidden=\"true\">\r\n <bp-icon name=\"chevron-down\" size=\"md\"></bp-icon>\r\n </span>\r\n </button>\r\n <div\r\n class=\"item__content\"\r\n part=\"content\"\r\n id=${contentId}\r\n role=\"region\"\r\n aria-labelledby=${headerId}\r\n >\r\n <div class=\"item__body\" part=\"body\">\r\n <slot></slot>\r\n </div>\r\n </div>\r\n </div>\r\n `;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'bp-accordion': BpAccordion;\r\n 'bp-accordion-item': BpAccordionItem;\r\n }\r\n}\r\n"],"names":["accordionStyles","css","BpAccordion","LitElement","event","customEvent","id","expanded","itemId","item","accordionItem","isExpanded","items","expandedIds","changedProperties","ids","classes","html","classMap","__decorateClass","property","customElement","BpAccordionItem","itemClasses","headerId","contentId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"accordion.js","sources":["../../source/components/accordion/accordion.style.ts","../../source/components/accordion/accordion.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const accordionStyles = css`\n /* ===== ACCORDION CONTAINER ===== */\n\n :host {\n display: block;\n }\n\n .accordion {\n font-family: var(--bp-font-family);\n display: flex;\n flex-direction: column;\n border: var(--bp-border-width) solid var(--bp-color-border);\n border-radius: var(--bp-border-radius);\n overflow: hidden;\n }\n\n /* Disabled state */\n .accordion--disabled {\n opacity: var(--bp-opacity-disabled);\n pointer-events: none;\n }\n\n /* ===== ACCORDION ITEM ===== */\n\n /* Separators between items */\n :host(:not(:first-of-type)) {\n border-top: var(--bp-border-width) solid var(--bp-color-border);\n }\n\n .item {\n display: flex;\n flex-direction: column;\n }\n\n /* Header button */\n .item__header {\n /* Reset */\n appearance: none;\n border: none;\n background: transparent;\n margin: 0;\n\n /* Layout */\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: var(--bp-spacing-4) var(--bp-spacing-4);\n gap: var(--bp-spacing-3);\n\n /* Typography */\n font-family: var(--bp-font-family);\n font-size: var(--bp-font-size-base);\n font-weight: var(--bp-font-weight-medium);\n text-align: left;\n color: var(--bp-color-text);\n line-height: var(--bp-line-height-normal);\n\n /* Interaction */\n cursor: pointer;\n transition: background-color var(--bp-transition-fast);\n }\n\n .item__header:hover:not(:disabled) {\n background-color: var(--bp-color-surface);\n }\n\n .item__header:focus {\n outline: none;\n }\n\n .item__header:focus-visible {\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\n outline-offset: var(--bp-focus-offset);\n }\n .item__header:active:not(:disabled) {\n background-color: var(--bp-color-surface-hover);\n transform: translateY(1px);\n }\n .item__header-content {\n display: flex;\n align-items: center;\n gap: var(--bp-spacing-3);\n flex: 1;\n }\n\n /* Expand/collapse icon */\n .item__icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n color: var(--bp-color-text-muted);\n transition: transform var(--bp-transition-fast);\n }\n\n /* Icon is sized by bp-icon component */\n\n /* Rotate icon when expanded */\n .item--expanded .item__icon {\n transform: rotate(180deg);\n }\n\n /* Collapsible content */\n .item__content {\n display: grid;\n grid-template-rows: 0fr;\n overflow: hidden;\n transition: grid-template-rows var(--bp-transition-base);\n content-visibility: hidden;\n }\n\n .item--expanded .item__content {\n grid-template-rows: 1fr;\n content-visibility: visible;\n }\n\n .item__body {\n min-height: 0;\n padding: 0 var(--bp-spacing-4) var(--bp-spacing-4) var(--bp-spacing-4);\n color: var(--bp-color-text);\n font-size: var(--bp-font-size-sm);\n line-height: var(--bp-line-height-relaxed);\n overflow: hidden;\n opacity: 0;\n transition: opacity var(--bp-transition-fast);\n }\n\n .item--expanded .item__body {\n opacity: 1;\n transition-delay: 100ms;\n }\n\n .item:not(.item--expanded) .item__body {\n padding-top: 0;\n padding-bottom: 0;\n opacity: 0;\n transition-delay: 0ms;\n }\n\n /* Disabled state */\n .item--disabled .item__header {\n cursor: not-allowed;\n opacity: var(--bp-opacity-disabled);\n }\n\n .item--disabled .item__icon {\n opacity: 1;\n }\n\n .item--disabled .item__header:hover {\n background-color: transparent;\n }\n\n /* Reduced motion */\n @media (prefers-reduced-motion: reduce) {\n .item__icon {\n transition: none;\n }\n\n .item__content {\n transition: none;\n }\n\n .item__body {\n transition: none;\n opacity: 1;\n }\n\n .item__header:active:not(:disabled) {\n transform: none;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { accordionStyles } from './accordion.style.js';\nimport '../icon/icon.js';\n\n/**\n * A container component that groups accordion items.\n * Controls single or multiple expansion behavior.\n *\n * @element bp-accordion\n *\n * @property {boolean} multiple - Whether multiple items can be expanded simultaneously\n * @property {string[]} expandedItems - Array of expanded item IDs\n * @property {boolean} disabled - Whether all items are disabled\n *\n * @fires bp-expand - Fired when an item is expanded\n * @fires bp-collapse - Fired when an item is collapsed\n *\n * @slot - Default slot for bp-accordion-item elements\n *\n * @csspart accordion - The main accordion container\n */\n@customElement('bp-accordion')\nexport class BpAccordion extends LitElement {\n /** Whether multiple items can be expanded simultaneously */\n @property({ type: Boolean, reflect: true }) declare multiple: boolean;\n\n /** Array of expanded item IDs */\n @property({ type: Array }) declare expandedItems: string[];\n\n /** Whether all items are disabled */\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\n\n static styles = [accordionStyles];\n\n constructor() {\n super();\n this.multiple = false;\n this.expandedItems = [];\n this.disabled = false;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('bp-item-toggle', this.handleItemToggle);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('bp-item-toggle', this.handleItemToggle);\n }\n\n /**\n * Handles item toggle events from child accordion items.\n * Updates expandedItems array based on multiple mode and dispatches expand/collapse events.\n */\n private handleItemToggle = (event: Event) => {\n const customEvent = event as CustomEvent<{ id: string; expanded: boolean }>;\n const { id, expanded } = customEvent.detail;\n\n if (expanded) {\n if (this.multiple) {\n this.expandedItems = [...this.expandedItems, id];\n } else {\n // Close other items when not in multiple mode\n this.expandedItems = [id];\n }\n this.dispatchEvent(\n new CustomEvent('bp-expand', {\n detail: { id },\n bubbles: true,\n composed: true,\n })\n );\n } else {\n this.expandedItems = this.expandedItems.filter((itemId) => itemId !== id);\n this.dispatchEvent(\n new CustomEvent('bp-collapse', {\n detail: { id },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n this.updateChildItems();\n };\n\n /**\n * Synchronizes child accordion items with the expandedItems state.\n * Also applies disabled state to all items when accordion is disabled.\n */\n private updateChildItems() {\n const items = this.querySelectorAll('bp-accordion-item');\n items.forEach((item) => {\n const accordionItem = item as BpAccordionItem;\n const isExpanded = this.expandedItems.includes(accordionItem.itemId);\n accordionItem.expanded = isExpanded;\n if (this.disabled) {\n accordionItem.disabled = true;\n }\n });\n }\n\n /**\n * Initializes expandedItems array from children with expanded attribute.\n * Called on first render to respect items marked as expanded in HTML.\n */\n private initializeExpandedItems() {\n const items = this.querySelectorAll('bp-accordion-item');\n const expandedIds: string[] = [];\n\n items.forEach((item) => {\n const accordionItem = item as BpAccordionItem;\n if (accordionItem.expanded && accordionItem.itemId) {\n expandedIds.push(accordionItem.itemId);\n }\n });\n\n if (expandedIds.length > 0) {\n // In single mode, only keep the first expanded item\n this.expandedItems = this.multiple ? expandedIds : [expandedIds[0]];\n }\n }\n\n firstUpdated(): void {\n // Initialize expanded items from children on first render\n this.initializeExpandedItems();\n this.updateChildItems();\n }\n\n updated(changedProperties: Map<string, unknown>): void {\n if (\n changedProperties.has('expandedItems') ||\n changedProperties.has('disabled')\n ) {\n this.updateChildItems();\n }\n }\n\n /** Expand an item by ID */\n expand(id: string) {\n if (!this.expandedItems.includes(id)) {\n if (this.multiple) {\n this.expandedItems = [...this.expandedItems, id];\n } else {\n this.expandedItems = [id];\n }\n this.updateChildItems();\n this.dispatchEvent(\n new CustomEvent('bp-expand', {\n detail: { id },\n bubbles: true,\n composed: true,\n })\n );\n }\n }\n\n /** Collapse an item by ID */\n collapse(id: string) {\n if (this.expandedItems.includes(id)) {\n this.expandedItems = this.expandedItems.filter((itemId) => itemId !== id);\n this.updateChildItems();\n this.dispatchEvent(\n new CustomEvent('bp-collapse', {\n detail: { id },\n bubbles: true,\n composed: true,\n })\n );\n }\n }\n\n /** Expand all items (only works in multiple mode) */\n expandAll() {\n if (!this.multiple) return;\n const items = this.querySelectorAll('bp-accordion-item');\n const ids: string[] = [];\n items.forEach((item) => {\n const accordionItem = item as BpAccordionItem;\n if (!accordionItem.disabled) {\n ids.push(accordionItem.itemId);\n }\n });\n this.expandedItems = ids;\n this.updateChildItems();\n }\n\n /** Collapse all items */\n collapseAll() {\n this.expandedItems = [];\n this.updateChildItems();\n }\n\n /**\n * Handles slot changes - when children are added or removed.\n * Initializes expanded state from new children.\n */\n private handleSlotChange() {\n // Only initialize from children if expandedItems is empty\n // Otherwise respect the parent's state\n if (this.expandedItems.length === 0) {\n this.initializeExpandedItems();\n }\n this.updateChildItems();\n }\n\n render() {\n const classes = {\n accordion: true,\n 'accordion--disabled': this.disabled,\n };\n\n return html`\n <div class=${classMap(classes)} part=\"accordion\" role=\"presentation\">\n <slot @slotchange=${this.handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\n/**\n * An individual accordion item with header and collapsible content.\n *\n * @element bp-accordion-item\n *\n * @property {string} itemId - Unique identifier for this item\n * @property {string} header - Header text displayed in the trigger button\n * @property {boolean} expanded - Whether the content is expanded\n * @property {boolean} disabled - Whether this item is disabled\n *\n * @slot - Default slot for the collapsible content\n * @slot header - Custom header content (overrides header property)\n * @slot icon - Custom icon for the header\n *\n * @csspart item - The accordion item container\n * @csspart header - The header/trigger button\n * @csspart icon - The expand/collapse icon\n * @csspart content - The collapsible content wrapper\n * @csspart body - The inner content container\n */\n@customElement('bp-accordion-item')\nexport class BpAccordionItem extends LitElement {\n /** Unique identifier for this item */\n @property({ type: String, attribute: 'item-id', reflect: true })\n declare itemId: string;\n\n /** Header text displayed in the trigger button */\n @property({ type: String }) declare header: string;\n\n /** Whether the content is expanded */\n @property({ type: Boolean, reflect: true }) declare expanded: boolean;\n\n /** Whether this item is disabled */\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\n\n static styles = [accordionStyles];\n\n constructor() {\n super();\n this.itemId = '';\n this.header = '';\n this.expanded = false;\n this.disabled = false;\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n // Generate ID if not provided\n if (!this.itemId) {\n this.itemId = `accordion-item-${Math.random().toString(36).slice(2, 9)}`;\n }\n }\n\n /**\n * Handles toggle action and dispatches bp-item-toggle event.\n * Also manages focus on the header button after expansion.\n */\n private handleToggle() {\n if (this.disabled) return;\n\n this.dispatchEvent(\n new CustomEvent('bp-item-toggle', {\n detail: { id: this.itemId, expanded: !this.expanded },\n bubbles: true,\n composed: true,\n })\n );\n\n // Focus management: focus header after toggle completes\n this.updateComplete.then(() => {\n const header = this.shadowRoot?.querySelector(\n '.item__header'\n ) as HTMLElement;\n header?.focus();\n });\n }\n\n /**\n * Handles keyboard navigation.\n * Triggers toggle on Enter or Space key press.\n */\n private handleKeyDown(event: KeyboardEvent) {\n if (this.disabled) return;\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.handleToggle();\n }\n }\n\n render() {\n const itemClasses = {\n item: true,\n 'item--expanded': this.expanded,\n 'item--disabled': this.disabled,\n };\n\n const headerId = `${this.itemId}-header`;\n const contentId = `${this.itemId}-content`;\n\n return html`\n <div class=${classMap(itemClasses)} part=\"item\">\n <button\n class=\"item__header\"\n part=\"header\"\n id=${headerId}\n aria-expanded=${this.expanded}\n aria-controls=${contentId}\n aria-disabled=${this.disabled}\n ?disabled=${this.disabled}\n @click=${this.handleToggle}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"item__header-content\">\n <slot name=\"icon\"></slot>\n <slot name=\"header\">${this.header}</slot>\n </span>\n <span class=\"item__icon\" part=\"icon\" aria-hidden=\"true\">\n <bp-icon name=\"chevron-down\" size=\"md\"></bp-icon>\n </span>\n </button>\n <div\n class=\"item__content\"\n part=\"content\"\n id=${contentId}\n role=\"region\"\n aria-labelledby=${headerId}\n >\n <div class=\"item__body\" part=\"body\">\n <slot></slot>\n </div>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-accordion': BpAccordion;\n 'bp-accordion-item': BpAccordionItem;\n }\n}\n"],"names":["accordionStyles","css","BpAccordion","LitElement","event","customEvent","id","expanded","itemId","item","accordionItem","isExpanded","items","expandedIds","changedProperties","ids","classes","html","classMap","__decorateClass","property","customElement","BpAccordionItem","itemClasses","headerId","contentId"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../source/components/badge/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAKvC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACrC;;;;OAIG;IACgD,OAAO,EACtD,SAAS,GACT,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,SAAS,CAAC;IAEd;;;;OAIG;IACgD,IAAI,
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../source/components/badge/badge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAKvC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,OAAQ,SAAQ,UAAU;IACrC;;;;OAIG;IACgD,OAAO,EACtD,SAAS,GACT,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,SAAS,CAAC;IAEd;;;;OAIG;IACgD,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE5E;;;;OAIG;IACiD,GAAG,EAAE,OAAO,CAAC;IAEjE,MAAM,CAAC,MAAM,4BAAiB;;IAS9B,MAAM;CAiBP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.js","sources":["../../source/components/badge/badge.style.ts","../../source/components/badge/badge.ts"],"sourcesContent":["import { css } from 'lit';\
|
|
1
|
+
{"version":3,"file":"badge.js","sources":["../../source/components/badge/badge.style.ts","../../source/components/badge/badge.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const badgeStyles = css`\n /* Base styles */\n :host {\n display: inline-block;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--bp-font-family);\n font-weight: var(--bp-font-weight-medium);\n line-height: 1;\n border-radius: var(--bp-border-radius-full);\n white-space: nowrap;\n transition:\n background-color var(--bp-transition-fast),\n color var(--bp-transition-fast);\n }\n\n /* Variants */\n .badge--primary {\n background-color: var(--bp-color-primary);\n color: var(--bp-color-text-inverse);\n }\n\n .badge--success {\n background-color: var(--bp-color-success);\n color: var(--bp-color-text-inverse);\n }\n\n .badge--error {\n background-color: var(--bp-color-error);\n color: var(--bp-color-text-inverse);\n }\n\n .badge--warning {\n background-color: var(--bp-color-warning);\n color: var(--bp-color-text-inverse);\n }\n\n .badge--info {\n background-color: var(--bp-color-info);\n color: var(--bp-color-text-inverse);\n }\n\n .badge--neutral {\n background-color: var(--bp-color-border-strong);\n color: var(--bp-color-text);\n }\n\n /* Sizes */\n .badge--sm {\n padding: var(--bp-spacing-xs) var(--bp-spacing-xs);\n font-size: var(--bp-font-size-xs);\n min-width: var(--bp-spacing-5);\n height: var(--bp-spacing-5);\n }\n\n .badge--md {\n padding: var(--bp-spacing-xs) var(--bp-spacing-sm);\n font-size: var(--bp-font-size-sm);\n min-width: var(--bp-spacing-6);\n height: var(--bp-spacing-6);\n }\n\n .badge--lg {\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\n font-size: var(--bp-font-size-base);\n min-width: var(--bp-spacing-8);\n height: var(--bp-spacing-8);\n }\n\n /* Dot variant */\n .badge--dot {\n padding: 0;\n border-radius: var(--bp-border-radius-full);\n }\n\n .badge--dot.badge--sm {\n width: var(--bp-spacing-2);\n height: var(--bp-spacing-2);\n min-width: var(--bp-spacing-2);\n }\n\n .badge--dot.badge--md {\n width: var(--bp-spacing-3);\n height: var(--bp-spacing-3);\n min-width: var(--bp-spacing-3);\n }\n\n .badge--dot.badge--lg {\n width: var(--bp-spacing-4);\n height: var(--bp-spacing-4);\n min-width: var(--bp-spacing-4);\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { badgeStyles } from './badge.style.js';\n\n/**\n * Badge component for displaying status indicators, counts, and labels.\n *\n * @element bp-badge\n *\n * @slot - Default slot for badge content (text or icons)\n *\n * @csspart badge - The badge container element\n *\n * @example\n * ```html\n * <bp-badge>New</bp-badge>\n * <bp-badge variant=\"success\">Active</bp-badge>\n * <bp-badge variant=\"error\" size=\"sm\">3</bp-badge>\n * ```\n */\n@customElement('bp-badge')\nexport class BpBadge extends LitElement {\n /**\n * Visual variant of the badge\n * @type {'primary' | 'success' | 'error' | 'warning' | 'info' | 'neutral'}\n * @default 'primary'\n */\n @property({ type: String, reflect: true }) declare variant:\n | 'primary'\n | 'success'\n | 'error'\n | 'warning'\n | 'info'\n | 'neutral';\n\n /**\n * Size of the badge\n * @type {'sm' | 'md' | 'lg'}\n * @default 'md'\n */\n @property({ type: String, reflect: true }) declare size: 'sm' | 'md' | 'lg';\n\n /**\n * Whether the badge is a dot/pill shape (for count indicators)\n * @type {boolean}\n * @default false\n */\n @property({ type: Boolean, reflect: true }) declare dot: boolean;\n\n static styles = [badgeStyles];\n\n constructor() {\n super();\n this.variant = 'primary';\n this.size = 'md';\n this.dot = false;\n }\n\n render() {\n return html`\n <span\n class=${classMap({\n badge: true,\n [`badge--${this.variant}`]: true,\n [`badge--${this.size}`]: true,\n 'badge--dot': this.dot,\n })}\n part=\"badge\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot></slot>\n </span>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-badge': BpBadge;\n }\n}\n"],"names":["badgeStyles","css","BpBadge","LitElement","html","classMap","__decorateClass","property","customElement"],"mappings":";;;AAEO,MAAMA,IAAcC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACoBpB,IAAMC,IAAN,cAAsBC,EAAW;AAAA,EA8BtC,cAAc;AACZ,UAAA,GACA,KAAK,UAAU,WACf,KAAK,OAAO,MACZ,KAAK,MAAM;AAAA,EACb;AAAA,EAEA,SAAS;AACP,WAAOC;AAAA;AAAA,gBAEKC,EAAS;AAAA,MACf,OAAO;AAAA,MACP,CAAC,UAAU,KAAK,OAAO,EAAE,GAAG;AAAA,MAC5B,CAAC,UAAU,KAAK,IAAI,EAAE,GAAG;AAAA,MACzB,cAAc,KAAK;AAAA,IAAA,CACpB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQR;AACF;AAtDaH,EA4BJ,SAAS,CAACF,CAAW;AAtBuBM,EAAA;AAAA,EAAlDC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAN9BL,EAMwC,WAAA,WAAA,CAAA;AAaAI,EAAA;AAAA,EAAlDC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAnB9BL,EAmBwC,WAAA,QAAA,CAAA;AAOCI,EAAA;AAAA,EAAnDC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA1B/BL,EA0ByC,WAAA,OAAA,CAAA;AA1BzCA,IAANI,EAAA;AAAA,EADNE,EAAc,UAAU;AAAA,GACZN,CAAA;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breadcrumb.js","sources":["../../source/components/breadcrumb/breadcrumb.style.ts","../../source/components/breadcrumb/breadcrumb.ts"],"sourcesContent":["import { css } from 'lit';\r\n\r\nexport const breadcrumbStyles = css`\r\n /* Base styles */\r\n :host {\r\n display: block;\r\n }\r\n\r\n /* Separator variants - set custom properties on host to cross shadow boundaries */\r\n :host([separator='slash']) {\r\n --bp-breadcrumb-separator-content: '/';\r\n }\r\n\r\n :host([separator='chevron']) {\r\n --bp-breadcrumb-separator-content: '›';\r\n --bp-breadcrumb-separator-size: 1.2em;\r\n }\r\n\r\n :host([separator='arrow']) {\r\n --bp-breadcrumb-separator-content: '→';\r\n }\r\n\r\n :host([separator='dot']) {\r\n --bp-breadcrumb-separator-content: '•';\r\n --bp-breadcrumb-separator-size: var(--bp-font-size-lg);\r\n }\r\n\r\n /* Size variants - set custom properties on host to cross shadow boundaries */\r\n :host([size='sm']) {\r\n --bp-breadcrumb-font-size: var(--bp-font-size-sm);\r\n --bp-breadcrumb-line-height: var(--bp-line-height-tight);\r\n }\r\n\r\n :host([size='md']) {\r\n --bp-breadcrumb-font-size: var(--bp-font-size-base);\r\n --bp-breadcrumb-line-height: var(--bp-line-height-normal);\r\n }\r\n\r\n :host([size='lg']) {\r\n --bp-breadcrumb-font-size: var(--bp-font-size-lg);\r\n --bp-breadcrumb-line-height: var(--bp-line-height-normal);\r\n }\r\n\r\n .breadcrumb {\r\n font-family: var(--bp-font-family);\r\n }\r\n\r\n .list {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n gap: 0;\r\n }\r\n\r\n .item {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 0;\r\n font-size: var(--bp-breadcrumb-font-size, var(--bp-font-size-base));\r\n line-height: var(--bp-breadcrumb-line-height, var(--bp-line-height-normal));\r\n }\r\n\r\n .item__icon {\r\n flex-shrink: 0;\r\n }\r\n\r\n .item__label {\r\n white-space: nowrap;\r\n }\r\n\r\n /* Link styles */\r\n .link {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--bp-spacing-xs);\r\n color: var(--bp-color-text-muted);\r\n text-decoration: none;\r\n transition: color var(--bp-transition-fast);\r\n outline: none;\r\n border-radius: var(--bp-border-radius);\r\n }\r\n\r\n .link:hover {\r\n color: var(--bp-color-primary);\r\n text-decoration: underline;\r\n }\r\n\r\n .link:active {\r\n transform: translateY(1px);\r\n }\r\n\r\n .link:focus-visible {\r\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\r\n outline-offset: var(--bp-focus-offset);\r\n }\r\n\r\n /* Text (non-link) styles */\r\n .text {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: var(--bp-spacing-xs);\r\n color: var(--bp-color-text);\r\n font-weight: var(--bp-font-weight-medium);\r\n }\r\n\r\n /* Current item */\r\n .item--current .text {\r\n color: var(--bp-color-text);\r\n }\r\n\r\n /* Separator styles */\r\n .separator {\r\n display: inline-flex;\r\n align-items: center;\r\n color: var(--bp-color-text-muted);\r\n margin: 0 var(--bp-spacing-2xs);\r\n user-select: none;\r\n }\r\n\r\n /* Hide separator on last item */\r\n :host(:last-of-type) .separator {\r\n display: none;\r\n }\r\n\r\n /* Separator content via ::before - uses custom properties from parent */\r\n .separator::before {\r\n content: var(--bp-breadcrumb-separator-content, '/');\r\n font-size: var(--bp-breadcrumb-separator-size, inherit);\r\n }\r\n\r\n .separator__icon {\r\n width: var(--bp-spacing-md);\r\n height: var(--bp-spacing-md);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .separator__icon--dot {\r\n font-size: var(--bp-font-size-lg);\r\n line-height: 1;\r\n }\r\n\r\n /* Ellipsis button */\r\n .ellipsis-button {\r\n appearance: none;\r\n border: none;\r\n background: transparent;\r\n padding: var(--bp-spacing-xs);\r\n margin: calc(-1 * var(--bp-spacing-xs));\r\n cursor: pointer;\r\n color: var(--bp-color-text-muted);\r\n border-radius: var(--bp-border-radius);\r\n transition: all var(--bp-transition-fast);\r\n outline: none;\r\n }\r\n\r\n .ellipsis-button:hover {\r\n color: var(--bp-color-primary);\r\n background: var(--bp-color-surface);\r\n }\r\n\r\n .ellipsis-button:active {\r\n transform: scale(0.95);\r\n }\r\n\r\n .ellipsis-button:focus-visible {\r\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\r\n outline-offset: var(--bp-focus-offset);\r\n }\r\n\r\n .ellipsis-dots {\r\n font-size: var(--bp-font-size-base);\r\n letter-spacing: var(--bp-spacing-0-5);\r\n }\r\n\r\n /* Sizes */\r\n .breadcrumb--sm {\r\n font-size: var(--bp-font-size-sm);\r\n line-height: var(--bp-line-height-tight);\r\n }\r\n\r\n .breadcrumb--sm .separator__icon {\r\n width: var(--bp-spacing-sm);\r\n height: var(--bp-spacing-sm);\r\n }\r\n\r\n .breadcrumb--md {\r\n font-size: var(--bp-font-size-base);\r\n line-height: var(--bp-line-height-normal);\r\n }\r\n\r\n .breadcrumb--md .separator__icon {\r\n width: var(--bp-spacing-md);\r\n height: var(--bp-spacing-md);\r\n }\r\n\r\n .breadcrumb--lg {\r\n font-size: var(--bp-font-size-lg);\r\n line-height: var(--bp-line-height-normal);\r\n }\r\n\r\n .breadcrumb--lg .separator__icon {\r\n width: var(--bp-spacing-lg);\r\n height: var(--bp-spacing-lg);\r\n }\r\n\r\n /* Separator variants */\r\n .breadcrumb--slash .separator__icon {\r\n font-size: inherit;\r\n }\r\n\r\n .breadcrumb--dot .separator__icon {\r\n font-size: inherit;\r\n }\r\n\r\n /* Item ellipsis */\r\n .item--ellipsis {\r\n display: inline-flex;\r\n }\r\n\r\n /* Collapse on mobile - handled via maxItems property instead of CSS */\r\n .breadcrumb--collapse-mobile {\r\n /* Reserved for future container query support */\r\n }\r\n`;\r\n","import { LitElement, html, nothing } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { ifDefined } from 'lit/directives/if-defined.js';\r\nimport { breadcrumbStyles } from './breadcrumb.style.js';\r\nimport type { IconName } from '../icon/icons/registry.generated.js';\r\n\r\nexport type BreadcrumbSize = 'sm' | 'md' | 'lg';\r\nexport type BreadcrumbSeparator = 'slash' | 'chevron' | 'arrow' | 'dot';\r\n\r\n/**\r\n * Breadcrumb item interface for programmatic configuration\r\n */\r\nexport interface BreadcrumbItem {\r\n /** Display label for the breadcrumb item */\r\n label: string;\r\n /** URL for the breadcrumb link (omit for current page) */\r\n href?: string;\r\n /** Icon name to display before the label */\r\n icon?: IconName;\r\n /** Whether this is the current/active page */\r\n current?: boolean;\r\n}\r\n\r\n/**\r\n * A breadcrumb navigation component showing the user's location in a hierarchy.\r\n *\r\n * @element bp-breadcrumb\r\n *\r\n * @property {BreadcrumbItem[]} items - Array of breadcrumb items\r\n * @property {BreadcrumbSize} size - The size of the breadcrumb\r\n * @property {BreadcrumbSeparator} separator - The separator style between items\r\n * @property {string} ariaLabel - Accessible label for the navigation\r\n * @property {boolean} collapseOnMobile - Whether to collapse middle items on small screens\r\n * @property {number} maxItems - Maximum visible items before collapsing (0 = no limit)\r\n *\r\n * @slot - Default slot for custom breadcrumb items\r\n * @slot separator - Custom separator content\r\n *\r\n * @fires bp-breadcrumb-click - Fired when a breadcrumb item is clicked\r\n *\r\n * @csspart nav - The nav element wrapper\r\n * @csspart list - The ordered list element\r\n * @csspart item - Individual breadcrumb item\r\n * @csspart item-current - The current/active breadcrumb item\r\n * @csspart link - Breadcrumb link element\r\n * @csspart separator - Separator between items\r\n * @csspart ellipsis - The ellipsis button when items are collapsed\r\n */\r\n@customElement('bp-breadcrumb')\r\nexport class BpBreadcrumb extends LitElement {\r\n /**\r\n * Array of breadcrumb items\r\n */\r\n @property({ type: Array }) declare items: BreadcrumbItem[];\r\n\r\n /**\r\n * The size of the breadcrumb\r\n */\r\n @property({ type: String, reflect: true }) declare size: BreadcrumbSize;\r\n\r\n /**\r\n * The separator style between items\r\n */\r\n @property({ type: String, reflect: true })\r\n declare separator: BreadcrumbSeparator;\r\n\r\n /**\r\n * Accessible label for the navigation landmark\r\n */\r\n @property({ type: String, attribute: 'aria-label' })\r\n declare ariaLabel: string;\r\n\r\n /**\r\n * Whether to collapse middle items on small screens\r\n */\r\n @property({ type: Boolean, attribute: 'collapse-on-mobile' })\r\n declare collapseOnMobile: boolean;\r\n\r\n /**\r\n * Maximum visible items before collapsing (0 = no limit)\r\n */\r\n @property({ type: Number, attribute: 'max-items' }) declare maxItems: number;\r\n\r\n static styles = [breadcrumbStyles];\r\n\r\n constructor() {\r\n super();\r\n this.items = [];\r\n this.size = 'md';\r\n this.separator = 'slash';\r\n this.ariaLabel = 'Breadcrumb';\r\n this.collapseOnMobile = false;\r\n this.maxItems = 0;\r\n }\r\n\r\n private handleItemClick(\r\n _event: MouseEvent,\r\n item: BreadcrumbItem,\r\n index: number\r\n ) {\r\n // Don't prevent default for actual navigation\r\n this.dispatchEvent(\r\n new CustomEvent('bp-breadcrumb-click', {\r\n detail: { item, index },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n\r\n private handleKeyDown(\r\n event: KeyboardEvent,\r\n item: BreadcrumbItem,\r\n index: number\r\n ) {\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n if (!item.href) {\r\n event.preventDefault();\r\n }\r\n this.dispatchEvent(\r\n new CustomEvent('bp-breadcrumb-click', {\r\n detail: { item, index },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n }\r\n\r\n private renderSeparator() {\r\n const separatorIcons = {\r\n slash: html`<span class=\"separator__icon\">/</span>`,\r\n chevron: html`\r\n <svg\r\n class=\"separator__icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <path d=\"M9 18l6-6-6-6\" />\r\n </svg>\r\n `,\r\n arrow: html`\r\n <svg\r\n class=\"separator__icon\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n >\r\n <path d=\"M5 12h14M12 5l7 7-7 7\" />\r\n </svg>\r\n `,\r\n dot: html`<span class=\"separator__icon separator__icon--dot\">•</span>`,\r\n };\r\n\r\n return html`\r\n <span class=\"separator\" part=\"separator\" aria-hidden=\"true\">\r\n <slot name=\"separator\">${separatorIcons[this.separator]}</slot>\r\n </span>\r\n `;\r\n }\r\n\r\n private renderItem(item: BreadcrumbItem, index: number, isLast: boolean) {\r\n const isCurrent = item.current || isLast;\r\n const itemClasses = {\r\n item: true,\r\n 'item--current': isCurrent,\r\n };\r\n\r\n return html`\r\n <li\r\n class=${classMap(itemClasses)}\r\n part=\"item ${isCurrent ? 'item-current' : ''}\"\r\n >\r\n ${item.href && !isCurrent\r\n ? html`\r\n <a\r\n class=\"link\"\r\n part=\"link\"\r\n href=${item.href}\r\n @click=${(e: MouseEvent) =>\r\n this.handleItemClick(e, item, index)}\r\n @keydown=${(e: KeyboardEvent) =>\r\n this.handleKeyDown(e, item, index)}\r\n >\r\n ${item.icon\r\n ? html`<bp-icon\r\n name=${item.icon}\r\n class=\"item__icon\"\r\n ></bp-icon>`\r\n : nothing}\r\n <span class=\"item__label\">${item.label}</span>\r\n </a>\r\n `\r\n : html`\r\n <span\r\n class=\"text\"\r\n part=\"text\"\r\n aria-current=${ifDefined(isCurrent ? 'page' : undefined)}\r\n >\r\n ${item.icon\r\n ? html`<bp-icon\r\n name=${item.icon}\r\n class=\"item__icon\"\r\n ></bp-icon>`\r\n : nothing}\r\n <span class=\"item__label\">${item.label}</span>\r\n </span>\r\n `}\r\n ${!isLast ? this.renderSeparator() : nothing}\r\n </li>\r\n `;\r\n }\r\n\r\n private renderEllipsis(hiddenCount: number) {\r\n return html`\r\n <li class=\"item item--ellipsis\" part=\"item ellipsis\">\r\n <button\r\n class=\"ellipsis-button\"\r\n part=\"ellipsis-button\"\r\n aria-label=\"Show ${hiddenCount} more items\"\r\n title=\"Show ${hiddenCount} more items\"\r\n >\r\n <span class=\"ellipsis-dots\">…</span>\r\n </button>\r\n ${this.renderSeparator()}\r\n </li>\r\n `;\r\n }\r\n\r\n private getVisibleItems(): {\r\n items: BreadcrumbItem[];\r\n hiddenCount: number;\r\n showEllipsis: boolean;\r\n } {\r\n if (this.maxItems <= 0 || this.items.length <= this.maxItems) {\r\n return { items: this.items, hiddenCount: 0, showEllipsis: false };\r\n }\r\n\r\n // Show first item, ellipsis, and last (maxItems - 1) items\r\n const firstItem = this.items[0];\r\n const lastItems = this.items.slice(-(this.maxItems - 1));\r\n const hiddenCount = this.items.length - this.maxItems;\r\n\r\n return {\r\n items: [firstItem, ...lastItems],\r\n hiddenCount,\r\n showEllipsis: true,\r\n };\r\n }\r\n\r\n render() {\r\n const containerClasses = {\r\n breadcrumb: true,\r\n [`breadcrumb--${this.size}`]: true,\r\n [`breadcrumb--separator-${this.separator}`]: true,\r\n 'breadcrumb--collapse-mobile': this.collapseOnMobile,\r\n };\r\n\r\n const {\r\n items: visibleItems,\r\n hiddenCount,\r\n showEllipsis,\r\n } = this.getVisibleItems();\r\n\r\n // If using programmatic items\r\n if (this.items.length > 0) {\r\n return html`\r\n <nav\r\n class=${classMap(containerClasses)}\r\n part=\"nav\"\r\n aria-label=${this.ariaLabel}\r\n >\r\n <ol class=\"list\" part=\"list\">\r\n ${showEllipsis\r\n ? html`\r\n ${this.renderItem(visibleItems[0], 0, false)}\r\n ${this.renderEllipsis(hiddenCount)}\r\n ${repeat(\r\n visibleItems.slice(1),\r\n (_item, index) => index,\r\n (item, index) =>\r\n this.renderItem(\r\n item,\r\n this.items.length - visibleItems.length + 1 + index,\r\n index === visibleItems.length - 2\r\n )\r\n )}\r\n `\r\n : repeat(\r\n visibleItems,\r\n (_item, index) => index,\r\n (item, index) =>\r\n this.renderItem(\r\n item,\r\n index,\r\n index === visibleItems.length - 1\r\n )\r\n )}\r\n </ol>\r\n </nav>\r\n `;\r\n }\r\n\r\n // Slotted content fallback\r\n return html`\r\n <nav\r\n class=${classMap(containerClasses)}\r\n part=\"nav\"\r\n aria-label=${this.ariaLabel}\r\n >\r\n <ol class=\"list\" part=\"list\">\r\n <slot></slot>\r\n </ol>\r\n </nav>\r\n `;\r\n }\r\n}\r\n\r\n/**\r\n * A breadcrumb item component for use with bp-breadcrumb.\r\n *\r\n * @element bp-breadcrumb-item\r\n *\r\n * @property {string} href - URL for the breadcrumb link\r\n * @property {boolean} current - Whether this is the current page\r\n *\r\n * @slot - Content of the breadcrumb item\r\n *\r\n * @csspart item - The item container\r\n * @csspart link - The link element (when href is provided)\r\n */\r\n@customElement('bp-breadcrumb-item')\r\nexport class BpBreadcrumbItem extends LitElement {\r\n /**\r\n * URL for the breadcrumb link (omit for current page)\r\n */\r\n @property({ type: String }) declare href: string;\r\n\r\n /**\r\n * Whether this is the current/active page\r\n */\r\n @property({ type: Boolean, reflect: true }) declare current: boolean;\r\n\r\n static styles = [breadcrumbStyles];\r\n\r\n constructor() {\r\n super();\r\n this.href = '';\r\n this.current = false;\r\n }\r\n\r\n render() {\r\n const itemClasses = {\r\n item: true,\r\n 'item--current': this.current,\r\n };\r\n\r\n return html`\r\n <li\r\n class=${classMap(itemClasses)}\r\n part=\"item ${this.current ? 'item-current' : ''}\"\r\n >\r\n ${this.href && !this.current\r\n ? html`\r\n <a class=\"link\" part=\"link\" href=${this.href}>\r\n <slot></slot>\r\n </a>\r\n `\r\n : html`\r\n <span\r\n class=\"text\"\r\n part=\"text\"\r\n aria-current=${ifDefined(this.current ? 'page' : undefined)}\r\n >\r\n <slot></slot>\r\n </span>\r\n `}\r\n <span class=\"separator\" part=\"separator\" aria-hidden=\"true\"></span>\r\n </li>\r\n `;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'bp-breadcrumb': BpBreadcrumb;\r\n 'bp-breadcrumb-item': BpBreadcrumbItem;\r\n }\r\n}\r\n"],"names":["breadcrumbStyles","css","BpBreadcrumb","LitElement","_event","item","index","event","separatorIcons","html","isLast","isCurrent","classMap","e","nothing","ifDefined","hiddenCount","firstItem","lastItems","containerClasses","visibleItems","showEllipsis","repeat","_item","__decorateClass","property","customElement","BpBreadcrumbItem","itemClasses"],"mappings":";;;;;AAEO,MAAMA,IAAmBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACiDzB,IAAMC,IAAN,cAA2BC,EAAW;AAAA,EAoC3C,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"}
|
|
1
|
+
{"version":3,"file":"breadcrumb.js","sources":["../../source/components/breadcrumb/breadcrumb.style.ts","../../source/components/breadcrumb/breadcrumb.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const breadcrumbStyles = css`\n /* Base styles */\n :host {\n display: block;\n }\n\n /* Separator variants - set custom properties on host to cross shadow boundaries */\n :host([separator='slash']) {\n --bp-breadcrumb-separator-content: '/';\n }\n\n :host([separator='chevron']) {\n --bp-breadcrumb-separator-content: '›';\n --bp-breadcrumb-separator-size: 1.2em;\n }\n\n :host([separator='arrow']) {\n --bp-breadcrumb-separator-content: '→';\n }\n\n :host([separator='dot']) {\n --bp-breadcrumb-separator-content: '•';\n --bp-breadcrumb-separator-size: var(--bp-font-size-lg);\n }\n\n /* Size variants - set custom properties on host to cross shadow boundaries */\n :host([size='sm']) {\n --bp-breadcrumb-font-size: var(--bp-font-size-sm);\n --bp-breadcrumb-line-height: var(--bp-line-height-tight);\n }\n\n :host([size='md']) {\n --bp-breadcrumb-font-size: var(--bp-font-size-base);\n --bp-breadcrumb-line-height: var(--bp-line-height-normal);\n }\n\n :host([size='lg']) {\n --bp-breadcrumb-font-size: var(--bp-font-size-lg);\n --bp-breadcrumb-line-height: var(--bp-line-height-normal);\n }\n\n .breadcrumb {\n font-family: var(--bp-font-family);\n }\n\n .list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n list-style: none;\n margin: 0;\n padding: 0;\n gap: 0;\n }\n\n .item {\n display: inline-flex;\n align-items: center;\n gap: 0;\n font-size: var(--bp-breadcrumb-font-size, var(--bp-font-size-base));\n line-height: var(--bp-breadcrumb-line-height, var(--bp-line-height-normal));\n }\n\n .item__icon {\n flex-shrink: 0;\n }\n\n .item__label {\n white-space: nowrap;\n }\n\n /* Link styles */\n .link {\n display: inline-flex;\n align-items: center;\n gap: var(--bp-spacing-xs);\n color: var(--bp-color-text-muted);\n text-decoration: none;\n transition: color var(--bp-transition-fast);\n outline: none;\n border-radius: var(--bp-border-radius);\n }\n\n .link:hover {\n color: var(--bp-color-primary);\n text-decoration: underline;\n }\n\n .link:active {\n transform: translateY(1px);\n }\n\n .link:focus-visible {\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\n outline-offset: var(--bp-focus-offset);\n }\n\n /* Text (non-link) styles */\n .text {\n display: inline-flex;\n align-items: center;\n gap: var(--bp-spacing-xs);\n color: var(--bp-color-text);\n font-weight: var(--bp-font-weight-medium);\n }\n\n /* Current item */\n .item--current .text {\n color: var(--bp-color-text);\n }\n\n /* Separator styles */\n .separator {\n display: inline-flex;\n align-items: center;\n color: var(--bp-color-text-muted);\n margin: 0 var(--bp-spacing-2xs);\n user-select: none;\n }\n\n /* Hide separator on last item */\n :host(:last-of-type) .separator {\n display: none;\n }\n\n /* Separator content via ::before - uses custom properties from parent */\n .separator::before {\n content: var(--bp-breadcrumb-separator-content, '/');\n font-size: var(--bp-breadcrumb-separator-size, inherit);\n }\n\n .separator__icon {\n width: var(--bp-spacing-md);\n height: var(--bp-spacing-md);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .separator__icon--dot {\n font-size: var(--bp-font-size-lg);\n line-height: 1;\n }\n\n /* Ellipsis button */\n .ellipsis-button {\n appearance: none;\n border: none;\n background: transparent;\n padding: var(--bp-spacing-xs);\n margin: calc(-1 * var(--bp-spacing-xs));\n cursor: pointer;\n color: var(--bp-color-text-muted);\n border-radius: var(--bp-border-radius);\n transition: all var(--bp-transition-fast);\n outline: none;\n }\n\n .ellipsis-button:hover {\n color: var(--bp-color-primary);\n background: var(--bp-color-surface);\n }\n\n .ellipsis-button:active {\n transform: scale(0.95);\n }\n\n .ellipsis-button:focus-visible {\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\n outline-offset: var(--bp-focus-offset);\n }\n\n .ellipsis-dots {\n font-size: var(--bp-font-size-base);\n letter-spacing: var(--bp-spacing-0-5);\n }\n\n /* Sizes */\n .breadcrumb--sm {\n font-size: var(--bp-font-size-sm);\n line-height: var(--bp-line-height-tight);\n }\n\n .breadcrumb--sm .separator__icon {\n width: var(--bp-spacing-sm);\n height: var(--bp-spacing-sm);\n }\n\n .breadcrumb--md {\n font-size: var(--bp-font-size-base);\n line-height: var(--bp-line-height-normal);\n }\n\n .breadcrumb--md .separator__icon {\n width: var(--bp-spacing-md);\n height: var(--bp-spacing-md);\n }\n\n .breadcrumb--lg {\n font-size: var(--bp-font-size-lg);\n line-height: var(--bp-line-height-normal);\n }\n\n .breadcrumb--lg .separator__icon {\n width: var(--bp-spacing-lg);\n height: var(--bp-spacing-lg);\n }\n\n /* Separator variants */\n .breadcrumb--slash .separator__icon {\n font-size: inherit;\n }\n\n .breadcrumb--dot .separator__icon {\n font-size: inherit;\n }\n\n /* Item ellipsis */\n .item--ellipsis {\n display: inline-flex;\n }\n\n /* Collapse on mobile - handled via maxItems property instead of CSS */\n .breadcrumb--collapse-mobile {\n /* Reserved for future container query support */\n }\n`;\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { breadcrumbStyles } from './breadcrumb.style.js';\nimport type { IconName } from '../icon/icons/registry.generated.js';\n\nexport type BreadcrumbSize = 'sm' | 'md' | 'lg';\nexport type BreadcrumbSeparator = 'slash' | 'chevron' | 'arrow' | 'dot';\n\n/**\n * Breadcrumb item interface for programmatic configuration\n */\nexport interface BreadcrumbItem {\n /** Display label for the breadcrumb item */\n label: string;\n /** URL for the breadcrumb link (omit for current page) */\n href?: string;\n /** Icon name to display before the label */\n icon?: IconName;\n /** Whether this is the current/active page */\n current?: boolean;\n}\n\n/**\n * A breadcrumb navigation component showing the user's location in a hierarchy.\n *\n * @element bp-breadcrumb\n *\n * @property {BreadcrumbItem[]} items - Array of breadcrumb items\n * @property {BreadcrumbSize} size - The size of the breadcrumb\n * @property {BreadcrumbSeparator} separator - The separator style between items\n * @property {string} ariaLabel - Accessible label for the navigation\n * @property {boolean} collapseOnMobile - Whether to collapse middle items on small screens\n * @property {number} maxItems - Maximum visible items before collapsing (0 = no limit)\n *\n * @slot - Default slot for custom breadcrumb items\n * @slot separator - Custom separator content\n *\n * @fires bp-breadcrumb-click - Fired when a breadcrumb item is clicked\n *\n * @csspart nav - The nav element wrapper\n * @csspart list - The ordered list element\n * @csspart item - Individual breadcrumb item\n * @csspart item-current - The current/active breadcrumb item\n * @csspart link - Breadcrumb link element\n * @csspart separator - Separator between items\n * @csspart ellipsis - The ellipsis button when items are collapsed\n */\n@customElement('bp-breadcrumb')\nexport class BpBreadcrumb extends LitElement {\n /**\n * Array of breadcrumb items\n */\n @property({ type: Array }) declare items: BreadcrumbItem[];\n\n /**\n * The size of the breadcrumb\n */\n @property({ type: String, reflect: true }) declare size: BreadcrumbSize;\n\n /**\n * The separator style between items\n */\n @property({ type: String, reflect: true })\n declare separator: BreadcrumbSeparator;\n\n /**\n * Accessible label for the navigation landmark\n */\n @property({ type: String, attribute: 'aria-label' })\n declare ariaLabel: string;\n\n /**\n * Whether to collapse middle items on small screens\n */\n @property({ type: Boolean, attribute: 'collapse-on-mobile' })\n declare collapseOnMobile: boolean;\n\n /**\n * Maximum visible items before collapsing (0 = no limit)\n */\n @property({ type: Number, attribute: 'max-items' }) declare maxItems: number;\n\n static styles = [breadcrumbStyles];\n\n constructor() {\n super();\n this.items = [];\n this.size = 'md';\n this.separator = 'slash';\n this.ariaLabel = 'Breadcrumb';\n this.collapseOnMobile = false;\n this.maxItems = 0;\n }\n\n private handleItemClick(\n _event: MouseEvent,\n item: BreadcrumbItem,\n index: number\n ) {\n // Don't prevent default for actual navigation\n this.dispatchEvent(\n new CustomEvent('bp-breadcrumb-click', {\n detail: { item, index },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleKeyDown(\n event: KeyboardEvent,\n item: BreadcrumbItem,\n index: number\n ) {\n if (event.key === 'Enter' || event.key === ' ') {\n if (!item.href) {\n event.preventDefault();\n }\n this.dispatchEvent(\n new CustomEvent('bp-breadcrumb-click', {\n detail: { item, index },\n bubbles: true,\n composed: true,\n })\n );\n }\n }\n\n private renderSeparator() {\n const separatorIcons = {\n slash: html`<span class=\"separator__icon\">/</span>`,\n chevron: html`\n <svg\n class=\"separator__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n `,\n arrow: html`\n <svg\n class=\"separator__icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <path d=\"M5 12h14M12 5l7 7-7 7\" />\n </svg>\n `,\n dot: html`<span class=\"separator__icon separator__icon--dot\">•</span>`,\n };\n\n return html`\n <span class=\"separator\" part=\"separator\" aria-hidden=\"true\">\n <slot name=\"separator\">${separatorIcons[this.separator]}</slot>\n </span>\n `;\n }\n\n private renderItem(item: BreadcrumbItem, index: number, isLast: boolean) {\n const isCurrent = item.current || isLast;\n const itemClasses = {\n item: true,\n 'item--current': isCurrent,\n };\n\n return html`\n <li\n class=${classMap(itemClasses)}\n part=\"item ${isCurrent ? 'item-current' : ''}\"\n >\n ${item.href && !isCurrent\n ? html`\n <a\n class=\"link\"\n part=\"link\"\n href=${item.href}\n @click=${(e: MouseEvent) =>\n this.handleItemClick(e, item, index)}\n @keydown=${(e: KeyboardEvent) =>\n this.handleKeyDown(e, item, index)}\n >\n ${item.icon\n ? html`<bp-icon\n name=${item.icon}\n class=\"item__icon\"\n ></bp-icon>`\n : nothing}\n <span class=\"item__label\">${item.label}</span>\n </a>\n `\n : html`\n <span\n class=\"text\"\n part=\"text\"\n aria-current=${ifDefined(isCurrent ? 'page' : undefined)}\n >\n ${item.icon\n ? html`<bp-icon\n name=${item.icon}\n class=\"item__icon\"\n ></bp-icon>`\n : nothing}\n <span class=\"item__label\">${item.label}</span>\n </span>\n `}\n ${!isLast ? this.renderSeparator() : nothing}\n </li>\n `;\n }\n\n private renderEllipsis(hiddenCount: number) {\n return html`\n <li class=\"item item--ellipsis\" part=\"item ellipsis\">\n <button\n class=\"ellipsis-button\"\n part=\"ellipsis-button\"\n aria-label=\"Show ${hiddenCount} more items\"\n title=\"Show ${hiddenCount} more items\"\n >\n <span class=\"ellipsis-dots\">…</span>\n </button>\n ${this.renderSeparator()}\n </li>\n `;\n }\n\n private getVisibleItems(): {\n items: BreadcrumbItem[];\n hiddenCount: number;\n showEllipsis: boolean;\n } {\n if (this.maxItems <= 0 || this.items.length <= this.maxItems) {\n return { items: this.items, hiddenCount: 0, showEllipsis: false };\n }\n\n // Show first item, ellipsis, and last (maxItems - 1) items\n const firstItem = this.items[0];\n const lastItems = this.items.slice(-(this.maxItems - 1));\n const hiddenCount = this.items.length - this.maxItems;\n\n return {\n items: [firstItem, ...lastItems],\n hiddenCount,\n showEllipsis: true,\n };\n }\n\n render() {\n const containerClasses = {\n breadcrumb: true,\n [`breadcrumb--${this.size}`]: true,\n [`breadcrumb--separator-${this.separator}`]: true,\n 'breadcrumb--collapse-mobile': this.collapseOnMobile,\n };\n\n const {\n items: visibleItems,\n hiddenCount,\n showEllipsis,\n } = this.getVisibleItems();\n\n // If using programmatic items\n if (this.items.length > 0) {\n return html`\n <nav\n class=${classMap(containerClasses)}\n part=\"nav\"\n aria-label=${this.ariaLabel}\n >\n <ol class=\"list\" part=\"list\">\n ${showEllipsis\n ? html`\n ${this.renderItem(visibleItems[0], 0, false)}\n ${this.renderEllipsis(hiddenCount)}\n ${repeat(\n visibleItems.slice(1),\n (_item, index) => index,\n (item, index) =>\n this.renderItem(\n item,\n this.items.length - visibleItems.length + 1 + index,\n index === visibleItems.length - 2\n )\n )}\n `\n : repeat(\n visibleItems,\n (_item, index) => index,\n (item, index) =>\n this.renderItem(\n item,\n index,\n index === visibleItems.length - 1\n )\n )}\n </ol>\n </nav>\n `;\n }\n\n // Slotted content fallback\n return html`\n <nav\n class=${classMap(containerClasses)}\n part=\"nav\"\n aria-label=${this.ariaLabel}\n >\n <ol class=\"list\" part=\"list\">\n <slot></slot>\n </ol>\n </nav>\n `;\n }\n}\n\n/**\n * A breadcrumb item component for use with bp-breadcrumb.\n *\n * @element bp-breadcrumb-item\n *\n * @property {string} href - URL for the breadcrumb link\n * @property {boolean} current - Whether this is the current page\n *\n * @slot - Content of the breadcrumb item\n *\n * @csspart item - The item container\n * @csspart link - The link element (when href is provided)\n */\n@customElement('bp-breadcrumb-item')\nexport class BpBreadcrumbItem extends LitElement {\n /**\n * URL for the breadcrumb link (omit for current page)\n */\n @property({ type: String }) declare href: string;\n\n /**\n * Whether this is the current/active page\n */\n @property({ type: Boolean, reflect: true }) declare current: boolean;\n\n static styles = [breadcrumbStyles];\n\n constructor() {\n super();\n this.href = '';\n this.current = false;\n }\n\n render() {\n const itemClasses = {\n item: true,\n 'item--current': this.current,\n };\n\n return html`\n <li\n class=${classMap(itemClasses)}\n part=\"item ${this.current ? 'item-current' : ''}\"\n >\n ${this.href && !this.current\n ? html`\n <a class=\"link\" part=\"link\" href=${this.href}>\n <slot></slot>\n </a>\n `\n : html`\n <span\n class=\"text\"\n part=\"text\"\n aria-current=${ifDefined(this.current ? 'page' : undefined)}\n >\n <slot></slot>\n </span>\n `}\n <span class=\"separator\" part=\"separator\" aria-hidden=\"true\"></span>\n </li>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-breadcrumb': BpBreadcrumb;\n 'bp-breadcrumb-item': BpBreadcrumbItem;\n }\n}\n"],"names":["breadcrumbStyles","css","BpBreadcrumb","LitElement","_event","item","index","event","separatorIcons","html","isLast","isCurrent","classMap","e","nothing","ifDefined","hiddenCount","firstItem","lastItems","containerClasses","visibleItems","showEllipsis","repeat","_item","__decorateClass","property","customElement","BpBreadcrumbItem","itemClasses"],"mappings":";;;;;AAEO,MAAMA,IAAmBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACiDzB,IAAMC,IAAN,cAA2BC,EAAW;AAAA,EAoC3C,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","sources":["../../source/components/card/card.style.ts","../../source/components/card/card.ts"],"sourcesContent":["import { css } from 'lit';\r\n\r\nexport const cardStyles = css`\r\n /* Base styles */\r\n :host {\r\n display: block;\r\n }\r\n\r\n .card {\r\n font-family: var(--bp-font-family);\r\n background-color: var(--bp-color-surface-elevated);\r\n border-radius: var(--bp-border-radius-lg);\r\n overflow: hidden;\r\n transition:\r\n box-shadow var(--bp-transition-fast),\r\n transform var(--bp-transition-base),\r\n border-color var(--bp-transition-fast);\r\n }\r\n\r\n /* Content layout (media + body wrapper) */\r\n .card-content {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .card-content--horizontal {\r\n flex-direction: row;\r\n }\r\n\r\n .card-content--horizontal ::slotted([slot='media']) {\r\n width: auto;\r\n max-width: 50%;\r\n flex-shrink: 0;\r\n }\r\n\r\n .card-body {\r\n padding: var(--bp-spacing-lg);\r\n font-size: var(--bp-font-size-base);\r\n line-height: var(--bp-line-height-relaxed);\r\n color: var(--bp-color-text);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .card-body--no-padding {\r\n padding: 0;\r\n }\r\n\r\n /* Header and footer container styles */\r\n .card-header {\r\n padding: var(--bp-spacing-lg);\r\n border-bottom: var(--bp-border-width) solid var(--bp-color-border);\r\n font-weight: var(--bp-font-weight-semibold);\r\n font-size: var(--bp-font-size-lg);\r\n line-height: 1.4;\r\n color: var(--bp-color-text-strong);\r\n }\r\n\r\n .card-footer {\r\n padding: var(--bp-spacing-lg);\r\n border-top: var(--bp-border-width) solid var(--bp-color-border);\r\n font-size: var(--bp-font-size-sm);\r\n color: var(--bp-color-text-muted);\r\n }\r\n\r\n /* Media slot styles */\r\n ::slotted([slot='media']) {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 100%;\r\n }\r\n\r\n /* Variants */\r\n .card--default {\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n box-shadow: var(--bp-shadow-sm);\r\n }\r\n\r\n .card--outlined {\r\n border: var(--bp-border-width) solid var(--bp-color-border-strong);\r\n box-shadow: none;\r\n }\r\n\r\n .card--elevated {\r\n border: none;\r\n box-shadow: var(--bp-shadow-lg);\r\n }\r\n\r\n /* States */\r\n .card--default.card--hoverable:hover,\r\n .card--default.card--clickable:hover {\r\n box-shadow: var(--bp-shadow-md);\r\n border-color: var(--bp-color-border-strong);\r\n }\r\n\r\n .card--outlined.card--hoverable:hover,\r\n .card--outlined.card--clickable:hover {\r\n box-shadow: var(--bp-shadow-md);\r\n }\r\n\r\n .card--elevated.card--hoverable:hover,\r\n .card--elevated.card--clickable:hover {\r\n box-shadow: var(--bp-shadow-xl);\r\n }\r\n\r\n .card--clickable {\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n\r\n .card--clickable:focus-visible {\r\n outline: var(--bp-focus-ring);\r\n outline-offset: var(--bp-focus-offset);\r\n }\r\n\r\n .card--clickable:active {\r\n box-shadow: var(--bp-shadow-sm);\r\n }\r\n`;\r\n","import { LitElement, html } from 'lit';\r\nimport { customElement, property } from 'lit/decorators.js';\r\nimport { ifDefined } from 'lit/directives/if-defined.js';\r\nimport { cardStyles } from './card.style.js';\r\n\r\nexport type CardVariant = 'default' | 'outlined' | 'elevated';\r\nexport type CardDirection = 'vertical' | 'horizontal';\r\n/**\r\n * A versatile card component for organizing and displaying content.\r\n *\r\n * @slot - Default slot for card body content\r\n * @slot header - Optional header section\r\n * @slot footer - Optional footer section\r\n * @slot media - Optional media section (images, illustrations, etc.)\r\n *\r\n * @fires bp-click - Fired when clickable card is clicked\r\n */\r\n@customElement('bp-card')\r\nexport class BpCard extends LitElement {\r\n /**\r\n * Visual variant of the card\r\n */\r\n @property({ type: String, reflect: true }) declare variant: CardVariant;\r\n\r\n /**\r\n * Whether the card should display a hover effect\r\n */\r\n @property({ type: Boolean, reflect: true }) declare hoverable: boolean;\r\n\r\n /**\r\n * Whether the card is clickable (shows pointer cursor and emits click events)\r\n */\r\n @property({ type: Boolean, reflect: true }) declare clickable: boolean;\r\n\r\n /**\r\n * Whether to remove default padding from the card body\r\n */\r\n @property({ type: Boolean, reflect: true }) declare noPadding: boolean;\r\n\r\n /**\r\n * Layout direction for the card content (media + body area).\r\n * 'vertical' stacks media above body, 'horizontal' places them side by side.\r\n * Header and footer are unaffected and remain full-width.\r\n */\r\n @property({ type: String, reflect: true }) declare direction: CardDirection;\r\n\r\n /** Whether the header slot has assigned content */\r\n @property({ type: Boolean, attribute: false })\r\n private hasHeader = false;\r\n\r\n /** Whether the footer slot has assigned content */\r\n @property({ type: Boolean, attribute: false })\r\n private hasFooter = false;\r\n\r\n static styles = [cardStyles];\r\n\r\n constructor() {\r\n super();\r\n this.variant = 'default';\r\n this.hoverable = false;\r\n this.clickable = false;\r\n this.noPadding = false;\r\n this.direction = 'vertical';\r\n }\r\n\r\n /**\r\n * Handles slot change events for the header slot.\r\n * Updates hasHeader state to control header visibility.\r\n */\r\n private handleHeaderSlotChange = (event: Event): void => {\r\n const slot = event.target as HTMLElement & {\r\n assignedNodes: (options?: { flatten?: boolean }) => Node[];\r\n };\r\n this.hasHeader = slot.assignedNodes({ flatten: true }).length > 0;\r\n };\r\n\r\n /**\r\n * Handles slot change events for the footer slot.\r\n * Updates hasFooter state to control footer visibility.\r\n */\r\n private handleFooterSlotChange = (event: Event): void => {\r\n const slot = event.target as HTMLElement & {\r\n assignedNodes: (options?: { flatten?: boolean }) => Node[];\r\n };\r\n this.hasFooter = slot.assignedNodes({ flatten: true }).length > 0;\r\n };\r\n\r\n private handleClick(event: MouseEvent) {\r\n if (!this.clickable) return;\r\n\r\n // Only prevent default if not clicking on interactive elements\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('a, button, input, select, textarea')) {\r\n event.preventDefault();\r\n }\r\n\r\n this.dispatchEvent(\r\n new CustomEvent('bp-click', {\r\n detail: { originalEvent: event },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n }\r\n\r\n render() {\r\n return html`\r\n <div\r\n class=\"card card--${this.variant} ${this.hoverable || this.clickable\r\n ? 'card--hoverable'\r\n : ''} ${this.clickable ? 'card--clickable' : ''}\"\r\n part=\"card\"\r\n @click=${this.handleClick}\r\n role=${this.clickable ? 'button' : 'article'}\r\n tabindex=${ifDefined(this.clickable ? '0' : undefined)}\r\n @keydown=${this.clickable ? this.handleKeydown : undefined}\r\n >\r\n ${this.hasHeader\r\n ? html`<div class=\"card-header\" part=\"header\">\r\n <slot\r\n name=\"header\"\r\n @slotchange=${this.handleHeaderSlotChange}\r\n ></slot>\r\n </div>`\r\n : html`<slot\r\n name=\"header\"\r\n @slotchange=${this.handleHeaderSlotChange}\r\n ></slot>`}\r\n <div\r\n class=\"card-content ${this.direction === 'horizontal'\r\n ? 'card-content--horizontal'\r\n : ''}\"\r\n part=\"content\"\r\n >\r\n <slot name=\"media\" part=\"media\"></slot>\r\n <div\r\n class=\"card-body ${this.noPadding ? 'card-body--no-padding' : ''}\"\r\n part=\"body\"\r\n >\r\n <slot></slot>\r\n </div>\r\n </div>\r\n ${this.hasFooter\r\n ? html`<div class=\"card-footer\" part=\"footer\">\r\n <slot\r\n name=\"footer\"\r\n @slotchange=${this.handleFooterSlotChange}\r\n ></slot>\r\n </div>`\r\n : html`<slot\r\n name=\"footer\"\r\n @slotchange=${this.handleFooterSlotChange}\r\n ></slot>`}\r\n </div>\r\n `;\r\n }\r\n\r\n private handleKeydown(event: Event) {\r\n const keyboardEvent = event as typeof window.KeyboardEvent.prototype;\r\n if (keyboardEvent.key === 'Enter' || keyboardEvent.key === ' ') {\r\n event.preventDefault();\r\n this.handleClick(event as unknown as MouseEvent);\r\n }\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'bp-card': BpCard;\r\n }\r\n}\r\n"],"names":["cardStyles","css","BpCard","LitElement","event","slot","html","ifDefined","keyboardEvent","__decorateClass","property","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"card.js","sources":["../../source/components/card/card.style.ts","../../source/components/card/card.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const cardStyles = css`\n /* Base styles */\n :host {\n display: block;\n }\n\n .card {\n font-family: var(--bp-font-family);\n background-color: var(--bp-color-surface-elevated);\n border-radius: var(--bp-border-radius-lg);\n overflow: hidden;\n transition:\n box-shadow var(--bp-transition-fast),\n transform var(--bp-transition-base),\n border-color var(--bp-transition-fast);\n }\n\n /* Content layout (media + body wrapper) */\n .card-content {\n display: flex;\n flex-direction: column;\n }\n\n .card-content--horizontal {\n flex-direction: row;\n }\n\n .card-content--horizontal ::slotted([slot='media']) {\n width: auto;\n max-width: 50%;\n flex-shrink: 0;\n }\n\n .card-body {\n padding: var(--bp-spacing-lg);\n font-size: var(--bp-font-size-base);\n line-height: var(--bp-line-height-relaxed);\n color: var(--bp-color-text);\n flex: 1;\n min-width: 0;\n }\n\n .card-body--no-padding {\n padding: 0;\n }\n\n /* Header and footer container styles */\n .card-header {\n padding: var(--bp-spacing-lg);\n border-bottom: var(--bp-border-width) solid var(--bp-color-border);\n font-weight: var(--bp-font-weight-semibold);\n font-size: var(--bp-font-size-lg);\n line-height: 1.4;\n color: var(--bp-color-text-strong);\n }\n\n .card-footer {\n padding: var(--bp-spacing-lg);\n border-top: var(--bp-border-width) solid var(--bp-color-border);\n font-size: var(--bp-font-size-sm);\n color: var(--bp-color-text-muted);\n }\n\n /* Media slot styles */\n ::slotted([slot='media']) {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n }\n\n /* Variants */\n .card--default {\n border: var(--bp-border-width) solid var(--bp-color-border);\n box-shadow: var(--bp-shadow-sm);\n }\n\n .card--outlined {\n border: var(--bp-border-width) solid var(--bp-color-border-strong);\n box-shadow: none;\n }\n\n .card--elevated {\n border: none;\n box-shadow: var(--bp-shadow-lg);\n }\n\n /* States */\n .card--default.card--hoverable:hover,\n .card--default.card--clickable:hover {\n box-shadow: var(--bp-shadow-md);\n border-color: var(--bp-color-border-strong);\n }\n\n .card--outlined.card--hoverable:hover,\n .card--outlined.card--clickable:hover {\n box-shadow: var(--bp-shadow-md);\n }\n\n .card--elevated.card--hoverable:hover,\n .card--elevated.card--clickable:hover {\n box-shadow: var(--bp-shadow-xl);\n }\n\n .card--clickable {\n cursor: pointer;\n user-select: none;\n }\n\n .card--clickable:focus-visible {\n outline: var(--bp-focus-ring);\n outline-offset: var(--bp-focus-offset);\n }\n\n .card--clickable:active {\n box-shadow: var(--bp-shadow-sm);\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { cardStyles } from './card.style.js';\n\nexport type CardVariant = 'default' | 'outlined' | 'elevated';\nexport type CardDirection = 'vertical' | 'horizontal';\n/**\n * A versatile card component for organizing and displaying content.\n *\n * @slot - Default slot for card body content\n * @slot header - Optional header section\n * @slot footer - Optional footer section\n * @slot media - Optional media section (images, illustrations, etc.)\n *\n * @fires bp-click - Fired when clickable card is clicked\n */\n@customElement('bp-card')\nexport class BpCard extends LitElement {\n /**\n * Visual variant of the card\n */\n @property({ type: String, reflect: true }) declare variant: CardVariant;\n\n /**\n * Whether the card should display a hover effect\n */\n @property({ type: Boolean, reflect: true }) declare hoverable: boolean;\n\n /**\n * Whether the card is clickable (shows pointer cursor and emits click events)\n */\n @property({ type: Boolean, reflect: true }) declare clickable: boolean;\n\n /**\n * Whether to remove default padding from the card body\n */\n @property({ type: Boolean, reflect: true }) declare noPadding: boolean;\n\n /**\n * Layout direction for the card content (media + body area).\n * 'vertical' stacks media above body, 'horizontal' places them side by side.\n * Header and footer are unaffected and remain full-width.\n */\n @property({ type: String, reflect: true }) declare direction: CardDirection;\n\n /** Whether the header slot has assigned content */\n @property({ type: Boolean, attribute: false })\n private hasHeader = false;\n\n /** Whether the footer slot has assigned content */\n @property({ type: Boolean, attribute: false })\n private hasFooter = false;\n\n static styles = [cardStyles];\n\n constructor() {\n super();\n this.variant = 'default';\n this.hoverable = false;\n this.clickable = false;\n this.noPadding = false;\n this.direction = 'vertical';\n }\n\n /**\n * Handles slot change events for the header slot.\n * Updates hasHeader state to control header visibility.\n */\n private handleHeaderSlotChange = (event: Event): void => {\n const slot = event.target as HTMLElement & {\n assignedNodes: (options?: { flatten?: boolean }) => Node[];\n };\n this.hasHeader = slot.assignedNodes({ flatten: true }).length > 0;\n };\n\n /**\n * Handles slot change events for the footer slot.\n * Updates hasFooter state to control footer visibility.\n */\n private handleFooterSlotChange = (event: Event): void => {\n const slot = event.target as HTMLElement & {\n assignedNodes: (options?: { flatten?: boolean }) => Node[];\n };\n this.hasFooter = slot.assignedNodes({ flatten: true }).length > 0;\n };\n\n private handleClick(event: MouseEvent) {\n if (!this.clickable) return;\n\n // Only prevent default if not clicking on interactive elements\n const target = event.target as HTMLElement;\n if (!target.closest('a, button, input, select, textarea')) {\n event.preventDefault();\n }\n\n this.dispatchEvent(\n new CustomEvent('bp-click', {\n detail: { originalEvent: event },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n render() {\n return html`\n <div\n class=\"card card--${this.variant} ${this.hoverable || this.clickable\n ? 'card--hoverable'\n : ''} ${this.clickable ? 'card--clickable' : ''}\"\n part=\"card\"\n @click=${this.handleClick}\n role=${this.clickable ? 'button' : 'article'}\n tabindex=${ifDefined(this.clickable ? '0' : undefined)}\n @keydown=${this.clickable ? this.handleKeydown : undefined}\n >\n ${this.hasHeader\n ? html`<div class=\"card-header\" part=\"header\">\n <slot\n name=\"header\"\n @slotchange=${this.handleHeaderSlotChange}\n ></slot>\n </div>`\n : html`<slot\n name=\"header\"\n @slotchange=${this.handleHeaderSlotChange}\n ></slot>`}\n <div\n class=\"card-content ${this.direction === 'horizontal'\n ? 'card-content--horizontal'\n : ''}\"\n part=\"content\"\n >\n <slot name=\"media\" part=\"media\"></slot>\n <div\n class=\"card-body ${this.noPadding ? 'card-body--no-padding' : ''}\"\n part=\"body\"\n >\n <slot></slot>\n </div>\n </div>\n ${this.hasFooter\n ? html`<div class=\"card-footer\" part=\"footer\">\n <slot\n name=\"footer\"\n @slotchange=${this.handleFooterSlotChange}\n ></slot>\n </div>`\n : html`<slot\n name=\"footer\"\n @slotchange=${this.handleFooterSlotChange}\n ></slot>`}\n </div>\n `;\n }\n\n private handleKeydown(event: Event) {\n const keyboardEvent = event as typeof window.KeyboardEvent.prototype;\n if (keyboardEvent.key === 'Enter' || keyboardEvent.key === ' ') {\n event.preventDefault();\n this.handleClick(event as unknown as MouseEvent);\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-card': BpCard;\n }\n}\n"],"names":["cardStyles","css","BpCard","LitElement","event","slot","html","ifDefined","keyboardEvent","__decorateClass","property","customElement"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","sources":["../../source/components/checkbox/checkbox.style.ts","../../source/components/checkbox/checkbox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const checkboxStyles = css`\n /* Base styles */\n :host {\n display: inline-block;\n }\n\n .checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--bp-spacing-sm);\n cursor: pointer;\n font-family: var(--bp-font-family);\n font-size: var(--bp-font-size-base);\n color: var(--bp-color-text);\n user-select: none;\n }\n\n .checkbox__input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n margin: 0;\n padding: 0;\n }\n\n .checkbox__checkmark {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: var(--bp-border-width) solid var(--bp-color-border-strong);\n border-radius: var(--bp-border-radius-sm);\n background-color: var(--bp-color-surface);\n transition: all var(--bp-transition-fast);\n }\n\n .checkbox__checkmark svg {\n width: 100%;\n height: 100%;\n color: var(--bp-color-text-inverse);\n opacity: 0;\n transform: scale(0);\n transition:\n opacity var(--bp-duration-fast) var(--bp-ease-out),\n transform var(--bp-duration-fast) var(--bp-ease-bounce);\n }\n\n .checkbox__label {\n line-height: var(--bp-line-height-normal);\n }\n\n /* Sizes */\n .checkbox--sm .checkbox__checkmark {\n width: var(--bp-spacing-4);\n height: var(--bp-spacing-4);\n }\n\n .checkbox--sm .checkbox__label {\n font-size: var(--bp-font-size-sm);\n }\n\n .checkbox--md .checkbox__checkmark {\n width: var(--bp-spacing-5);\n height: var(--bp-spacing-5);\n }\n\n .checkbox--md .checkbox__label {\n font-size: var(--bp-font-size-base);\n }\n\n .checkbox--lg .checkbox__checkmark {\n width: var(--bp-spacing-6);\n height: var(--bp-spacing-6);\n }\n\n .checkbox--lg .checkbox__label {\n font-size: var(--bp-font-size-lg);\n }\n\n /* States - Checked */\n .checkbox--checked .checkbox__checkmark {\n background-color: var(--bp-color-primary);\n border-color: var(--bp-color-primary);\n }\n\n .checkbox--checked .checkbox__checkmark svg {\n opacity: 1;\n transform: scale(1);\n }\n\n /* States - Indeterminate */\n .checkbox--indeterminate .checkbox__checkmark {\n background-color: var(--bp-color-primary);\n border-color: var(--bp-color-primary);\n }\n\n .checkbox--indeterminate .checkbox__checkmark svg {\n opacity: 1;\n transform: scale(1);\n }\n\n /* States - Hover */\n .checkbox:hover:not(.checkbox--disabled):not(.checkbox--checked):not(\n .checkbox--indeterminate\n )\n .checkbox__checkmark {\n border-color: var(--bp-color-primary);\n background-color: color-mix(\n in srgb,\n var(--bp-color-primary) 8%,\n transparent\n );\n }\n\n .checkbox--checked:hover:not(.checkbox--disabled) .checkbox__checkmark,\n .checkbox--indeterminate:hover:not(.checkbox--disabled) .checkbox__checkmark {\n background-color: var(--bp-color-primary-hover);\n border-color: var(--bp-color-primary-hover);\n }\n\n /* States - Active */\n .checkbox:active:not(.checkbox--disabled) .checkbox__checkmark {\n transform: scale(0.95);\n }\n\n /* States - Focused */\n .checkbox--focused .checkbox__checkmark {\n outline: var(--bp-focus-width) solid var(--bp-color-focus);\n outline-offset: var(--bp-focus-offset);\n }\n\n /* States - Disabled */\n .checkbox--disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n /* States - Error */\n .checkbox--error .checkbox__checkmark {\n border-color: var(--bp-color-error);\n }\n\n .checkbox--error.checkbox--checked .checkbox__checkmark,\n .checkbox--error.checkbox--indeterminate .checkbox__checkmark {\n background-color: var(--bp-color-error);\n border-color: var(--bp-color-error);\n }\n\n /* Touch target size: ensure 44x44px minimum on touch devices */\n @media (pointer: coarse) {\n .checkbox {\n min-height: 44px;\n padding: var(--bp-spacing-xs) 0;\n }\n\n .checkbox__checkmark {\n position: relative;\n }\n\n /* Expand touch target with pseudo-element */\n .checkbox__checkmark::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 44px;\n height: 44px;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { checkboxStyles } from './checkbox.style.js';\n\nexport type CheckboxSize = 'sm' | 'md' | 'lg';\n\n/**\n * A form checkbox input with label support and multiple states.\n *\n * @element bp-checkbox\n *\n * @property {boolean} checked - Whether the checkbox is checked\n * @property {boolean} indeterminate - Indeterminate state (partial selection)\n * @property {boolean} disabled - Whether the checkbox is disabled\n * @property {boolean} required - Whether the checkbox is required\n * @property {string} name - The name for form submission\n * @property {string} value - The value for form submission\n * @property {CheckboxSize} size - The size of the checkbox\n * @property {boolean} error - Whether the checkbox has an error state\n *\n * @slot - The checkbox label text\n *\n * @fires bp-change - Fired when the checked state changes\n * @fires bp-focus - Fired when the checkbox receives focus\n * @fires bp-blur - Fired when the checkbox loses focus\n *\n * @csspart checkbox - The checkbox container\n * @csspart input - The native checkbox input element\n * @csspart checkmark - The visual checkmark indicator\n * @csspart label - The label text container\n */\n@customElement('bp-checkbox')\nexport class BpCheckbox extends LitElement {\n @query('input[type=\"checkbox\"]') declare input: HTMLInputElement;\n\n /**\n * Whether the checkbox is checked.\n */\n @property({ type: Boolean, reflect: true }) declare checked: boolean;\n\n /**\n * Whether the checkbox is in an indeterminate state.\n * This is a visual-only state for \"partially checked\" appearance.\n */\n @property({ type: Boolean, reflect: true }) declare indeterminate: boolean;\n\n /**\n * Whether the checkbox is disabled.\n */\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\n\n /**\n * Whether the checkbox is required.\n */\n @property({ type: Boolean, reflect: true }) declare required: boolean;\n\n /**\n * The name of the checkbox for form submission.\n */\n @property({ type: String, reflect: true }) declare name: string;\n\n /**\n * The value of the checkbox for form submission.\n */\n @property({ type: String }) declare value: string;\n\n /**\n * The size of the checkbox.\n */\n @property({ type: String, reflect: true }) declare size: CheckboxSize;\n\n /**\n * Whether the checkbox has an error state.\n */\n @property({ type: Boolean, reflect: true }) declare error: boolean;\n\n @state() private hasFocus = false;\n\n static styles = [checkboxStyles];\n\n static formAssociated = true;\n // eslint-disable-next-line no-undef\n private internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this.checked = false;\n this.indeterminate = false;\n this.disabled = false;\n this.required = false;\n this.name = '';\n this.value = 'on';\n this.size = 'md';\n this.error = false;\n\n // attachInternals may not be available in all environments (e.g., test)\n if (typeof this.attachInternals === 'function') {\n this.internals = this.attachInternals();\n }\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.updateFormValue();\n }\n\n updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has('checked')) {\n this.updateFormValue();\n if (this.input) {\n this.input.checked = this.checked;\n }\n }\n\n if (changedProperties.has('indeterminate') && this.input) {\n this.input.indeterminate = this.indeterminate;\n }\n }\n\n private updateFormValue() {\n const value = this.checked ? this.value : null;\n this.internals?.setFormValue(value);\n }\n\n private handleChange(event: Event) {\n const target = event.target as HTMLInputElement;\n this.checked = target.checked;\n this.indeterminate = false;\n\n this.dispatchEvent(\n new CustomEvent('bp-change', {\n detail: { checked: this.checked },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new CustomEvent('bp-focus', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new CustomEvent('bp-blur', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /**\n * Sets focus on the checkbox.\n */\n // eslint-disable-next-line no-undef\n focus(options?: FocusOptions) {\n this.input?.focus(options);\n }\n\n /**\n * Removes focus from the checkbox.\n */\n blur() {\n this.input?.blur();\n }\n\n render() {\n const classes = [\n 'checkbox',\n `checkbox--${this.size}`,\n this.checked ? 'checkbox--checked' : '',\n this.indeterminate ? 'checkbox--indeterminate' : '',\n this.disabled ? 'checkbox--disabled' : '',\n this.error ? 'checkbox--error' : '',\n this.hasFocus ? 'checkbox--focused' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return html`\n <label part=\"checkbox\" class=\"${classes}\">\n <input\n part=\"input\"\n type=\"checkbox\"\n class=\"checkbox__input\"\n .checked=${live(this.checked)}\n .indeterminate=${live(this.indeterminate)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n value=${this.value}\n aria-checked=${this.indeterminate ? 'mixed' : this.checked}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n />\n <span part=\"checkmark\" class=\"checkbox__checkmark\">\n ${this.indeterminate\n ? html`<svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>`\n : html`<svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13 4L6 11L3 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>`}\n </span>\n <span part=\"label\" class=\"checkbox__label\">\n <slot></slot>\n </span>\n </label>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-checkbox': BpCheckbox;\n }\n}\n"],"names":["checkboxStyles","css","BpCheckbox","LitElement","changedProperties","value","event","target","options","classes","html","live","ifDefined","__decorateClass","query","property","state","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checkbox.js","sources":["../../source/components/checkbox/checkbox.style.ts","../../source/components/checkbox/checkbox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const checkboxStyles = css`\n /* Base styles */\n :host {\n display: inline-block;\n }\n\n .checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--bp-spacing-sm);\n cursor: pointer;\n font-family: var(--bp-font-family);\n font-size: var(--bp-font-size-base);\n color: var(--bp-color-text);\n user-select: none;\n }\n\n .checkbox__input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n margin: 0;\n padding: 0;\n }\n\n .checkbox__checkmark {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border: var(--bp-border-width) solid var(--bp-color-border-strong);\n border-radius: var(--bp-border-radius-sm);\n background-color: var(--bp-color-surface);\n transition: all var(--bp-transition-fast);\n }\n\n .checkbox__checkmark svg {\n width: 100%;\n height: 100%;\n color: var(--bp-color-text-inverse);\n opacity: 0;\n transform: scale(0);\n transition:\n opacity var(--bp-duration-fast) var(--bp-ease-out),\n transform var(--bp-duration-fast) var(--bp-ease-bounce);\n }\n\n .checkbox__label {\n line-height: var(--bp-line-height-normal);\n }\n\n /* Sizes */\n .checkbox--sm .checkbox__checkmark {\n width: var(--bp-spacing-4);\n height: var(--bp-spacing-4);\n }\n\n .checkbox--sm .checkbox__label {\n font-size: var(--bp-font-size-sm);\n }\n\n .checkbox--md .checkbox__checkmark {\n width: var(--bp-spacing-5);\n height: var(--bp-spacing-5);\n }\n\n .checkbox--md .checkbox__label {\n font-size: var(--bp-font-size-base);\n }\n\n .checkbox--lg .checkbox__checkmark {\n width: var(--bp-spacing-6);\n height: var(--bp-spacing-6);\n }\n\n .checkbox--lg .checkbox__label {\n font-size: var(--bp-font-size-lg);\n }\n\n /* States - Checked */\n .checkbox--checked .checkbox__checkmark {\n background-color: var(--bp-color-primary);\n border-color: var(--bp-color-primary);\n }\n\n .checkbox--checked .checkbox__checkmark svg {\n opacity: 1;\n transform: scale(1);\n }\n\n /* States - Indeterminate */\n .checkbox--indeterminate .checkbox__checkmark {\n background-color: var(--bp-color-primary);\n border-color: var(--bp-color-primary);\n }\n\n .checkbox--indeterminate .checkbox__checkmark svg {\n opacity: 1;\n transform: scale(1);\n }\n\n /* States - Hover */\n .checkbox:hover:not(.checkbox--disabled):not(.checkbox--checked):not(\n .checkbox--indeterminate\n )\n .checkbox__checkmark {\n border-color: var(--bp-color-primary);\n background-color: color-mix(\n in srgb,\n var(--bp-color-primary) 8%,\n transparent\n );\n }\n\n .checkbox--checked:hover:not(.checkbox--disabled) .checkbox__checkmark,\n .checkbox--indeterminate:hover:not(.checkbox--disabled) .checkbox__checkmark {\n background-color: var(--bp-color-primary-hover);\n border-color: var(--bp-color-primary-hover);\n }\n\n /* States - Active */\n .checkbox:active:not(.checkbox--disabled) .checkbox__checkmark {\n transform: scale(0.95);\n }\n\n /* States - Focused */\n .checkbox--focused .checkbox__checkmark {\n outline: var(--bp-focus-width) solid var(--bp-color-focus);\n outline-offset: var(--bp-focus-offset);\n }\n\n /* States - Disabled */\n .checkbox--disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n /* States - Error */\n .checkbox--error .checkbox__checkmark {\n border-color: var(--bp-color-error);\n }\n\n .checkbox--error.checkbox--checked .checkbox__checkmark,\n .checkbox--error.checkbox--indeterminate .checkbox__checkmark {\n background-color: var(--bp-color-error);\n border-color: var(--bp-color-error);\n }\n\n /* Touch target size: ensure 44x44px minimum on touch devices */\n @media (pointer: coarse) {\n .checkbox {\n min-height: 44px;\n padding: var(--bp-spacing-xs) 0;\n }\n\n .checkbox__checkmark {\n position: relative;\n }\n\n /* Expand touch target with pseudo-element */\n .checkbox__checkmark::before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 44px;\n height: 44px;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { live } from 'lit/directives/live.js';\nimport { checkboxStyles } from './checkbox.style.js';\n\nexport type CheckboxSize = 'sm' | 'md' | 'lg';\n\n/**\n * A form checkbox input with label support and multiple states.\n *\n * @element bp-checkbox\n *\n * @property {boolean} checked - Whether the checkbox is checked\n * @property {boolean} indeterminate - Indeterminate state (partial selection)\n * @property {boolean} disabled - Whether the checkbox is disabled\n * @property {boolean} required - Whether the checkbox is required\n * @property {string} name - The name for form submission\n * @property {string} value - The value for form submission\n * @property {CheckboxSize} size - The size of the checkbox\n * @property {boolean} error - Whether the checkbox has an error state\n *\n * @slot - The checkbox label text\n *\n * @fires bp-change - Fired when the checked state changes\n * @fires bp-focus - Fired when the checkbox receives focus\n * @fires bp-blur - Fired when the checkbox loses focus\n *\n * @csspart checkbox - The checkbox container\n * @csspart input - The native checkbox input element\n * @csspart checkmark - The visual checkmark indicator\n * @csspart label - The label text container\n */\n@customElement('bp-checkbox')\nexport class BpCheckbox extends LitElement {\n @query('input[type=\"checkbox\"]') declare input: HTMLInputElement;\n\n /**\n * Whether the checkbox is checked.\n */\n @property({ type: Boolean, reflect: true }) declare checked: boolean;\n\n /**\n * Whether the checkbox is in an indeterminate state.\n * This is a visual-only state for \"partially checked\" appearance.\n */\n @property({ type: Boolean, reflect: true }) declare indeterminate: boolean;\n\n /**\n * Whether the checkbox is disabled.\n */\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\n\n /**\n * Whether the checkbox is required.\n */\n @property({ type: Boolean, reflect: true }) declare required: boolean;\n\n /**\n * The name of the checkbox for form submission.\n */\n @property({ type: String, reflect: true }) declare name: string;\n\n /**\n * The value of the checkbox for form submission.\n */\n @property({ type: String }) declare value: string;\n\n /**\n * The size of the checkbox.\n */\n @property({ type: String, reflect: true }) declare size: CheckboxSize;\n\n /**\n * Whether the checkbox has an error state.\n */\n @property({ type: Boolean, reflect: true }) declare error: boolean;\n\n @state() private hasFocus = false;\n\n static styles = [checkboxStyles];\n\n static formAssociated = true;\n\n private internals: ElementInternals | null = null;\n\n constructor() {\n super();\n this.checked = false;\n this.indeterminate = false;\n this.disabled = false;\n this.required = false;\n this.name = '';\n this.value = 'on';\n this.size = 'md';\n this.error = false;\n\n // attachInternals may not be available in all environments (e.g., test)\n if (typeof this.attachInternals === 'function') {\n this.internals = this.attachInternals();\n }\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.updateFormValue();\n }\n\n updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has('checked')) {\n this.updateFormValue();\n if (this.input) {\n this.input.checked = this.checked;\n }\n }\n\n if (changedProperties.has('indeterminate') && this.input) {\n this.input.indeterminate = this.indeterminate;\n }\n }\n\n private updateFormValue() {\n const value = this.checked ? this.value : null;\n this.internals?.setFormValue(value);\n }\n\n private handleChange(event: Event) {\n const target = event.target as HTMLInputElement;\n this.checked = target.checked;\n this.indeterminate = false;\n\n this.dispatchEvent(\n new CustomEvent('bp-change', {\n detail: { checked: this.checked },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleFocus() {\n this.hasFocus = true;\n this.dispatchEvent(\n new CustomEvent('bp-focus', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private handleBlur() {\n this.hasFocus = false;\n this.dispatchEvent(\n new CustomEvent('bp-blur', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /**\n * Sets focus on the checkbox.\n */\n\n focus(options?: FocusOptions) {\n this.input?.focus(options);\n }\n\n /**\n * Removes focus from the checkbox.\n */\n blur() {\n this.input?.blur();\n }\n\n render() {\n const classes = [\n 'checkbox',\n `checkbox--${this.size}`,\n this.checked ? 'checkbox--checked' : '',\n this.indeterminate ? 'checkbox--indeterminate' : '',\n this.disabled ? 'checkbox--disabled' : '',\n this.error ? 'checkbox--error' : '',\n this.hasFocus ? 'checkbox--focused' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return html`\n <label part=\"checkbox\" class=\"${classes}\">\n <input\n part=\"input\"\n type=\"checkbox\"\n class=\"checkbox__input\"\n .checked=${live(this.checked)}\n .indeterminate=${live(this.indeterminate)}\n ?disabled=${this.disabled}\n ?required=${this.required}\n name=${ifDefined(this.name || undefined)}\n value=${this.value}\n aria-checked=${this.indeterminate ? 'mixed' : this.checked}\n @change=${this.handleChange}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n />\n <span part=\"checkmark\" class=\"checkbox__checkmark\">\n ${this.indeterminate\n ? html`<svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>`\n : html`<svg\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13 4L6 11L3 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>`}\n </span>\n <span part=\"label\" class=\"checkbox__label\">\n <slot></slot>\n </span>\n </label>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-checkbox': BpCheckbox;\n }\n}\n"],"names":["checkboxStyles","css","BpCheckbox","LitElement","changedProperties","value","event","target","options","classes","html","live","ifDefined","__decorateClass","query","property","state","customElement"],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { LitElement, type PropertyValues } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* Result returned by a highlight adapter.
|
|
4
|
+
*/
|
|
5
|
+
export interface HighlightResult {
|
|
6
|
+
/** The highlighted code as an HTML string. */
|
|
7
|
+
html: string;
|
|
8
|
+
/** Whether highlighting was actually applied (false = plain text fallback). */
|
|
9
|
+
isHighlighted: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Adapter interface for pluggable syntax highlighting.
|
|
13
|
+
*/
|
|
14
|
+
export interface CodeBlockHighlightAdapter {
|
|
15
|
+
/**
|
|
16
|
+
* Called once when the adapter is first used.
|
|
17
|
+
* Use this for async initialization (loading Shiki, registering languages, etc).
|
|
18
|
+
* Return value is passed to `highlight()` as context.
|
|
19
|
+
*/
|
|
20
|
+
initialize?(): Promise<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Return highlighted HTML for the given code and language.
|
|
23
|
+
* `context` is the resolved value from `initialize()`.
|
|
24
|
+
*/
|
|
25
|
+
highlight(options: {
|
|
26
|
+
code: string;
|
|
27
|
+
language: string;
|
|
28
|
+
context: unknown;
|
|
29
|
+
}): HighlightResult;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Built-in plain text adapter that escapes HTML and renders monospace text.
|
|
33
|
+
* Zero dependencies, zero bundle cost.
|
|
34
|
+
*/
|
|
35
|
+
export declare const plainTextAdapter: CodeBlockHighlightAdapter;
|
|
36
|
+
/**
|
|
37
|
+
* A code block component for displaying syntax-highlighted code with
|
|
38
|
+
* copy-to-clipboard, line numbers, line highlighting, and expand/collapse.
|
|
39
|
+
*
|
|
40
|
+
* @slot title - Custom title content. Overrides the `title` attribute.
|
|
41
|
+
* @slot controls - Additional control buttons placed before the copy button.
|
|
42
|
+
* @slot copy-icon - Custom icon for the copy button (default state).
|
|
43
|
+
* @slot copied-icon - Custom icon for the copy button (success state).
|
|
44
|
+
*
|
|
45
|
+
* @fires bp-copy - Fired after a copy attempt. Detail: `{ code: string, success: boolean }`
|
|
46
|
+
*
|
|
47
|
+
* @csspart base - Outer wrapper
|
|
48
|
+
* @csspart header - Header bar
|
|
49
|
+
* @csspart title - Title text area
|
|
50
|
+
* @csspart controls - Controls container
|
|
51
|
+
* @csspart copy-button - The copy button
|
|
52
|
+
* @csspart body - Scrollable code container
|
|
53
|
+
* @csspart pre - The `<pre>` element
|
|
54
|
+
* @csspart code - The `<code>` element
|
|
55
|
+
* @csspart line-number - Individual line number cell
|
|
56
|
+
* @csspart line - Individual line of code
|
|
57
|
+
*/
|
|
58
|
+
export declare class BpCodeBlock extends LitElement {
|
|
59
|
+
/**
|
|
60
|
+
* The source code to display.
|
|
61
|
+
*/
|
|
62
|
+
code: string;
|
|
63
|
+
/**
|
|
64
|
+
* Language identifier for syntax highlighting (e.g. 'typescript', 'html', 'python').
|
|
65
|
+
* Also displayed as a label when no title is set.
|
|
66
|
+
*/
|
|
67
|
+
language: string;
|
|
68
|
+
/**
|
|
69
|
+
* Optional title displayed in the header (e.g. a filename like `index.ts`).
|
|
70
|
+
* Overrides the language label.
|
|
71
|
+
*/
|
|
72
|
+
title: string;
|
|
73
|
+
/**
|
|
74
|
+
* Show line number gutter.
|
|
75
|
+
*/
|
|
76
|
+
showLineNumbers: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Array of 1-based line numbers to visually highlight.
|
|
79
|
+
*/
|
|
80
|
+
highlightLines: number[];
|
|
81
|
+
/**
|
|
82
|
+
* Wrap long lines instead of horizontal scroll.
|
|
83
|
+
*/
|
|
84
|
+
wrapLines: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Show the copy-to-clipboard button.
|
|
87
|
+
*/
|
|
88
|
+
showCopyButton: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* When set, collapse the code block to this many visible lines with a "Show more" toggle.
|
|
91
|
+
*/
|
|
92
|
+
maxLines: number | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Show/hide the header bar. When false, the copy button floats over the code.
|
|
95
|
+
*/
|
|
96
|
+
showHeader: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* The syntax highlight adapter to use for this instance.
|
|
99
|
+
* Defaults to `BpCodeBlock.defaultAdapter` which is the plainTextAdapter.
|
|
100
|
+
*/
|
|
101
|
+
highlightAdapter: CodeBlockHighlightAdapter;
|
|
102
|
+
/**
|
|
103
|
+
* Global default adapter used when no per-instance adapter is set.
|
|
104
|
+
*/
|
|
105
|
+
static defaultAdapter: CodeBlockHighlightAdapter;
|
|
106
|
+
private _copyState;
|
|
107
|
+
private _expanded;
|
|
108
|
+
private _highlightedHtml;
|
|
109
|
+
private _adapterContext;
|
|
110
|
+
private _adapterInitialized;
|
|
111
|
+
private _lineCount;
|
|
112
|
+
private _highlightSet;
|
|
113
|
+
private _highlightedLines;
|
|
114
|
+
private _copyResetTimer;
|
|
115
|
+
static styles: import("lit").CSSResult[];
|
|
116
|
+
constructor();
|
|
117
|
+
disconnectedCallback(): void;
|
|
118
|
+
protected willUpdate(changedProperties: PropertyValues): void;
|
|
119
|
+
connectedCallback(): void;
|
|
120
|
+
private _initializeAdapter;
|
|
121
|
+
private _updateHighlightingSync;
|
|
122
|
+
private _handleCopy;
|
|
123
|
+
private _fallbackCopy;
|
|
124
|
+
private _toggleExpanded;
|
|
125
|
+
private get _shouldCollapse();
|
|
126
|
+
private get _isCollapsed();
|
|
127
|
+
private get _headerLabel();
|
|
128
|
+
private _getCopyAriaLabel;
|
|
129
|
+
private _renderCopyIcon;
|
|
130
|
+
private _renderCopyButton;
|
|
131
|
+
private _renderHeader;
|
|
132
|
+
private _renderFloatingCopyButton;
|
|
133
|
+
private _renderLine;
|
|
134
|
+
private _renderCodeLines;
|
|
135
|
+
private _renderExpandButton;
|
|
136
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
137
|
+
}
|
|
138
|
+
declare global {
|
|
139
|
+
interface HTMLElementTagNameMap {
|
|
140
|
+
'bp-code-block': BpCodeBlock;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=code-block.d.ts.map
|