@hashicorp/design-system-components 4.24.0-rc-20251002140454 → 4.24.1-rc-20251103142501

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.
Files changed (51) hide show
  1. package/declarations/components/hds/advanced-table/models/row.d.ts +3 -2
  2. package/declarations/components/hds/code-block/copy-button.d.ts +1 -0
  3. package/declarations/components/hds/code-block/index.d.ts +1 -0
  4. package/declarations/components/hds/copy/button/index.d.ts +4 -0
  5. package/declarations/components/hds/flyout/index.d.ts +1 -18
  6. package/declarations/components/hds/modal/index.d.ts +2 -2
  7. package/declarations/components/hds/theme-switcher/index.d.ts +41 -0
  8. package/declarations/components.d.ts +1 -0
  9. package/declarations/services/hds-theming.d.ts +68 -0
  10. package/declarations/services.d.ts +1 -0
  11. package/declarations/template-registry.d.ts +3 -0
  12. package/dist/_app_/components/hds/theme-switcher.js +1 -0
  13. package/dist/_app_/services/hds-theming.js +1 -0
  14. package/dist/components/hds/advanced-table/models/row.js +19 -15
  15. package/dist/components/hds/advanced-table/models/row.js.map +1 -1
  16. package/dist/components/hds/advanced-table/models/table.js +2 -4
  17. package/dist/components/hds/advanced-table/models/table.js.map +1 -1
  18. package/dist/components/hds/app-footer/copyright.js +1 -1
  19. package/dist/components/hds/code-block/copy-button.js +1 -1
  20. package/dist/components/hds/code-block/copy-button.js.map +1 -1
  21. package/dist/components/hds/code-block/index.js +1 -1
  22. package/dist/components/hds/code-block/index.js.map +1 -1
  23. package/dist/components/hds/copy/button/index.js +15 -1
  24. package/dist/components/hds/copy/button/index.js.map +1 -1
  25. package/dist/components/hds/dialog-primitive/body.js +1 -1
  26. package/dist/components/hds/flyout/index.js +31 -54
  27. package/dist/components/hds/flyout/index.js.map +1 -1
  28. package/dist/components/hds/modal/index.js +48 -35
  29. package/dist/components/hds/modal/index.js.map +1 -1
  30. package/dist/components/hds/theme-switcher/index.js +86 -0
  31. package/dist/components/hds/theme-switcher/index.js.map +1 -0
  32. package/dist/components.js +1 -0
  33. package/dist/components.js.map +1 -1
  34. package/dist/services/hds-theming.js +204 -0
  35. package/dist/services/hds-theming.js.map +1 -0
  36. package/dist/services.js +1 -1
  37. package/dist/styles/@hashicorp/design-system-components-common.css +9823 -0
  38. package/dist/styles/@hashicorp/design-system-components-common.css.map +1 -0
  39. package/dist/styles/@hashicorp/design-system-components-common.scss +20 -0
  40. package/dist/styles/@hashicorp/design-system-components.css +32 -18
  41. package/dist/styles/@hashicorp/design-system-components.css.map +1 -0
  42. package/dist/styles/@hashicorp/design-system-components.scss +4 -59
  43. package/dist/styles/@hashicorp/design-system-power-select-overrides.css +229 -0
  44. package/dist/styles/@hashicorp/design-system-power-select-overrides.css.map +1 -0
  45. package/dist/styles/components/app-footer.scss +3 -0
  46. package/dist/styles/components/form/file-input.scss +1 -0
  47. package/dist/styles/components/index.scss +52 -0
  48. package/package.json +9 -4
  49. package/translations/hds/components/app-footer/copyright/en-us.yaml +1 -1
  50. package/translations/hds/components/copy-button/en-us.yaml +1 -0
  51. package/dist/styles/@hashicorp/design-system-components.scss.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/hds/code-block/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { tracked } from '@glimmer/tracking';\nimport { assert } from '@ember/debug';\nimport { next, schedule } from '@ember/runloop';\nimport { htmlSafe } from '@ember/template';\nimport { guidFor } from '@ember/object/internals';\nimport { modifier } from 'ember-modifier';\n\nimport Prism from 'prismjs';\n\nimport type { SafeString } from '@ember/template';\nimport type { WithBoundArgs } from '@glint/template';\n\nimport type { HdsCodeBlockTitleSignature } from './title';\nimport type { HdsCodeBlockDescriptionSignature } from './description';\nimport { HdsCodeBlockLanguageValues } from './types.ts';\nimport type { HdsCodeBlockLanguages } from './types.ts';\nimport type { HdsCopyButtonSignature } from '../copy/button/index.ts';\n\nimport HdsCodeBlockTitleComponent from './title.ts';\nimport HdsCodeBlockDescriptionComponent from './description.ts';\n\nimport 'prismjs/plugins/line-numbers/prism-line-numbers';\nimport 'prismjs/plugins/line-highlight/prism-line-highlight';\n\nimport 'prismjs/components/prism-bash';\nimport 'prismjs/components/prism-go';\nimport 'prismjs/components/prism-hcl';\nimport 'prismjs/components/prism-json';\nimport 'prismjs/components/prism-log';\nimport 'prismjs/components/prism-ruby';\nimport 'prismjs/components/prism-shell-session';\nimport 'prismjs/components/prism-yaml';\n\n// These imports are required to overcome a global variable clash in Helios website\n// where language import are overriden by the Prism instance in `CodeBlock`\n// Note that `prism-handlebars` is dependant on `prism-markup-templating`\nimport 'prismjs/components/prism-markup-templating';\nimport 'prismjs/components/prism-handlebars';\n\nexport const LANGUAGES: HdsCodeBlockLanguages[] = Object.values(\n HdsCodeBlockLanguageValues\n);\n\nexport interface HdsCodeBlockSignature {\n Args: {\n ariaLabel?: string;\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n hasCopyButton?: boolean;\n hasLineNumbers?: boolean;\n hasLineWrapping?: boolean;\n highlightLines?: string;\n lineNumberStart?: number;\n isStandalone?: boolean;\n language?: HdsCodeBlockLanguages;\n maxHeight?: string;\n value: string;\n copyButtonText?: HdsCopyButtonSignature['Args']['text'];\n onCopy?: HdsCopyButtonSignature['Args']['onSuccess'];\n };\n Blocks: {\n default: [\n {\n Title?: WithBoundArgs<\n typeof HdsCodeBlockTitleComponent,\n 'didInsertNode'\n >;\n Description?: WithBoundArgs<\n typeof HdsCodeBlockDescriptionComponent,\n 'didInsertNode'\n >;\n },\n ];\n };\n Element: HTMLDivElement;\n}\n\nexport default class HdsCodeBlock extends Component<HdsCodeBlockSignature> {\n @tracked private _prismCode: SafeString = htmlSafe('');\n @tracked private _isExpanded: boolean = false;\n @tracked private _codeContentHeight: number = 0;\n @tracked private _codeContainerHeight: number = 0;\n @tracked private _titleId: string | undefined;\n @tracked private _descriptionId: string | undefined;\n\n // Generates a unique ID for the code content\n private _preCodeId = 'pre-code-' + guidFor(this);\n private _preCodeElement!: HTMLPreElement;\n private _observer!: ResizeObserver;\n\n // If a code block is hidden from view, and made visible after load, the Prism code needs to be re-run\n private _setUpCodeObserver = modifier((element: HTMLElement) => {\n this._preCodeElement = element.querySelector(\n '.hds-code-block__code'\n ) as HTMLPreElement;\n this._observer = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.contentBoxSize) {\n this._updateCodeHeights();\n this._updatePrismPlugins();\n }\n });\n });\n this._observer.observe(element);\n\n return () => {\n this._observer.disconnect();\n };\n });\n\n private _setUpCodeBlockCode = modifier((element: HTMLElement) => {\n this._isExpanded = false; // reset expanded state on updates\n this.setPrismCode(element);\n return () => {};\n });\n\n get ariaLabelledBy(): string | undefined {\n if (this.args.ariaLabel !== undefined) {\n return;\n }\n\n return this.args.ariaLabelledBy ?? this._titleId;\n }\n\n get ariaDescribedBy(): string | undefined {\n return this.args.ariaDescribedBy ?? this._descriptionId;\n }\n\n // code text content for the CodeBlock\n get code(): string {\n const code = this.args.value;\n\n assert(\n '@code for \"Hds::CodeBlock\" must have a valid value',\n code !== undefined\n );\n\n if (Prism?.plugins?.['NormalizeWhitespace']) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return Prism.plugins['NormalizeWhitespace'].normalize(code);\n }\n\n return code;\n }\n\n get maxHeight(): string | undefined {\n return this._isExpanded ? 'none' : this.args.maxHeight;\n }\n\n // Shows overlay footer if maxHeight is set and the pre tag content height is greater than the pre tag height\n get showFooter(): boolean {\n if (this.args.maxHeight) {\n return this._codeContentHeight > this._codeContainerHeight;\n }\n return false;\n }\n\n // Name of coding language used within CodeBlock for syntax highlighting\n get language(): HdsCodeBlockLanguages | undefined {\n return this.args.language ?? undefined;\n }\n\n // Displays line numbers if true\n get hasLineNumbers(): boolean {\n return this.args.hasLineNumbers ?? true;\n }\n\n // Make CodeBlock container corners appear rounded (the standalone variation)\n get isStandalone(): boolean {\n return this.args.isStandalone ?? true;\n }\n\n // Make text content wrap to multiple lines\n get hasLineWrapping(): boolean {\n return this.args.hasLineWrapping ?? false;\n }\n\n get copyButtonText(): HdsCopyButtonSignature['Args']['text'] {\n return this.args.copyButtonText ? this.args.copyButtonText : 'Copy';\n }\n\n @action\n registerTitleElement(element: HdsCodeBlockTitleSignature['Element']): void {\n this._titleId = element.id;\n }\n\n @action\n registerDescriptionElement(\n element: HdsCodeBlockDescriptionSignature['Element']\n ): void {\n this._descriptionId = element.id;\n }\n\n @action\n setPrismCode(element: HTMLElement): void {\n const code = this.code;\n const language = this.language;\n const grammar = language ? Prism.languages[language] : undefined;\n\n if (code) {\n // eslint-disable-next-line ember/no-runloop\n next((): void => {\n if (language && grammar) {\n this._prismCode = htmlSafe(Prism.highlight(code, grammar, language));\n } else {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n this._prismCode = htmlSafe(Prism.util.encode(code).toString());\n }\n\n // Existing line numbers must be removed in order to be updated correctly\n const lineNumbers = element.querySelector(\n '.line-numbers-rows'\n ) as HTMLElement;\n if (lineNumbers) {\n element.removeChild(lineNumbers);\n }\n\n if (this.args.highlightLines) {\n this._prismCode = this._addHighlightSrOnlyText(\n this._prismCode.toString()\n );\n }\n\n // Force prism-line-numbers plugin initialization, required for Prism.highlight usage\n // See https://github.com/PrismJS/prism/issues/1234\n Prism.hooks.run('complete', {\n code,\n element,\n });\n\n // eslint-disable-next-line ember/no-runloop\n schedule('afterRender', (): void => {\n this._updateCodeHeights();\n // we need to delay re-evaluating the context for prism plugins for as much as possible, and `afterRender` is the 'latest' we can use in the component lifecycle\n this._updatePrismPlugins();\n });\n });\n }\n }\n\n private _updateCodeHeights(): void {\n if (!this._isExpanded) {\n // Get the actual height & the content height of the preCodeElement\n this._codeContentHeight = this._preCodeElement?.scrollHeight ?? 0;\n this._codeContainerHeight = this._preCodeElement?.clientHeight ?? 0;\n }\n }\n\n private _updatePrismPlugins(): void {\n if (this.hasLineNumbers && Prism?.plugins?.['lineNumbers']) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n Prism.plugins['lineNumbers'].resize(this._preCodeElement);\n }\n\n // Force prism-line-highlight plugin initialization\n // Context: https://github.com/hashicorp/design-system/pull/1749#discussion_r1374288785\n if (this.args.highlightLines) {\n // we piggy-back on the plugin's `resize` event listener to trigger a new call of the `highlightLines` function: https://github.com/PrismJS/prism/blob/master/plugins/line-highlight/prism-line-highlight.js#L337\n if (window) window.dispatchEvent(new Event('resize'));\n }\n }\n\n @action\n toggleExpanded(): void {\n this._isExpanded = !this._isExpanded;\n }\n\n // Logic for determining where line highlighting starts and ends taken from Prism.js plugin source code\n // Context: https://github.com/PrismJS/prism/blob/19f8de66b0f3a79aedbbf096081a4060fc0e80af/src/plugins/line-highlight/prism-line-highlight.ts#L82\n private _addHighlightSrOnlyText(code: string): SafeString {\n const NEW_LINE_EXP = /\\n(?!$)/g;\n const lines = code.split(NEW_LINE_EXP);\n const numLines = lines.length;\n const lineOffset = this.args.lineNumberStart\n ? this.args.lineNumberStart\n : 0;\n\n const highlightStart = '<span class=\"sr-only\">highlight start</span>';\n const highlightEnd = '<span class=\"sr-only\">highlight end</span>';\n\n const ranges = this.args.highlightLines\n ?.replace(/\\s+/g, '')\n .split(',')\n .filter(Boolean);\n\n if (ranges && ranges.length > 0) {\n const highlightedLines = [] as { start: number; end: number }[];\n\n ranges.forEach((currentRange) => {\n const range = currentRange.split('-');\n const start = +range[0]! - lineOffset;\n let end = +range[1]! || start - lineOffset;\n end = Math.min(numLines, end);\n highlightedLines.push({\n start: start,\n end: end,\n });\n });\n\n highlightedLines.forEach((line) => {\n lines[line.start - 1] = highlightStart + lines[line.start - 1];\n lines[line.end - 1] = lines[line.end - 1] + highlightEnd;\n });\n\n return htmlSafe(lines.join('\\n'));\n } else {\n return htmlSafe(code);\n }\n }\n\n get classNames(): string {\n // Currently there is only one theme so the class name is hard-coded.\n // In the future, additional themes such as a \"light\" theme could be added.\n const classes = ['hds-code-block', 'hds-code-block--theme-dark'];\n\n if (this.language) {\n classes.push(`language-${this.language}`);\n }\n\n if (this.isStandalone === true) {\n classes.push('hds-code-block--is-standalone');\n }\n\n if (this.hasLineWrapping === true) {\n classes.push('hds-code-block--has-line-wrapping');\n }\n\n // Note: Prism.js is using the specific class name \"line-numbers\" to determine implementation of line numbers in the UI\n if (this.hasLineNumbers) {\n classes.push('line-numbers');\n }\n\n if (this.showFooter) {\n classes.push('hds-code-block--has-overlay-footer');\n }\n\n if (this._isExpanded) {\n classes.push('hds-code-block--is-expanded');\n }\n\n return classes.join(' ');\n }\n}\n"],"names":["LANGUAGES","Object","values","HdsCodeBlockLanguageValues","HdsCodeBlock","Component","g","prototype","tracked","htmlSafe","i","void 0","_preCodeId","guidFor","_preCodeElement","_observer","_setUpCodeObserver","modifier","element","querySelector","ResizeObserver","entries","forEach","entry","contentBoxSize","_updateCodeHeights","_updatePrismPlugins","observe","disconnect","_setUpCodeBlockCode","_isExpanded","setPrismCode","ariaLabelledBy","args","ariaLabel","undefined","_titleId","ariaDescribedBy","_descriptionId","code","value","assert","Prism","plugins","normalize","maxHeight","showFooter","_codeContentHeight","_codeContainerHeight","language","hasLineNumbers","isStandalone","hasLineWrapping","copyButtonText","registerTitleElement","id","n","action","registerDescriptionElement","grammar","languages","next","_prismCode","highlight","util","encode","toString","lineNumbers","removeChild","highlightLines","_addHighlightSrOnlyText","hooks","run","schedule","scrollHeight","clientHeight","resize","window","dispatchEvent","Event","toggleExpanded","NEW_LINE_EXP","lines","split","numLines","length","lineOffset","lineNumberStart","highlightStart","highlightEnd","ranges","replace","filter","Boolean","highlightedLines","currentRange","range","start","end","Math","min","push","line","join","classNames","classes","setComponentTemplate","TEMPLATE"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/hds/code-block/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { tracked } from '@glimmer/tracking';\nimport { assert } from '@ember/debug';\nimport { next, schedule } from '@ember/runloop';\nimport { htmlSafe } from '@ember/template';\nimport { guidFor } from '@ember/object/internals';\nimport { modifier } from 'ember-modifier';\n\nimport Prism from 'prismjs';\n\nimport type { SafeString } from '@ember/template';\nimport type { WithBoundArgs } from '@glint/template';\n\nimport type { HdsCodeBlockTitleSignature } from './title';\nimport type { HdsCodeBlockDescriptionSignature } from './description';\nimport { HdsCodeBlockLanguageValues } from './types.ts';\nimport type { HdsCodeBlockLanguages } from './types.ts';\nimport type { HdsCopyButtonSignature } from '../copy/button/index.ts';\n\nimport HdsCodeBlockTitleComponent from './title.ts';\nimport HdsCodeBlockDescriptionComponent from './description.ts';\n\nimport 'prismjs/plugins/line-numbers/prism-line-numbers';\nimport 'prismjs/plugins/line-highlight/prism-line-highlight';\n\nimport 'prismjs/components/prism-bash';\nimport 'prismjs/components/prism-go';\nimport 'prismjs/components/prism-hcl';\nimport 'prismjs/components/prism-json';\nimport 'prismjs/components/prism-log';\nimport 'prismjs/components/prism-ruby';\nimport 'prismjs/components/prism-shell-session';\nimport 'prismjs/components/prism-yaml';\n\n// These imports are required to overcome a global variable clash in Helios website\n// where language import are overriden by the Prism instance in `CodeBlock`\n// Note that `prism-handlebars` is dependant on `prism-markup-templating`\nimport 'prismjs/components/prism-markup-templating';\nimport 'prismjs/components/prism-handlebars';\n\nexport const LANGUAGES: HdsCodeBlockLanguages[] = Object.values(\n HdsCodeBlockLanguageValues\n);\n\nexport interface HdsCodeBlockSignature {\n Args: {\n ariaLabel?: string;\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n hasCopyButton?: boolean;\n hasLineNumbers?: boolean;\n hasLineWrapping?: boolean;\n highlightLines?: string;\n lineNumberStart?: number;\n isStandalone?: boolean;\n language?: HdsCodeBlockLanguages;\n maxHeight?: string;\n value: string;\n copyButtonText?: HdsCopyButtonSignature['Args']['text'];\n onCopy?: HdsCopyButtonSignature['Args']['onSuccess'];\n copySuccessMessageText?: HdsCopyButtonSignature['Args']['ariaMessageText'];\n };\n Blocks: {\n default: [\n {\n Title?: WithBoundArgs<\n typeof HdsCodeBlockTitleComponent,\n 'didInsertNode'\n >;\n Description?: WithBoundArgs<\n typeof HdsCodeBlockDescriptionComponent,\n 'didInsertNode'\n >;\n },\n ];\n };\n Element: HTMLDivElement;\n}\n\nexport default class HdsCodeBlock extends Component<HdsCodeBlockSignature> {\n @tracked private _prismCode: SafeString = htmlSafe('');\n @tracked private _isExpanded: boolean = false;\n @tracked private _codeContentHeight: number = 0;\n @tracked private _codeContainerHeight: number = 0;\n @tracked private _titleId: string | undefined;\n @tracked private _descriptionId: string | undefined;\n\n // Generates a unique ID for the code content\n private _preCodeId = 'pre-code-' + guidFor(this);\n private _preCodeElement!: HTMLPreElement;\n private _observer!: ResizeObserver;\n\n // If a code block is hidden from view, and made visible after load, the Prism code needs to be re-run\n private _setUpCodeObserver = modifier((element: HTMLElement) => {\n this._preCodeElement = element.querySelector(\n '.hds-code-block__code'\n ) as HTMLPreElement;\n this._observer = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.contentBoxSize) {\n this._updateCodeHeights();\n this._updatePrismPlugins();\n }\n });\n });\n this._observer.observe(element);\n\n return () => {\n this._observer.disconnect();\n };\n });\n\n private _setUpCodeBlockCode = modifier((element: HTMLElement) => {\n this._isExpanded = false; // reset expanded state on updates\n this.setPrismCode(element);\n return () => {};\n });\n\n get ariaLabelledBy(): string | undefined {\n if (this.args.ariaLabel !== undefined) {\n return;\n }\n\n return this.args.ariaLabelledBy ?? this._titleId;\n }\n\n get ariaDescribedBy(): string | undefined {\n return this.args.ariaDescribedBy ?? this._descriptionId;\n }\n\n // code text content for the CodeBlock\n get code(): string {\n const code = this.args.value;\n\n assert(\n '@code for \"Hds::CodeBlock\" must have a valid value',\n code !== undefined\n );\n\n if (Prism?.plugins?.['NormalizeWhitespace']) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return Prism.plugins['NormalizeWhitespace'].normalize(code);\n }\n\n return code;\n }\n\n get maxHeight(): string | undefined {\n return this._isExpanded ? 'none' : this.args.maxHeight;\n }\n\n // Shows overlay footer if maxHeight is set and the pre tag content height is greater than the pre tag height\n get showFooter(): boolean {\n if (this.args.maxHeight) {\n return this._codeContentHeight > this._codeContainerHeight;\n }\n return false;\n }\n\n // Name of coding language used within CodeBlock for syntax highlighting\n get language(): HdsCodeBlockLanguages | undefined {\n return this.args.language ?? undefined;\n }\n\n // Displays line numbers if true\n get hasLineNumbers(): boolean {\n return this.args.hasLineNumbers ?? true;\n }\n\n // Make CodeBlock container corners appear rounded (the standalone variation)\n get isStandalone(): boolean {\n return this.args.isStandalone ?? true;\n }\n\n // Make text content wrap to multiple lines\n get hasLineWrapping(): boolean {\n return this.args.hasLineWrapping ?? false;\n }\n\n get copyButtonText(): HdsCopyButtonSignature['Args']['text'] {\n return this.args.copyButtonText ? this.args.copyButtonText : 'Copy';\n }\n\n @action\n registerTitleElement(element: HdsCodeBlockTitleSignature['Element']): void {\n this._titleId = element.id;\n }\n\n @action\n registerDescriptionElement(\n element: HdsCodeBlockDescriptionSignature['Element']\n ): void {\n this._descriptionId = element.id;\n }\n\n @action\n setPrismCode(element: HTMLElement): void {\n const code = this.code;\n const language = this.language;\n const grammar = language ? Prism.languages[language] : undefined;\n\n if (code) {\n // eslint-disable-next-line ember/no-runloop\n next((): void => {\n if (language && grammar) {\n this._prismCode = htmlSafe(Prism.highlight(code, grammar, language));\n } else {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n this._prismCode = htmlSafe(Prism.util.encode(code).toString());\n }\n\n // Existing line numbers must be removed in order to be updated correctly\n const lineNumbers = element.querySelector(\n '.line-numbers-rows'\n ) as HTMLElement;\n if (lineNumbers) {\n element.removeChild(lineNumbers);\n }\n\n if (this.args.highlightLines) {\n this._prismCode = this._addHighlightSrOnlyText(\n this._prismCode.toString()\n );\n }\n\n // Force prism-line-numbers plugin initialization, required for Prism.highlight usage\n // See https://github.com/PrismJS/prism/issues/1234\n Prism.hooks.run('complete', {\n code,\n element,\n });\n\n // eslint-disable-next-line ember/no-runloop\n schedule('afterRender', (): void => {\n this._updateCodeHeights();\n // we need to delay re-evaluating the context for prism plugins for as much as possible, and `afterRender` is the 'latest' we can use in the component lifecycle\n this._updatePrismPlugins();\n });\n });\n }\n }\n\n private _updateCodeHeights(): void {\n if (!this._isExpanded) {\n // Get the actual height & the content height of the preCodeElement\n this._codeContentHeight = this._preCodeElement?.scrollHeight ?? 0;\n this._codeContainerHeight = this._preCodeElement?.clientHeight ?? 0;\n }\n }\n\n private _updatePrismPlugins(): void {\n if (this.hasLineNumbers && Prism?.plugins?.['lineNumbers']) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n Prism.plugins['lineNumbers'].resize(this._preCodeElement);\n }\n\n // Force prism-line-highlight plugin initialization\n // Context: https://github.com/hashicorp/design-system/pull/1749#discussion_r1374288785\n if (this.args.highlightLines) {\n // we piggy-back on the plugin's `resize` event listener to trigger a new call of the `highlightLines` function: https://github.com/PrismJS/prism/blob/master/plugins/line-highlight/prism-line-highlight.js#L337\n if (window) window.dispatchEvent(new Event('resize'));\n }\n }\n\n @action\n toggleExpanded(): void {\n this._isExpanded = !this._isExpanded;\n }\n\n // Logic for determining where line highlighting starts and ends taken from Prism.js plugin source code\n // Context: https://github.com/PrismJS/prism/blob/19f8de66b0f3a79aedbbf096081a4060fc0e80af/src/plugins/line-highlight/prism-line-highlight.ts#L82\n private _addHighlightSrOnlyText(code: string): SafeString {\n const NEW_LINE_EXP = /\\n(?!$)/g;\n const lines = code.split(NEW_LINE_EXP);\n const numLines = lines.length;\n const lineOffset = this.args.lineNumberStart\n ? this.args.lineNumberStart\n : 0;\n\n const highlightStart = '<span class=\"sr-only\">highlight start</span>';\n const highlightEnd = '<span class=\"sr-only\">highlight end</span>';\n\n const ranges = this.args.highlightLines\n ?.replace(/\\s+/g, '')\n .split(',')\n .filter(Boolean);\n\n if (ranges && ranges.length > 0) {\n const highlightedLines = [] as { start: number; end: number }[];\n\n ranges.forEach((currentRange) => {\n const range = currentRange.split('-');\n const start = +range[0]! - lineOffset;\n let end = +range[1]! || start - lineOffset;\n end = Math.min(numLines, end);\n highlightedLines.push({\n start: start,\n end: end,\n });\n });\n\n highlightedLines.forEach((line) => {\n lines[line.start - 1] = highlightStart + lines[line.start - 1];\n lines[line.end - 1] = lines[line.end - 1] + highlightEnd;\n });\n\n return htmlSafe(lines.join('\\n'));\n } else {\n return htmlSafe(code);\n }\n }\n\n get classNames(): string {\n // Currently there is only one theme so the class name is hard-coded.\n // In the future, additional themes such as a \"light\" theme could be added.\n const classes = ['hds-code-block', 'hds-code-block--theme-dark'];\n\n if (this.language) {\n classes.push(`language-${this.language}`);\n }\n\n if (this.isStandalone === true) {\n classes.push('hds-code-block--is-standalone');\n }\n\n if (this.hasLineWrapping === true) {\n classes.push('hds-code-block--has-line-wrapping');\n }\n\n // Note: Prism.js is using the specific class name \"line-numbers\" to determine implementation of line numbers in the UI\n if (this.hasLineNumbers) {\n classes.push('line-numbers');\n }\n\n if (this.showFooter) {\n classes.push('hds-code-block--has-overlay-footer');\n }\n\n if (this._isExpanded) {\n classes.push('hds-code-block--is-expanded');\n }\n\n return classes.join(' ');\n }\n}\n"],"names":["LANGUAGES","Object","values","HdsCodeBlockLanguageValues","HdsCodeBlock","Component","g","prototype","tracked","htmlSafe","i","void 0","_preCodeId","guidFor","_preCodeElement","_observer","_setUpCodeObserver","modifier","element","querySelector","ResizeObserver","entries","forEach","entry","contentBoxSize","_updateCodeHeights","_updatePrismPlugins","observe","disconnect","_setUpCodeBlockCode","_isExpanded","setPrismCode","ariaLabelledBy","args","ariaLabel","undefined","_titleId","ariaDescribedBy","_descriptionId","code","value","assert","Prism","plugins","normalize","maxHeight","showFooter","_codeContentHeight","_codeContainerHeight","language","hasLineNumbers","isStandalone","hasLineWrapping","copyButtonText","registerTitleElement","id","n","action","registerDescriptionElement","grammar","languages","next","_prismCode","highlight","util","encode","toString","lineNumbers","removeChild","highlightLines","_addHighlightSrOnlyText","hooks","run","schedule","scrollHeight","clientHeight","resize","window","dispatchEvent","Event","toggleExpanded","NEW_LINE_EXP","lines","split","numLines","length","lineOffset","lineNumberStart","highlightStart","highlightEnd","ranges","replace","filter","Boolean","highlightedLines","currentRange","range","start","end","Math","min","push","line","join","classNames","classes","setComponentTemplate","TEMPLATE"],"mappings":"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"}
