diff --git a/commitlint.config.cjs b/commitlint.config.cjs index f4119dfc..5fed8d4e 100644 --- a/commitlint.config.cjs +++ b/commitlint.config.cjs @@ -1,35 +1,36 @@ module.exports = { - extends: ['@commitlint/config-conventional'], + extends: ["@commitlint/config-conventional"], rules: { - 'scope-enum': [ + "scope-enum": [ 2, - 'always', + "always", [ - 'storybook', - 'design', - 'react', - 'deps', - 'deps-dev', + "storybook", + "design", + "react", + "deps", + "deps-dev", // Components as scopes listed below - 'button', - 'icon', - 'input', - 'badge', - 'tab', - 'tooltip', - 'progress-indicator', - 'checkbox-group', - 'checkbox', - 'alert', - 'select', - 'pagination', - 'radio', - 'dialog', - 'drawer', - 'dropdown', - 'switch', - 'textarea', - 'popover', + "button", + "icon", + "input", + "badge", + "tab", + "tooltip", + "progress-indicator", + "checkbox-group", + "checkbox", + "alert", + "select", + "pagination", + "radio", + "dialog", + "drawer", + "dropdown", + "switch", + "textarea", + "popover", + "notification", ], ], }, diff --git a/src/baklava.ts b/src/baklava.ts index f6f7c0a2..43ab0fd7 100644 --- a/src/baklava.ts +++ b/src/baklava.ts @@ -23,4 +23,6 @@ export { default as BlDropdown } from "./components/dropdown/bl-dropdown"; export { default as BlDropdownItem } from "./components/dropdown/item/bl-dropdown-item"; export { default as BlDropdownGroup } from "./components/dropdown/group/bl-dropdown-group"; export { default as BlSwitch } from "./components/switch/bl-switch"; +export { default as BlNotification } from "./components/notification/bl-notification"; +export { default as BlNotificationCard } from "./components/notification/card/bl-notification-card"; export { getIconPath, setIconPath } from "./utilities/asset-paths"; diff --git a/src/components/alert/bl-alert.test.ts b/src/components/alert/bl-alert.test.ts index 064bf2fd..bf7f2299 100644 --- a/src/components/alert/bl-alert.test.ts +++ b/src/components/alert/bl-alert.test.ts @@ -147,12 +147,25 @@ describe("Slot", () => { const el = await fixture( html` Action Slot + Should not render this element Action Slot ` ); - const actionSlot = el.shadowRoot?.querySelector('slot[name="action"]'); - expect(actionSlot).to.exist; + const actionSlot = el.shadowRoot!.querySelector('slot[name="action"]') as HTMLSlotElement; + const [actionElement, actionSpanElement] = actionSlot.assignedElements(); + + expect(actionElement as HTMLElement).to.exist; + expect(actionElement.tagName).to.eq("BL-BUTTON"); + expect(actionSpanElement as HTMLElement).to.not.exist; + + const actionSecondarySlot = el.shadowRoot!.querySelector( + 'slot[name="action-secondary"]' + ) as HTMLSlotElement; + const actionSecondaryElement = actionSecondarySlot?.assignedElements()[0] as HTMLElement; + + expect(actionSecondaryElement).to.exist; + expect(actionSecondaryElement.tagName).to.eq("BL-BUTTON"); }); it("renders `action` slot empty when bl-button is not used", async () => { const el = await fixture( diff --git a/src/components/alert/bl-alert.ts b/src/components/alert/bl-alert.ts index c22b275d..207571e7 100644 --- a/src/components/alert/bl-alert.ts +++ b/src/components/alert/bl-alert.ts @@ -104,7 +104,7 @@ export default class BlAlert extends LitElement { private _initAlertActionSlot(event: Event) { const slotElement = event.target as HTMLSlotElement; - const slotElements = slotElement.assignedElements(); + const slotElements = slotElement.assignedElements({ flatten: true }); slotElements.forEach(element => { if (element.tagName !== "BL-BUTTON") { @@ -112,9 +112,9 @@ export default class BlAlert extends LitElement { return; } - (slotElement.parentElement as HTMLElement).style.display = "flex"; + (this.shadowRoot?.querySelector(".actions") as HTMLElement).style.display = "flex"; - const variant = element.slot === "action-secondary" ? "secondary" : "primary"; + const variant = slotElement.name === "action-secondary" ? "secondary" : "primary"; const buttonTypes: Record = { info: "default", warning: "neutral", diff --git a/src/components/dialog/bl-dialog.mdx b/src/components/dialog/bl-dialog.mdx index 2b25aad8..3709988b 100644 --- a/src/components/dialog/bl-dialog.mdx +++ b/src/components/dialog/bl-dialog.mdx @@ -94,6 +94,14 @@ document.querySelector("bl-dialog").addEventListener("bl-dialog-request-close", }); ``` +## Using HTML Dialog Element + +Starting from version 2.4.0 of Baklava, the `bl-dialog` component uses a polyfill implementation by default due to some quirks in the native HTML Dialog element. +This change was prompted by issues encountered during the development of the `bl-notification` component, where the native dialog element blocked any actions on it, event with Popover attribute. + +If you wish to use the native HTML Dialog element, you can do so by setting the `polyfilled` attribute to `false`. +Please note that this will cause notifications to render under the dialog backdrop. Prior to version 2.4.0, this was the default behavior. + ## Reference diff --git a/src/components/dialog/bl-dialog.test.ts b/src/components/dialog/bl-dialog.test.ts index 7f691084..7a0deaec 100644 --- a/src/components/dialog/bl-dialog.test.ts +++ b/src/components/dialog/bl-dialog.test.ts @@ -90,7 +90,7 @@ describe("bl-dialog", () => { window.HTMLDialogElement = htmlDialogElement; }); it("should render html dialog component with the default values when supports html dialog", async () => { - const el = await fixture(html``); + const el = await fixture(html``); assert.shadowDom.equal( el, @@ -132,7 +132,7 @@ describe("bl-dialog", () => { }); it("should close the dialog when the close btn is clicked", async () => { - const el = await fixture(html` + const el = await fixture(html`
My Content
`); const dialog = el.shadowRoot?.querySelector(".dialog") as HTMLDivElement; @@ -340,7 +340,7 @@ describe("bl-dialog", () => { }); it("should fire bl-dialog-request-close event when dialog closes by clicking backdrop", async () => { - const el = await fixture(html` + const el = await fixture(html` `); const dialog = el?.shadowRoot?.querySelector(".dialog"); diff --git a/src/components/dialog/bl-dialog.ts b/src/components/dialog/bl-dialog.ts index 2c76cc87..a7774259 100644 --- a/src/components/dialog/bl-dialog.ts +++ b/src/components/dialog/bl-dialog.ts @@ -48,9 +48,17 @@ export default class BlDialog extends LitElement { * using polyfill by setting this to true in some cases like to show some content on top of dialog * in case you are not able to use Popover API. Be aware that, polyfilled version can cause some * inconsistencies in terms of accessibility and stacking context. So use it with extra caution. + * + * As of the current implementation, you can render above the dialog HTML element using the Popover API. However, + * it will block any actions on the Popover element. This issue was encountered during the development of the `bl-notification` component. + * As a result, we decided to enable the polyfill for the `bl-dialog` component by default. If you prefer to use the native dialog, you can set + * this property to false. Please note, doing so will cause notifications to render under the dialog backdrop. + * For more information, refer to the comment linked below: + * + * https://github.com/Trendyol/baklava/issues/141#issuecomment-1810301413 */ @property({ type: Boolean, reflect: true }) - polyfilled = !window.HTMLDialogElement; + polyfilled = true; @query(".dialog") private dialog: HTMLDialogElement & DialogElement; @@ -176,7 +184,7 @@ export default class BlDialog extends LitElement { } render(): TemplateResult { - return this.polyfilled + return this.polyfilled || !window.HTMLDialogElement ? html`