diff --git a/.prettierrc.json b/.prettierrc.json index be05741f..5799269f 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -8,6 +8,7 @@ "trailingComma": "es5", "useTabs": false, "importOrder": [ + "^react", "^lit", "", "^[./]", diff --git a/README.md b/README.md index 484d415c..385fb176 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ Web implementation of the design system is created as native web components so i Preferred way of using Baklava is using it via CDN. Just import library JS and CSS files to your main document like below: ```html - - + + ``` This way library will be served from a very high performant CDN and all of the Baklava web components will be ready to use inside your web project. 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/docs/customizing-baklava-theme.stories.mdx b/docs/customizing-baklava-theme.stories.mdx index 88e77986..a2d38da4 100644 --- a/docs/customizing-baklava-theme.stories.mdx +++ b/docs/customizing-baklava-theme.stories.mdx @@ -19,7 +19,7 @@ instead of `themes/default.css` file. Like: ```html - + ``` With this opportunity you can use all of the Baklava components with your own branding colors, own selection of Font or different sizing values. @@ -29,9 +29,9 @@ With this opportunity you can use all of the Baklava components with your own br If you want to change a small set of the design tokens, you may consider to extend default theme. ```html - + - + ``` With this, you can -for example- only override color palette for your app and continue to use typography or spacing rules from the default theme. diff --git a/docs/design-system/colors.stories.mdx b/docs/design-system/colors.stories.mdx index 00e60daf..0ca26d40 100644 --- a/docs/design-system/colors.stories.mdx +++ b/docs/design-system/colors.stories.mdx @@ -28,6 +28,11 @@ Baklava uses a list of defined color with some default values. subtitle="Warning Color" colors={{ '': 'var(--bl-color-warning)', '--highlight': 'var(--bl-color-warning-highlight)', '--contrast': 'var(--bl-color-warning-contrast)' }} /> + Size: 32px / 2rem
Height: 36px (font size + `bl-size-3xs`) |

Heading 1 Regular

| +| `--bl-font-heading-1-medium` | Weight: 500 / Medium
Size: 32px / 2rem
Height: 36px (font size + `bl-size-3xs`) |

Heading 1 Medium

| +| `--bl-font-heading-1-semibold` | Weight: 600 / Semibold
Size: 32px / 2rem
Height: 36px (font size + `bl-size-3xs`) |

Heading 1 Semibold

| +| `--bl-font-heading-1-bold` | Weight: 700 / Bold
Size: 32px / 2rem
Height: 36px (font size + `bl-size-3xs`) |

Heading 1 Bold

| + +#### Heading 2 + +| Variable | Styles | Example | +|:---------|:-------|:-------:| +| `--bl-font-heading-2-regular`| Weight: 400 / Regular
Size: 28px / 1.75rem
Height: 32px (font size + `bl-size-3xs`) |

Heading 2 Regular

| +| `--bl-font-heading-2-medium` | Weight: 500 / Medium
Size: 28px / 1.75rem
Height: 32px (font size + `bl-size-3xs`) |

Heading 2 Medium

| +| `--bl-font-heading-2-semibold` | Weight: 600 / Semibold
Size: 28px / 1.75rem
Height: 32px (font size + `bl-size-3xs`) |

Heading 2 Semibold

| +| `--bl-font-heading-2-bold` | Weight: 700 / Bold
Size: 28px / 1.75rem
Height: 32px (font size + `bl-size-3xs`) |

Heading 2 Bold

| + +#### Heading 3 + | Variable | Styles | Example | |:---------|:-------|:-------:| -| `--bl-font-heading-1` | Weight: 300 / Light
Size: 32px / 2rem
Height: 36px (font size + `bl-size-3xs`) |

Heading 1

| -| `--bl-font-heading-2` | Weight: 400 / Regular
Size: 28px / 1.75rem
Height: 32px (font size + `bl-size-3xs`) |

Heading 2

| -| `--bl-font-heading-3` | Weight: 400 / Regular
Size: 24px / 1.5rem
Height: 28px (font size + `bl-size-3xs`) |

Heading 3

| +| `--bl-font-heading-3-regular`| Weight: 400 / Regular
Size: 24px / 1.5rem
Height: 28px (font size + `bl-size-3xs`) |

Heading 3 Regular

| +| `--bl-font-heading-3-medium` | Weight: 500 / Medium
Size: 24px / 1.5rem
Height: 28px (font size + `bl-size-3xs`) |

Heading 3 Medium

| +| `--bl-font-heading-3-semibold` | Weight: 600 / Semibold
Size: 24px / 1.5rem
Height: 28px (font size + `bl-size-3xs`) |

Heading 3 Semibold

| +| `--bl-font-heading-3-bold` | Weight: 700 / Bold
Size: 24px / 1.5rem
Height: 28px (font size + `bl-size-3xs`) |

Heading 3 Bold

| ## Sub Titles @@ -54,7 +75,7 @@ Subtitles are smaller than headlines. They are typically reserved for medium-emp | Variable | Styles | Example | |:---------|:-------|:-------:| -| `--bl-font-title-2-regula` | Weight: 400 / Regular
Size: 16px / 1rem
Height: 20px (font size + `bl-size-3xs`) |

Sub Title 2 Regular

| +| `--bl-font-title-2-regular` | Weight: 400 / Regular
Size: 16px / 1rem
Height: 20px (font size + `bl-size-3xs`) |

Sub Title 2 Regular

| | `--bl-font-title-2-medium` | Weight: 500 / Medium
Size: 16px / 1rem
Height: 20px (font size + `bl-size-3xs`) |

Sub Title 2 Medium

| | `--bl-font-title-2-semibold` | Weight: 600 / Semibold
Size: 16px / 1rem
Height: 20px (font size + `bl-size-3xs`) |

Sub Title 2 Semibold

| | `--bl-font-title-2-bold` | Weight: 700 / Bold
Size: 16px / 1rem
Height: 20px (font size + `bl-size-3xs`) |

Sub Title 2 Bold

| @@ -82,11 +103,26 @@ Subtitles are smaller than headlines. They are typically reserved for medium-emp Body text typically used for long-form writing as it works well for small text sizes. +#### Body Text 1 + +| Variable | Styles | Example | +|:---------|:-------|:-------:| +| `--bl-font-body-text-1-regular` | Weight: 400 / Regular
Size: 16px / 1rem
Height: 18px (font size + `bl-size-4xs`) |

Form Body Text 1 Regular

| +| `--bl-font-body-text-1-medium` | Weight: 500 / Medium
Size: 16px / 1rem
Height: 18px (font size + `bl-size-4xs`) |

Form Body Text 1 Medium

| + +#### Body Text 2 + +| Variable | Styles | Example | +|:---------|:-------|:-------:| +| `--bl-font-body-text-2-regular` | Weight: 400 / Regular
Size: 14px / 0.875rem
Height: 16px (font size + `bl-size-4xs`) |

Form Body Text 2 Regular

| +| `--bl-font-body-text-2-medium` | Weight: 500 / Medium
Size: 14px / 0.875rem
Height: 16px (font size + `bl-size-4xs`) |

Form Body Text 2 Medium

| + +#### Body Text 3 + | Variable | Styles | Example | |:---------|:-------|:-------:| -| `--bl-font-body-text-1` | Weight: 400 / Regular
Size: 16px / 1rem
Height: 18px (font size + `bl-size-4xs`) |

Form Body Text 1

| -| `--bl-font-body-text-2` | Weight: 400 / Regular
Size: 14px / 0.875rem
Height: 16px (font size + `bl-size-4xs`) |

Form Body Text 2

| -| `--bl-font-body-text-3` | Weight: 400 / Regular
Size: 12px / 0.75rem
Height: 14px (font size + `bl-size-4xs`)|

Form Body Text 3

| +| `--bl-font-body-text-3-regular` | Weight: 400 / Regular
Size: 12px / 0.75rem
Height: 14px (font size + `bl-size-4xs`) |

Form Body Text 3 Regular

| +| `--bl-font-body-text-3-medium` | Weight: 500 / Medium
Size: 12px / 0.75rem
Height: 14px (font size + `bl-size-4xs`) |

Form Body Text 3 Medium

| ## Captions diff --git a/docs/using-baklava-in-react.stories.mdx b/docs/using-baklava-in-react.stories.mdx index 3cc5ab77..bb8c51ff 100644 --- a/docs/using-baklava-in-react.stories.mdx +++ b/docs/using-baklava-in-react.stories.mdx @@ -17,8 +17,8 @@ npm install @trendyol/baklava Include Baklava library from CDN to your project's `index.html` file's `` section. ```html - - + + ``` Then you can use Baklava React components in your project by importing them from `@trendyol/baklava/dist/baklava-react` in your code. @@ -62,7 +62,7 @@ import ReactDOM from "react-dom/client"; import "@trendyol/baklava"; import { setIconPath } from "@trendyol/baklava"; import "@trendyol/baklava/dist/themes/default.css"; -setIconPath("https://cdn.jsdelivr.net/npm/@trendyol/baklava@2.3.0/dist/assets"); +setIconPath("https://cdn.jsdelivr.net/npm/@trendyol/baklava@3.0.0/dist/assets"); import App from "./App"; @@ -193,7 +193,7 @@ import "vitest-dom/extend-expect"; import "@trendyol/baklava"; import { setIconPath } from "@trendyol/baklava"; import "@trendyol/baklava/dist/themes/default.css"; -setIconPath("https://cdn.jsdelivr.net/npm/@trendyol/baklava@2.3.0/dist/assets"); +setIconPath("https://cdn.jsdelivr.net/npm/@trendyol/baklava@3.0.0/dist/assets"); ``` We are ready to write tests. diff --git a/docs/using-baklava-in-vue.stories.mdx b/docs/using-baklava-in-vue.stories.mdx index ba490dac..3de03100 100644 --- a/docs/using-baklava-in-vue.stories.mdx +++ b/docs/using-baklava-in-vue.stories.mdx @@ -17,8 +17,8 @@ To make the rule more generic, easiest way is ignoring the elements start with ` To be able to use Baklava via CDN, you should add our default.css and baklava.js at head tag in your index.html file. ```html - - + + ``` ### Via NPM @@ -29,7 +29,7 @@ then, ```js @import "@trendyol/baklava/dist/themes/default.css"; import { setIconPath } from '@trendyol/baklava' -setIconPath('https://cdn.jsdelivr.net/npm/@trendyol/baklava@2.3.0/dist/assets') +setIconPath('https://cdn.jsdelivr.net/npm/@trendyol/baklava@3.0.0/dist/assets') ``` #### Vue2 diff --git a/package-lock.json b/package-lock.json index f8469438..9468c947 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@storybook/addon-mdx-gfm": "^7.4.3", "@storybook/addon-viewport": "^7.4.3", "@storybook/jest": "^0.2.2", - "@storybook/testing-library": "^0.2.0", + "@storybook/testing-library": "^0.2.2", "@storybook/web-components": "7.4.3", "@storybook/web-components-vite": "^7.4.3", "@trivago/prettier-plugin-sort-imports": "^4.1.1", @@ -2376,6 +2376,19 @@ "node": ">=8" } }, + "node_modules/@commitlint/load/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/@commitlint/message": { "version": "16.2.1", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz", @@ -6641,13 +6654,13 @@ } }, "node_modules/@storybook/testing-library": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.1.tgz", - "integrity": "sha512-AdbfLCm1C2nEFrhA3ScdicfW6Fjcorehr6RlGwECMiWwaXisnP971Wd4psqtWxlAqQo4tYBZ0f6rJ3J78JLtsg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", + "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", "dev": true, "dependencies": { "@testing-library/dom": "^9.0.0", - "@testing-library/user-event": "~14.4.0", + "@testing-library/user-event": "^14.4.0", "ts-dedent": "^2.2.0" } }, @@ -24629,7 +24642,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -27600,6 +27612,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true } } }, @@ -30483,13 +30501,13 @@ } }, "@storybook/testing-library": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.1.tgz", - "integrity": "sha512-AdbfLCm1C2nEFrhA3ScdicfW6Fjcorehr6RlGwECMiWwaXisnP971Wd4psqtWxlAqQo4tYBZ0f6rJ3J78JLtsg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@storybook/testing-library/-/testing-library-0.2.2.tgz", + "integrity": "sha512-L8sXFJUHmrlyU2BsWWZGuAjv39Jl1uAqUHdxmN42JY15M4+XCMjGlArdCCjDe1wpTSW6USYISA9axjZojgtvnw==", "dev": true, "requires": { "@testing-library/dom": "^9.0.0", - "@testing-library/user-event": "~14.4.0", + "@testing-library/user-event": "^14.4.0", "ts-dedent": "^2.2.0" } }, diff --git a/package.json b/package.json index ec978e51..155020c8 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "serve": "node scripts/build.js --serve", "storybook:dev": "storybook dev -p 1994", "lint": "npm-run-all -s lint:*", - "lint:tsc": "tsc --noEmit", + "lint:tsc": "tsc --noEmit --project ./tsconfig.json", "lint:eslint": "eslint src", "lint:style": "stylelint src/**/*.css", "lint:prettier": "prettier --check src", @@ -89,7 +89,7 @@ "@storybook/addon-mdx-gfm": "^7.4.3", "@storybook/addon-viewport": "^7.4.3", "@storybook/jest": "^0.2.2", - "@storybook/testing-library": "^0.2.0", + "@storybook/testing-library": "^0.2.2", "@storybook/web-components": "7.4.3", "@storybook/web-components-vite": "^7.4.3", "@trivago/prettier-plugin-sort-imports": "^4.1.1", diff --git a/scripts/generate-react-exports.js b/scripts/generate-react-exports.js index 474c6f00..cdeff8de 100644 --- a/scripts/generate-react-exports.js +++ b/scripts/generate-react-exports.js @@ -3,7 +3,7 @@ import { pascalCase } from "pascal-case"; import path from "path"; import { format } from "prettier"; import { fileURLToPath } from "url"; - +import prettierConfig from "../.prettierrc.json" assert { type: "json" }; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -24,43 +24,41 @@ const baklavaReactFileParts = []; for (const module of customElementsModules) { const { declarations, path } = module; - const componentDeclaration = declarations.find(declaration => declaration.customElement === true); - const { events, name: componentName, tagName: fileName, jsDoc } = componentDeclaration; + const component = declarations.find(declaration => declaration.customElement === true); + const { name: componentName, tagName: fileName } = component; - const eventNames = - events?.reduce((acc, curr) => { - acc[getReactEventName(curr.name)] = curr.name; - return acc; - }, {}) || {}; + const eventNames = (component.events || []).map(event => { + const reactEvent = getReactEventName(event.name); + const reactEventName = `${componentName}${reactEvent.split("onBl")[1]}`; + return `${reactEvent}: '${event.name}' as EventName<${reactEventName}>`; + }).join(',\n'); - const eventTypes = - events?.map(event => { - const eventName = getReactEventName(event.name); - const eventType = cleanGenericTypes(componentDeclaration.typeParameters, event.type.text); - const predefinedEventName = `${componentName}${eventName.split("onBl")[1]}`; + component.events?.forEach(event => { + const eventName = getReactEventName(event.name); + const eventType = cleanGenericTypes(component.typeParameters, event.type.text); + const predefinedEventName = `${componentName}${eventName.split("onBl")[1]}`; - eventStatements.push(`export declare type ${predefinedEventName} = ${eventType};`); - return `${eventName}: EventName<${predefinedEventName}>`; - }) || []; + eventStatements.push(`export declare type ${predefinedEventName} = ${eventType};`); + }); const importPath = path.replace(/^src\//, "").replace(/\.ts$/, ""); - const typeName = componentName + "Type"; - const formattedEventTypes = eventTypes.length ? `, {${eventTypes.join(", ")}}` : ""; - const componentType = `${typeName}${formattedEventTypes}`; - importStatements.push(`import type ${typeName} from "./${importPath}";`); - exportStatements.push(`export declare type ${componentName} = ${typeName}`); + importStatements.push(`export type ${componentName} = import("./${importPath}").default;`); + + const jsDoc = component.jsDoc || ""; const source = ` - ${jsDoc || ""} + ${jsDoc} export const ${componentName} = React.lazy(() => customElements.whenDefined('${fileName}').then(() => ({ - default: createComponent<${componentType}>({ + default: createComponent({ react: React, displayName: "${componentName}", tagName: "${fileName}", - elementClass: customElements.get("${fileName}"), - events: ${JSON.stringify(eventNames)}, + elementClass: customElements.get("${fileName}") as Constructor<${componentName}>, + events: { + ${eventNames} + }, }) })) ); @@ -76,16 +74,19 @@ function getReactEventName(baklavaEventName) { } function writeBaklavaReactFile(fileContentParts) { + const constructorType = `type Constructor = { new (): T };`; + const content = [ `/* eslint-disable @typescript-eslint/ban-ts-comment */`, `// @ts-nocheck`, ...importStatements, ...eventStatements, + constructorType, ...exportStatements, ...fileContentParts, ].join("\n\n"); - const formattedContent = format(content, { parser: "typescript" }); + const formattedContent = format(content, Object.assign(prettierConfig, { parser: "typescript" })); const outputPath = `${__dirname}/../src/baklava-react.ts`; fs.writeFileSync(outputPath, formattedContent); } 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.css b/src/components/alert/bl-alert.css index 0d67db45..db8c2f2f 100644 --- a/src/components/alert/bl-alert.css +++ b/src/components/alert/bl-alert.css @@ -4,8 +4,8 @@ .alert { --padding: var(--bl-size-m); - --main-color: var(--bl-color-primary); - --main-bg-color: var(--bl-color-primary-contrast); + --main-color: var(--bl-color-info); + --main-bg-color: var(--bl-color-info-contrast); position: relative; display: flex; @@ -14,7 +14,7 @@ background-color: var(--main-bg-color); color: var(--bl-color-neutral-darker); box-shadow: inset 0 0 0 1px var(--main-color); - border-radius: var(--bl-border-radius-s); + border-radius: var(--bl-border-radius-l); padding: calc(var(--padding) / 2) var(--padding); padding-right: calc(var(--padding) / 2); } 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..81cb60a4 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,11 +112,11 @@ 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", + info: "neutral", warning: "neutral", success: "success", danger: "danger", 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`