@@ -2,12 +2,13 @@ import Component from '@glimmer/component';
2
2
  import { assert } from '@ember/debug';
3
3
  import { tracked } from '@glimmer/tracking';
4
4
  import { action } from '@ember/object';
5
+ import { service } from '@ember/service';
5
6
  import { HdsCopyButtonSizeValues } from './types.js';
6
7
  import { precompileTemplate } from '@ember/template-compilation';
7
8
  import { g, i, n } from 'decorator-transforms/runtime';
8
9
  import { setComponentTemplate } from '@ember/component';
9
10
 
10
- var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::Button\n class={{this.classNames}}\n @size={{this.size}}\n @isFullWidth={{@isFullWidth}}\n @text={{@text}}\n @icon={{this.icon}}\n @isIconOnly={{@isIconOnly}}\n @color=\"secondary\"\n @iconPosition=\"trailing\"\n {{hds-clipboard text=@textToCopy target=@targetToCopy onSuccess=this.onSuccess onError=this.onError}}\n ...attributes\n/>");
11
+ var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::Button\n class={{this.classNames}}\n @size={{this.size}}\n @isFullWidth={{@isFullWidth}}\n @text={{@text}}\n @icon={{this.icon}}\n @isIconOnly={{@isIconOnly}}\n @color=\"secondary\"\n @iconPosition=\"trailing\"\n {{hds-clipboard text=@textToCopy target=@targetToCopy onSuccess=this.onSuccess onError=this.onError}}\n ...attributes\n/>\n<span class=\"sr-only\" aria-live=\"polite\">{{this.ariaMessageText}}</span>");
11
12
 
12
13
  /**
13
14
  * Copyright (c) HashiCorp, Inc.
@@ -21,6 +22,10 @@ const SUCCESS_ICON = 'clipboard-checked';
21
22
  const ERROR_ICON = 'clipboard-x';
22
23
  const DEFAULT_STATUS = 'idle';
23
24
  class HdsCopyButton extends Component {
25
+ static {
26
+ g(this.prototype, "hdsIntl", [service]);
27
+ }
28
+ #hdsIntl = (i(this, "hdsIntl"), void 0);
24
29
  static {
25
30
  g(this.prototype, "_status", [tracked], function () {
26
31
  return DEFAULT_STATUS;
@@ -73,6 +78,15 @@ class HdsCopyButton extends Component {
73
78
  classes.push(`hds-copy-button--status-${this._status}`);
74
79
  return classes.join(' ');
75
80
  }
81
+ get ariaMessageText() {
82
+ if (this._status === 'success') {
83
+ return this.args.ariaMessageText ?? this.hdsIntl.t('hds.components.copy-button.aria-message-text', {
84
+ default: 'Copied to clipboard'
85
+ });
86
+ } else {
87
+ return '';
88
+ }
89
+ }
76
90
  onSuccess(args) {
77
91
  this._status = 'success';
78
92
  this.resetStatusDelayed();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../../src/components/hds/copy/button/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { assert } from '@ember/debug';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { HdsCopyButtonSizeValues } from './types.ts';\nimport type { HdsCopyButtonSizes } from './types.ts';\nimport type { HdsButtonSignature } from '../../button/';\nimport type { HdsClipboardModifierSignature } from '../../../../modifiers/hds-clipboard.ts';\nimport type { HdsIconSignature } from '../../icon';\n\nexport const DEFAULT_SIZE = HdsCopyButtonSizeValues.Medium;\nexport const SIZES: HdsCopyButtonSizes[] = Object.values(\n HdsCopyButtonSizeValues\n);\nexport const DEFAULT_ICON = 'clipboard-copy';\nexport const SUCCESS_ICON = 'clipboard-checked';\nexport const ERROR_ICON = 'clipboard-x';\nexport const DEFAULT_STATUS = 'idle';\n\nexport interface HdsCopyButtonSignature {\n Args: HdsButtonSignature['Args'] & {\n size?: HdsCopyButtonSizes;\n textToCopy?: HdsClipboardModifierSignature['Args']['Named']['text'];\n targetToCopy?: HdsClipboardModifierSignature['Args']['Named']['target'];\n onSuccess?: HdsClipboardModifierSignature['Args']['Named']['onSuccess'];\n onError?: HdsClipboardModifierSignature['Args']['Named']['onError'];\n };\n Element: HdsButtonSignature['Element'];\n}\n\nexport default class HdsCopyButton extends Component<HdsCopyButtonSignature> {\n @tracked private _status = DEFAULT_STATUS;\n @tracked private _timer: ReturnType<typeof setTimeout> | undefined;\n\n /**\n * @param icon\n * @type {string}\n * @description The icon to be displayed for each status; automatically calculated based on the tracked property `status`.\n */\n get icon(): HdsIconSignature['Args']['name'] {\n let icon: HdsIconSignature['Args']['name'] = DEFAULT_ICON;\n if (this._status === 'success') {\n icon = SUCCESS_ICON;\n } else if (this._status === 'error') {\n icon = ERROR_ICON;\n }\n return icon;\n }\n\n /**\n * @param size\n * @type {string}\n * @default medium\n * @description The size of the copy/button; acceptable values are `small` and `medium`\n */\n get size(): HdsCopyButtonSizes {\n const { size = DEFAULT_SIZE } = this.args;\n\n assert(\n `@size for \"Hds::Copy::Button\" must be one of the following: ${SIZES.join(\n ', '\n )}; received: ${size}`,\n SIZES.includes(size)\n );\n\n return size;\n }\n\n /**\n * Get the class names to apply to the component.\n * @method CopyButton#classNames\n * @return {string} The \"class\" attribute to apply to the component.\n */\n get classNames(): string {\n const classes = ['hds-copy-button'];\n\n // add a class based on the @size argument\n classes.push(`hds-button--size-${this.size}`);\n\n classes.push(`hds-copy-button--status-${this._status}`);\n\n return classes.join(' ');\n }\n\n @action\n onSuccess(\n args: HdsClipboardModifierSignature['Args']['Named']['onSuccess']\n ): void {\n this._status = 'success';\n this.resetStatusDelayed();\n\n const { onSuccess } = this.args;\n\n if (typeof onSuccess === 'function') {\n onSuccess(args);\n }\n }\n\n @action\n onError(\n args: HdsClipboardModifierSignature['Args']['Named']['onError']\n ): void {\n this._status = 'error';\n this.resetStatusDelayed();\n\n const { onError } = this.args;\n\n if (typeof onError === 'function') {\n onError(args);\n }\n }\n\n resetStatusDelayed(): void {\n clearTimeout(this._timer);\n // make it fade back to the default state\n this._timer = setTimeout((): void => {\n this._status = DEFAULT_STATUS;\n }, 1500);\n }\n}\n"],"names":["DEFAULT_SIZE","HdsCopyButtonSizeValues","Medium","SIZES","Object","values","DEFAULT_ICON","SUCCESS_ICON","ERROR_ICON","DEFAULT_STATUS","HdsCopyButton","Component","g","prototype","tracked","i","void 0","icon","_status","size","args","assert","join","includes","classNames","classes","push","onSuccess","resetStatusDelayed","n","action","onError","clearTimeout","_timer","setTimeout","setComponentTemplate","TEMPLATE"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../../src/components/hds/copy/button/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { assert } from '@ember/debug';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { service } from '@ember/service';\n\nimport { HdsCopyButtonSizeValues } from './types.ts';\n\nimport type { HdsCopyButtonSizes } from './types.ts';\nimport type { HdsButtonSignature } from '../../button/';\nimport type { HdsClipboardModifierSignature } from '../../../../modifiers/hds-clipboard.ts';\nimport type { HdsIconSignature } from '../../icon';\nimport type HdsIntlService from '../../../../services/hds-intl';\n\nexport const DEFAULT_SIZE = HdsCopyButtonSizeValues.Medium;\nexport const SIZES: HdsCopyButtonSizes[] = Object.values(\n HdsCopyButtonSizeValues\n);\nexport const DEFAULT_ICON = 'clipboard-copy';\nexport const SUCCESS_ICON = 'clipboard-checked';\nexport const ERROR_ICON = 'clipboard-x';\nexport const DEFAULT_STATUS = 'idle';\n\nexport interface HdsCopyButtonSignature {\n Args: HdsButtonSignature['Args'] & {\n size?: HdsCopyButtonSizes;\n textToCopy?: HdsClipboardModifierSignature['Args']['Named']['text'];\n targetToCopy?: HdsClipboardModifierSignature['Args']['Named']['target'];\n onSuccess?: HdsClipboardModifierSignature['Args']['Named']['onSuccess'];\n onError?: HdsClipboardModifierSignature['Args']['Named']['onError'];\n ariaMessageText?: string;\n };\n Element: HdsButtonSignature['Element'];\n}\n\nexport default class HdsCopyButton extends Component<HdsCopyButtonSignature> {\n @service hdsIntl!: HdsIntlService;\n\n @tracked private _status = DEFAULT_STATUS;\n @tracked private _timer: ReturnType<typeof setTimeout> | undefined;\n\n /**\n * @param icon\n * @type {string}\n * @description The icon to be displayed for each status; automatically calculated based on the tracked property `status`.\n */\n get icon(): HdsIconSignature['Args']['name'] {\n let icon: HdsIconSignature['Args']['name'] = DEFAULT_ICON;\n if (this._status === 'success') {\n icon = SUCCESS_ICON;\n } else if (this._status === 'error') {\n icon = ERROR_ICON;\n }\n return icon;\n }\n\n /**\n * @param size\n * @type {string}\n * @default medium\n * @description The size of the copy/button; acceptable values are `small` and `medium`\n */\n get size(): HdsCopyButtonSizes {\n const { size = DEFAULT_SIZE } = this.args;\n\n assert(\n `@size for \"Hds::Copy::Button\" must be one of the following: ${SIZES.join(\n ', '\n )}; received: ${size}`,\n SIZES.includes(size)\n );\n\n return size;\n }\n\n /**\n * Get the class names to apply to the component.\n * @method CopyButton#classNames\n * @return {string} The \"class\" attribute to apply to the component.\n */\n get classNames(): string {\n const classes = ['hds-copy-button'];\n\n // add a class based on the @size argument\n classes.push(`hds-button--size-${this.size}`);\n\n classes.push(`hds-copy-button--status-${this._status}`);\n\n return classes.join(' ');\n }\n\n get ariaMessageText(): string {\n if (this._status === 'success') {\n return (\n this.args.ariaMessageText ??\n this.hdsIntl.t('hds.components.copy-button.aria-message-text', {\n default: 'Copied to clipboard',\n })\n );\n } else {\n return '';\n }\n }\n\n @action\n onSuccess(\n args: HdsClipboardModifierSignature['Args']['Named']['onSuccess']\n ): void {\n this._status = 'success';\n this.resetStatusDelayed();\n\n const { onSuccess } = this.args;\n\n if (typeof onSuccess === 'function') {\n onSuccess(args);\n }\n }\n\n @action\n onError(\n args: HdsClipboardModifierSignature['Args']['Named']['onError']\n ): void {\n this._status = 'error';\n this.resetStatusDelayed();\n\n const { onError } = this.args;\n\n if (typeof onError === 'function') {\n onError(args);\n }\n }\n\n resetStatusDelayed(): void {\n clearTimeout(this._timer);\n // make it fade back to the default state\n this._timer = setTimeout((): void => {\n this._status = DEFAULT_STATUS;\n }, 1500);\n }\n}\n"],"names":["DEFAULT_SIZE","HdsCopyButtonSizeValues","Medium","SIZES","Object","values","DEFAULT_ICON","SUCCESS_ICON","ERROR_ICON","DEFAULT_STATUS","HdsCopyButton","Component","g","prototype","service","i","void 0","tracked","icon","_status","size","args","assert","join","includes","classNames","classes","push","ariaMessageText","hdsIntl","t","default","onSuccess","resetStatusDelayed","n","action","onError","clearTimeout","_timer","setTimeout","setComponentTemplate","TEMPLATE"],"mappings":"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"}
@@ -2,7 +2,7 @@ import TemplateOnlyComponent from '@ember/component/template-only';
2
2
  import { precompileTemplate } from '@ember/template-compilation';
3
3
  import { setComponentTemplate } from '@ember/component';
4
4
 
5
- var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<div class=\"hds-dialog-primitive__body {{@contextualClass}}\" tabindex=\"0\" ...attributes>\n {{yield}}\n</div>");
5
+ var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<div class=\"hds-dialog-primitive__body {{@contextualClass}}\" tabindex=\"-1\" ...attributes>\n {{yield}}\n</div>");
6
6
 
7
7
  /**
8
8
  * Copyright (c) HashiCorp, Inc.
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
4
4
  import { assert } from '@ember/debug';
5
5
  import { getElementId } from '../../../utils/hds-get-element-id.js';
6
6
  import { buildWaiter } from '@ember/test-waiters';
7
+ import { modifier } from 'ember-modifier';
7
8
  import { HdsFlyoutSizesValues } from './types.js';
8
9
  import '../dialog-primitive/body.js';
9
10
  import '../dialog-primitive/description.js';
@@ -13,7 +14,7 @@ import { precompileTemplate } from '@ember/template-compilation';
13
14
  import { g, i, n } from 'decorator-transforms/runtime';
14
15
  import { setComponentTemplate } from '@ember/component';
15
16
 
16
- var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::DialogPrimitive::Wrapper\n class={{this.classNames}}\n ...attributes\n aria-labelledby={{this.id}}\n {{did-insert this.didInsert}}\n {{will-destroy this.willDestroyNode}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss clickOutsideDeactivates=true)}}\n>\n <:header>\n {{yield\n (hash\n Header=(component\n \"hds/dialog-primitive/header\"\n id=this.id\n onDismiss=this.onDismiss\n contextualClassPrefix=\"hds-flyout\"\n titleTag=\"h1\"\n )\n Description=(component \"hds/dialog-primitive/description\" contextualClass=\"hds-flyout__description\")\n )\n }}\n </:header>\n <:body>\n {{yield (hash Body=(component \"hds/dialog-primitive/body\" contextualClass=\"hds-flyout__body\"))}}\n </:body>\n <:footer>\n {{yield\n (hash\n Footer=(component \"hds/dialog-primitive/footer\" onDismiss=this.onDismiss contextualClass=\"hds-flyout__footer\")\n )\n }}\n </:footer>\n</Hds::DialogPrimitive::Wrapper>\n\n{{#if this._isOpen}}\n <Hds::DialogPrimitive::Overlay @contextualClass=\"hds-flyout__overlay\" />\n{{/if}}");
17
+ var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::DialogPrimitive::Wrapper\n class={{this.classNames}}\n ...attributes\n aria-labelledby={{this.id}}\n {{this._registerDialog}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss clickOutsideDeactivates=true)}}\n>\n <:header>\n {{yield\n (hash\n Header=(component\n \"hds/dialog-primitive/header\"\n id=this.id\n onDismiss=this.onDismiss\n contextualClassPrefix=\"hds-flyout\"\n titleTag=\"h1\"\n )\n Description=(component \"hds/dialog-primitive/description\" contextualClass=\"hds-flyout__description\")\n )\n }}\n </:header>\n <:body>\n {{yield (hash Body=(component \"hds/dialog-primitive/body\" contextualClass=\"hds-flyout__body\"))}}\n </:body>\n <:footer>\n {{yield\n (hash\n Footer=(component \"hds/dialog-primitive/footer\" onDismiss=this.onDismiss contextualClass=\"hds-flyout__footer\")\n )\n }}\n </:footer>\n</Hds::DialogPrimitive::Wrapper>\n\n{{#if this._isOpen}}\n <Hds::DialogPrimitive::Overlay @contextualClass=\"hds-flyout__overlay\" />\n{{/if}}");
17
18
 
18
19
  /**
19
20
  * Copyright (c) HashiCorp, Inc.
@@ -36,15 +37,6 @@ class HdsFlyout extends Component {
36
37
  _element;
37
38
  _body;
38
39
  _bodyInitialOverflowValue = '';
39
-
40
- /**
41
- * Sets the size of the flyout
42
- * Accepted values: medium, large
43
- *
44
- * @param size
45
- * @type {string}
46
- * @default 'medium'
47
- */
48
40
  get size() {
49
41
  const {
50
42
  size = DEFAULT_SIZE
@@ -52,19 +44,9 @@ class HdsFlyout extends Component {
52
44
  assert(`@size for "Hds::Flyout" must be one of the following: ${SIZES.join(', ')}; received: ${size}`, SIZES.includes(size));
53
45
  return size;
54
46
  }
55
-
56
- /**
57
- * Calculates the unique ID to assign to the title
58
- */
59
47
  get id() {
60
48
  return getElementId(this);
61
49
  }
62
-
63
- /**
64
- * Get the class names to apply to the component.
65
- * @method classNames
66
- * @return {string} The "class" attribute to apply to the component.
67
- */
68
50
  get classNames() {
69
51
  const classes = ['hds-flyout'];
70
52
 
@@ -77,11 +59,31 @@ class HdsFlyout extends Component {
77
59
  this.args.onClose(event);
78
60
  }
79
61
  this._isOpen = false;
62
+
63
+ // Reset page `overflow` property
64
+ if (this._body) {
65
+ this._body.style.removeProperty('overflow');
66
+ if (this._bodyInitialOverflowValue === '') {
67
+ if (this._body.style.length === 0) {
68
+ this._body.removeAttribute('style');
69
+ }
70
+ } else {
71
+ this._body.style.setProperty('overflow', this._bodyInitialOverflowValue);
72
+ }
73
+ }
74
+
75
+ // Return focus to a specific element (if provided)
76
+ if (this.args.returnFocusTo) {
77
+ const initiator = document.getElementById(this.args.returnFocusTo);
78
+ if (initiator) {
79
+ initiator.focus();
80
+ }
81
+ }
80
82
  }
81
83
  static {
82
84
  n(this.prototype, "registerOnCloseCallback", [action]);
83
85
  }
84
- didInsert(element) {
86
+ _registerDialog = modifier(element => {
85
87
  // Store references of `<dialog>` and `<body>` elements
86
88
  this._element = element;
87
89
  this._body = document.body;
@@ -98,20 +100,16 @@ class HdsFlyout extends Component {
98
100
  if (!this._element.open) {
99
101
  this.open();
100
102
  }
101
- }
102
- static {
103
- n(this.prototype, "didInsert", [action]);
104
- }
105
- willDestroyNode() {
106
- if (this._element) {
107
- this._element.removeEventListener('close',
103
+ return () => {
104
+ // if the <dialog> is removed from the dom while open we emulate the close event
105
+ if (this._isOpen) {
106
+ this._element?.dispatchEvent(new Event('close'));
107
+ }
108
+ this._element?.removeEventListener('close',
108
109
  // eslint-disable-next-line @typescript-eslint/unbound-method
109
110
  this.registerOnCloseCallback, true);
110
- }
111
- }
112
- static {
113
- n(this.prototype, "willDestroyNode", [action]);
114
- }
111
+ };
112
+ });
115
113
  open() {
116
114
  // Make flyout dialog visible using the native `showModal` method
117
115
  this._element.showModal();
@@ -131,7 +129,6 @@ class HdsFlyout extends Component {
131
129
  async onDismiss() {
132
130
  // allow ember test helpers to be aware of when the `close` event fires
133
131
  // when using `click` or other helpers from '@ember/test-helpers'
134
- // Notice: this code will get stripped out in production builds (DEBUG evaluates to `true` in dev/test builds, but `false` in prod builds)
135
132
  if (this._element.open) {
136
133
  const token = waiter.beginAsync();
137
134
  const listener = () => {
@@ -143,26 +140,6 @@ class HdsFlyout extends Component {
143
140
 
144
141
  // Make flyout dialog invisible using the native `close` method
145
142
  this._element.close();
146
-
147
- // Reset page `overflow` property
148
- if (this._body) {
149
- this._body.style.removeProperty('overflow');
150
- if (this._bodyInitialOverflowValue === '') {
151
- if (this._body.style.length === 0) {
152
- this._body.removeAttribute('style');
153
- }
154
- } else {
155
- this._body.style.setProperty('overflow', this._bodyInitialOverflowValue);
156
- }
157
- }
158
-
159
- // Return focus to a specific element (if provided)
160
- if (this.args.returnFocusTo) {
161
- const initiator = document.getElementById(this.args.returnFocusTo);
162
- if (initiator) {
163
- initiator.focus();
164
- }
165
- }
166
143
  }
167
144
  static {
168
145
  n(this.prototype, "onDismiss", [action]);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/hds/flyout/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { assert } from '@ember/debug';\nimport { getElementId } from '../../../utils/hds-get-element-id.ts';\nimport { buildWaiter } from '@ember/test-waiters';\nimport type { WithBoundArgs } from '@glint/template';\n\nimport type { HdsFlyoutSizes } from './types.ts';\n\nimport { HdsFlyoutSizesValues } from './types.ts';\nimport HdsDialogPrimitiveBodyComponent from '../dialog-primitive/body.ts';\nimport HdsDialogPrimitiveDescriptionComponent from '../dialog-primitive/description.ts';\nimport HdsDialogPrimitiveFooterComponent from '../dialog-primitive/footer.ts';\nimport HdsDialogPrimitiveHeaderComponent from '../dialog-primitive/header.ts';\n\nconst waiter = buildWaiter('@hashicorp/design-system-components:flyout');\n\nexport const DEFAULT_SIZE = HdsFlyoutSizesValues.Medium;\nexport const DEFAULT_HAS_OVERLAY = true;\nexport const SIZES: HdsFlyoutSizes[] = Object.values(HdsFlyoutSizesValues);\n\nexport interface HdsFlyoutSignature {\n Args: {\n size?: HdsFlyoutSizes;\n returnFocusTo?: string;\n onOpen?: () => void;\n onClose?: (event: Event) => void;\n };\n Blocks: {\n default: [\n {\n Header?: WithBoundArgs<\n typeof HdsDialogPrimitiveHeaderComponent,\n 'id' | 'onDismiss' | 'contextualClassPrefix'\n >;\n Description?: WithBoundArgs<\n typeof HdsDialogPrimitiveDescriptionComponent,\n 'contextualClass'\n >;\n Body?: WithBoundArgs<\n typeof HdsDialogPrimitiveBodyComponent,\n 'contextualClass'\n >;\n Footer?: WithBoundArgs<\n typeof HdsDialogPrimitiveFooterComponent,\n 'onDismiss' | 'contextualClass'\n >;\n },\n ];\n };\n Element: HTMLDialogElement;\n}\n\nexport default class HdsFlyout extends Component<HdsFlyoutSignature> {\n @tracked private _isOpen = false;\n // TODO: make this property private; currently blocked by our consumers relying on it despite not being part of the public API: https://github.com/hashicorp/cloud-ui/blob/main/engines/waypoint/addon/components/preview-pane.ts#L15\n // private _element!: HTMLDialogElement;\n _element!: HTMLDialogElement;\n private _body!: HTMLElement;\n private _bodyInitialOverflowValue = '';\n\n /**\n * Sets the size of the flyout\n * Accepted values: medium, large\n *\n * @param size\n * @type {string}\n * @default 'medium'\n */\n get size(): HdsFlyoutSizes {\n const { size = DEFAULT_SIZE } = this.args;\n\n assert(\n `@size for \"Hds::Flyout\" must be one of the following: ${SIZES.join(\n ', '\n )}; received: ${size}`,\n SIZES.includes(size)\n );\n\n return size;\n }\n\n /**\n * Calculates the unique ID to assign to the title\n */\n get id(): string {\n return getElementId(this);\n }\n\n /**\n * Get the class names to apply to the component.\n * @method classNames\n * @return {string} The \"class\" attribute to apply to the component.\n */\n get classNames(): string {\n const classes = ['hds-flyout'];\n\n // add a class based on the @size argument\n classes.push(`hds-flyout--size-${this.size}`);\n\n return classes.join(' ');\n }\n\n @action registerOnCloseCallback(event: Event) {\n if (this.args.onClose && typeof this.args.onClose === 'function') {\n this.args.onClose(event);\n }\n\n this._isOpen = false;\n }\n\n @action\n didInsert(element: HTMLDialogElement): void {\n // Store references of `<dialog>` and `<body>` elements\n this._element = element;\n this._body = document.body;\n\n if (this._body) {\n // Store the initial `overflow` value of `<body>` so we can reset to it\n this._bodyInitialOverflowValue =\n this._body.style.getPropertyValue('overflow');\n }\n\n // Register \"onClose\" callback function to be called when a native 'close' event is dispatched\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this._element.addEventListener('close', this.registerOnCloseCallback, true);\n\n // If the flyout dialog is not already open\n if (!this._element.open) {\n this.open();\n }\n }\n\n @action\n willDestroyNode(): void {\n if (this._element) {\n this._element.removeEventListener(\n 'close',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.registerOnCloseCallback,\n true\n );\n }\n }\n\n @action\n open(): void {\n // Make flyout dialog visible using the native `showModal` method\n this._element.showModal();\n this._isOpen = true;\n\n // Prevent page from scrolling when the dialog is open\n if (this._body) this._body.style.setProperty('overflow', 'hidden');\n\n // Call \"onOpen\" callback function\n if (this.args.onOpen && typeof this.args.onOpen === 'function') {\n this.args.onOpen();\n }\n }\n\n @action\n // eslint-disable-next-line @typescript-eslint/require-await\n async onDismiss(): Promise<void> {\n // allow ember test helpers to be aware of when the `close` event fires\n // when using `click` or other helpers from '@ember/test-helpers'\n // Notice: this code will get stripped out in production builds (DEBUG evaluates to `true` in dev/test builds, but `false` in prod builds)\n if (this._element.open) {\n const token = waiter.beginAsync();\n const listener = () => {\n waiter.endAsync(token);\n this._element.removeEventListener('close', listener);\n };\n this._element.addEventListener('close', listener);\n }\n\n // Make flyout dialog invisible using the native `close` method\n this._element.close();\n\n // Reset page `overflow` property\n if (this._body) {\n this._body.style.removeProperty('overflow');\n if (this._bodyInitialOverflowValue === '') {\n if (this._body.style.length === 0) {\n this._body.removeAttribute('style');\n }\n } else {\n this._body.style.setProperty(\n 'overflow',\n this._bodyInitialOverflowValue\n );\n }\n }\n\n // Return focus to a specific element (if provided)\n if (this.args.returnFocusTo) {\n const initiator = document.getElementById(this.args.returnFocusTo);\n if (initiator) {\n initiator.focus();\n }\n }\n }\n}\n"],"names":["waiter","buildWaiter","DEFAULT_SIZE","HdsFlyoutSizesValues","Medium","DEFAULT_HAS_OVERLAY","SIZES","Object","values","HdsFlyout","Component","g","prototype","tracked","i","void 0","_element","_body","_bodyInitialOverflowValue","size","args","assert","join","includes","id","getElementId","classNames","classes","push","registerOnCloseCallback","event","onClose","_isOpen","n","action","didInsert","element","document","body","style","getPropertyValue","addEventListener","open","willDestroyNode","removeEventListener","showModal","setProperty","onOpen","onDismiss","token","beginAsync","listener","endAsync","close","removeProperty","length","removeAttribute","returnFocusTo","initiator","getElementById","focus","setComponentTemplate","TEMPLATE"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/hds/flyout/index.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { assert } from '@ember/debug';\nimport { getElementId } from '../../../utils/hds-get-element-id.ts';\nimport { buildWaiter } from '@ember/test-waiters';\nimport type { WithBoundArgs } from '@glint/template';\nimport { modifier } from 'ember-modifier';\n\nimport type { HdsFlyoutSizes } from './types.ts';\n\nimport { HdsFlyoutSizesValues } from './types.ts';\nimport HdsDialogPrimitiveBodyComponent from '../dialog-primitive/body.ts';\nimport HdsDialogPrimitiveDescriptionComponent from '../dialog-primitive/description.ts';\nimport HdsDialogPrimitiveFooterComponent from '../dialog-primitive/footer.ts';\nimport HdsDialogPrimitiveHeaderComponent from '../dialog-primitive/header.ts';\n\nconst waiter = buildWaiter('@hashicorp/design-system-components:flyout');\n\nexport const DEFAULT_SIZE = HdsFlyoutSizesValues.Medium;\nexport const DEFAULT_HAS_OVERLAY = true;\nexport const SIZES: HdsFlyoutSizes[] = Object.values(HdsFlyoutSizesValues);\n\nexport interface HdsFlyoutSignature {\n Args: {\n size?: HdsFlyoutSizes;\n returnFocusTo?: string;\n onOpen?: () => void;\n onClose?: (event: Event) => void;\n };\n Blocks: {\n default: [\n {\n Header?: WithBoundArgs<\n typeof HdsDialogPrimitiveHeaderComponent,\n 'id' | 'onDismiss' | 'contextualClassPrefix'\n >;\n Description?: WithBoundArgs<\n typeof HdsDialogPrimitiveDescriptionComponent,\n 'contextualClass'\n >;\n Body?: WithBoundArgs<\n typeof HdsDialogPrimitiveBodyComponent,\n 'contextualClass'\n >;\n Footer?: WithBoundArgs<\n typeof HdsDialogPrimitiveFooterComponent,\n 'onDismiss' | 'contextualClass'\n >;\n },\n ];\n };\n Element: HTMLDialogElement;\n}\n\nexport default class HdsFlyout extends Component<HdsFlyoutSignature> {\n @tracked private _isOpen = false;\n // TODO: make this property private; currently blocked by our consumers relying on it despite not being part of the public API: https://github.com/hashicorp/cloud-ui/blob/main/engines/waypoint/addon/components/preview-pane.ts#L15\n // private _element!: HTMLDialogElement;\n _element!: HTMLDialogElement;\n private _body!: HTMLElement;\n private _bodyInitialOverflowValue = '';\n\n get size(): HdsFlyoutSizes {\n const { size = DEFAULT_SIZE } = this.args;\n\n assert(\n `@size for \"Hds::Flyout\" must be one of the following: ${SIZES.join(\n ', '\n )}; received: ${size}`,\n SIZES.includes(size)\n );\n\n return size;\n }\n\n get id(): string {\n return getElementId(this);\n }\n\n get classNames(): string {\n const classes = ['hds-flyout'];\n\n // add a class based on the @size argument\n classes.push(`hds-flyout--size-${this.size}`);\n\n return classes.join(' ');\n }\n\n @action registerOnCloseCallback(event: Event) {\n if (this.args.onClose && typeof this.args.onClose === 'function') {\n this.args.onClose(event);\n }\n\n this._isOpen = false;\n\n // Reset page `overflow` property\n if (this._body) {\n this._body.style.removeProperty('overflow');\n if (this._bodyInitialOverflowValue === '') {\n if (this._body.style.length === 0) {\n this._body.removeAttribute('style');\n }\n } else {\n this._body.style.setProperty(\n 'overflow',\n this._bodyInitialOverflowValue\n );\n }\n }\n\n // Return focus to a specific element (if provided)\n if (this.args.returnFocusTo) {\n const initiator = document.getElementById(this.args.returnFocusTo);\n if (initiator) {\n initiator.focus();\n }\n }\n }\n\n private _registerDialog = modifier((element: HTMLDialogElement) => {\n // Store references of `<dialog>` and `<body>` elements\n this._element = element;\n this._body = document.body;\n\n if (this._body) {\n // Store the initial `overflow` value of `<body>` so we can reset to it\n this._bodyInitialOverflowValue =\n this._body.style.getPropertyValue('overflow');\n }\n\n // Register \"onClose\" callback function to be called when a native 'close' event is dispatched\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this._element.addEventListener('close', this.registerOnCloseCallback, true);\n\n // If the flyout dialog is not already open\n if (!this._element.open) {\n this.open();\n }\n\n return () => {\n // if the <dialog> is removed from the dom while open we emulate the close event\n if (this._isOpen) {\n this._element?.dispatchEvent(new Event('close'));\n }\n\n this._element?.removeEventListener(\n 'close',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.registerOnCloseCallback,\n true\n );\n };\n });\n\n @action\n open(): void {\n // Make flyout dialog visible using the native `showModal` method\n this._element.showModal();\n this._isOpen = true;\n\n // Prevent page from scrolling when the dialog is open\n if (this._body) this._body.style.setProperty('overflow', 'hidden');\n\n // Call \"onOpen\" callback function\n if (this.args.onOpen && typeof this.args.onOpen === 'function') {\n this.args.onOpen();\n }\n }\n\n @action\n // eslint-disable-next-line @typescript-eslint/require-await\n async onDismiss(): Promise<void> {\n // allow ember test helpers to be aware of when the `close` event fires\n // when using `click` or other helpers from '@ember/test-helpers'\n if (this._element.open) {\n const token = waiter.beginAsync();\n const listener = () => {\n waiter.endAsync(token);\n this._element.removeEventListener('close', listener);\n };\n this._element.addEventListener('close', listener);\n }\n\n // Make flyout dialog invisible using the native `close` method\n this._element.close();\n }\n}\n"],"names":["waiter","buildWaiter","DEFAULT_SIZE","HdsFlyoutSizesValues","Medium","DEFAULT_HAS_OVERLAY","SIZES","Object","values","HdsFlyout","Component","g","prototype","tracked","i","void 0","_element","_body","_bodyInitialOverflowValue","size","args","assert","join","includes","id","getElementId","classNames","classes","push","registerOnCloseCallback","event","onClose","_isOpen","style","removeProperty","length","removeAttribute","setProperty","returnFocusTo","initiator","document","getElementById","focus","n","action","_registerDialog","modifier","element","body","getPropertyValue","addEventListener","open","dispatchEvent","Event","removeEventListener","showModal","onOpen","onDismiss","token","beginAsync","listener","endAsync","close","setComponentTemplate","TEMPLATE"],"mappings":"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"}
@@ -4,6 +4,7 @@ import { action } from '@ember/object';
4
4
  import { assert } from '@ember/debug';
5
5
  import { getElementId } from '../../../utils/hds-get-element-id.js';
6
6
  import { buildWaiter } from '@ember/test-waiters';
7
+ import { modifier } from 'ember-modifier';
7
8
  import '../dialog-primitive/header.js';
8
9
  import '../dialog-primitive/body.js';
9
10
  import '../dialog-primitive/footer.js';
@@ -12,7 +13,7 @@ import { precompileTemplate } from '@ember/template-compilation';
12
13
  import { g, i, n } from 'decorator-transforms/runtime';
13
14
  import { setComponentTemplate } from '@ember/component';
14
15
 
15
- var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::DialogPrimitive::Wrapper\n class={{this.classNames}}\n ...attributes\n aria-labelledby={{this.id}}\n {{did-insert this.didInsert}}\n {{will-destroy this.willDestroyNode}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss clickOutsideDeactivates=true)}}\n>\n <:header>\n {{yield\n (hash\n Header=(component\n \"hds/dialog-primitive/header\"\n id=this.id\n onDismiss=this.onDismiss\n contextualClassPrefix=\"hds-modal\"\n titleTag=\"h1\"\n )\n )\n }}\n </:header>\n <:body>\n {{yield (hash Body=(component \"hds/dialog-primitive/body\" contextualClass=\"hds-modal__body\"))}}\n </:body>\n <:footer>\n {{yield\n (hash\n Footer=(component \"hds/dialog-primitive/footer\" onDismiss=this.onDismiss contextualClass=\"hds-modal__footer\")\n )\n }}\n </:footer>\n</Hds::DialogPrimitive::Wrapper>\n\n{{#if this._isOpen}}\n <Hds::DialogPrimitive::Overlay @contextualClass=\"hds-modal__overlay\" />\n{{/if}}");
16
+ var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<Hds::DialogPrimitive::Wrapper\n class={{this.classNames}}\n ...attributes\n aria-labelledby={{this.id}}\n {{this._registerDialog}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss)}}\n>\n <:header>\n {{yield\n (hash\n Header=(component\n \"hds/dialog-primitive/header\"\n id=this.id\n onDismiss=this.onDismiss\n contextualClassPrefix=\"hds-modal\"\n titleTag=\"h1\"\n )\n )\n }}\n </:header>\n <:body>\n {{yield (hash Body=(component \"hds/dialog-primitive/body\" contextualClass=\"hds-modal__body\"))}}\n </:body>\n <:footer>\n {{yield\n (hash\n Footer=(component \"hds/dialog-primitive/footer\" onDismiss=this.onDismiss contextualClass=\"hds-modal__footer\")\n )\n }}\n </:footer>\n</Hds::DialogPrimitive::Wrapper>\n\n{{#if this._isOpen}}\n <Hds::DialogPrimitive::Overlay @contextualClass=\"hds-modal__overlay\" />\n{{/if}}");
16
17
 
17
18
  /**
18
19
  * Copyright (c) HashiCorp, Inc.
@@ -34,6 +35,7 @@ class HdsModal extends Component {
34
35
  _element;
35
36
  _body;
36
37
  _bodyInitialOverflowValue = '';
38
+ _clickOutsideToDismissHandler;
37
39
  get isDismissDisabled() {
38
40
  return this.args.isDismissDisabled ?? false;
39
41
  }
@@ -80,12 +82,32 @@ class HdsModal extends Component {
80
82
  }
81
83
  } else {
82
84
  this._isOpen = false;
85
+
86
+ // Reset page `overflow` property
87
+ if (this._body) {
88
+ this._body.style.removeProperty('overflow');
89
+ if (this._bodyInitialOverflowValue === '') {
90
+ if (this._body.style.length === 0) {
91
+ this._body.removeAttribute('style');
92
+ }
93
+ } else {
94
+ this._body.style.setProperty('overflow', this._bodyInitialOverflowValue);
95
+ }
96
+ }
97
+
98
+ // Return focus to a specific element (if provided)
99
+ if (this.args.returnFocusTo) {
100
+ const initiator = document.getElementById(this.args.returnFocusTo);
101
+ if (initiator) {
102
+ initiator.focus();
103
+ }
104
+ }
83
105
  }
84
106
  }
85
107
  static {
86
108
  n(this.prototype, "registerOnCloseCallback", [action]);
87
109
  }
88
- didInsert(element) {
110
+ _registerDialog = modifier(element => {
89
111
  // Store references of `<dialog>` and `<body>` elements
90
112
  this._element = element;
91
113
  this._body = document.body;
@@ -102,20 +124,32 @@ class HdsModal extends Component {
102
124
  if (!this._element.open) {
103
125
  this.open();
104
126
  }
105
- }
106
- static {
107
- n(this.prototype, "didInsert", [action]);
108
- }
109
- willDestroyNode() {
110
- if (this._element) {
111
- this._element.removeEventListener('close',
127
+
128
+ // Note: because the Modal has the `@isDismissedDisabled` argument, we need to add our own click outside to dismiss logic. This is because `ember-focus-trap` treats the `focusTrapOptions` as static, so we can't update it dynamically if `@isDismissDisabled` changes.
129
+ this._clickOutsideToDismissHandler = event => {
130
+ // check if the click is outside the modal and the modal is open
131
+ if (!this._element.contains(event.target) && this._isOpen) {
132
+ if (!this.isDismissDisabled) {
133
+ // here we use `void` because `onDismiss` is an async function, but in reality we don't need to handle the result or wait for its completion
134
+ void this.onDismiss();
135
+ }
136
+ }
137
+ };
138
+ document.addEventListener('click', this._clickOutsideToDismissHandler, {
139
+ capture: true,
140
+ passive: false
141
+ });
142
+ return () => {
143
+ // if the <dialog> is removed from the dom while open we emulate the close event
144
+ if (this._isOpen) {
145
+ this._element?.dispatchEvent(new Event('close'));
146
+ }
147
+ this._element?.removeEventListener('close',
112
148
  // eslint-disable-next-line @typescript-eslint/unbound-method
113
149
  this.registerOnCloseCallback, true);
114
- }
115
- }
116
- static {
117
- n(this.prototype, "willDestroyNode", [action]);
118
- }
150
+ document.removeEventListener('click', this._clickOutsideToDismissHandler, true);
151
+ };
152
+ });
119
153
  open() {
120
154
  // Make modal dialog visible using the native `showModal` method
121
155
  this._element.showModal();
@@ -135,7 +169,6 @@ class HdsModal extends Component {
135
169
  async onDismiss() {
136
170
  // allow ember test helpers to be aware of when the `close` event fires
137
171
  // when using `click` or other helpers from '@ember/test-helpers'
138
- // Notice: this code will get stripped out in production builds (DEBUG evaluates to `true` in dev/test builds, but `false` in prod builds)
139
172
  if (this._element.open) {
140
173
  const token = waiter.beginAsync();
141
174
  const listener = () => {
@@ -147,26 +180,6 @@ class HdsModal extends Component {
147
180
 
148
181
  // Make modal dialog invisible using the native `close` method
149
182
  this._element.close();
150
-
151
- // Reset page `overflow` property
152
- if (this._body) {
153
- this._body.style.removeProperty('overflow');
154
- if (this._bodyInitialOverflowValue === '') {
155
- if (this._body.style.length === 0) {
156
- this._body.removeAttribute('style');
157
- }
158
- } else {
159
- this._body.style.setProperty('overflow', this._bodyInitialOverflowValue);
160
- }
161
- }
162
-
163
- // Return focus to a specific element (if provided)
164
- if (this.args.returnFocusTo) {
165
- const initiator = document.getElementById(this.args.returnFocusTo);
166
- if (initiator) {
167
- initiator.focus();
168
- }
169
- }
170
183
  }
171
184
  static {
172
185
  n(this.prototype, "onDismiss", [action]);