@hashicorp/design-system-components 4.19.0 → 4.20.0-rc-20250513142046
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/declarations/components/hds/code-block/index.d.ts +6 -39
- package/dist/components/hds/app-side-nav/index.js +12 -5
- package/dist/components/hds/app-side-nav/index.js.map +1 -1
- package/dist/components/hds/code-block/index.js +56 -41
- package/dist/components/hds/code-block/index.js.map +1 -1
- package/dist/components/hds/form/label/index.js +1 -1
- package/dist/styles/@hashicorp/design-system-components.css +86 -13
- package/dist/styles/components/code-block/index.scss +96 -11
- package/package.json +1 -1
|
@@ -47,52 +47,19 @@ export interface HdsCodeBlockSignature {
|
|
|
47
47
|
}
|
|
48
48
|
export default class HdsCodeBlock extends Component<HdsCodeBlockSignature> {
|
|
49
49
|
private _prismCode;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
* @param _preCodeId
|
|
54
|
-
*/
|
|
50
|
+
private _isExpanded;
|
|
51
|
+
private _codeContentHeight;
|
|
52
|
+
private _codeContainerHeight;
|
|
55
53
|
private _preCodeId;
|
|
56
|
-
/**
|
|
57
|
-
* @param code
|
|
58
|
-
* @type {string}
|
|
59
|
-
* @description code text content for the CodeBlock
|
|
60
|
-
*/
|
|
61
54
|
get code(): string;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
* @type {string}
|
|
65
|
-
* @default undefined
|
|
66
|
-
* @description name of coding language used within CodeBlock for syntax highlighting
|
|
67
|
-
*/
|
|
55
|
+
get maxHeight(): string | undefined;
|
|
56
|
+
get showFooter(): boolean;
|
|
68
57
|
get language(): HdsCodeBlockLanguages | undefined;
|
|
69
|
-
/**
|
|
70
|
-
* @param hasLineNumbers
|
|
71
|
-
* @type {boolean}
|
|
72
|
-
* @default true
|
|
73
|
-
* @description Displays line numbers if true
|
|
74
|
-
*/
|
|
75
58
|
get hasLineNumbers(): boolean;
|
|
76
|
-
/**
|
|
77
|
-
* @param isStandalone
|
|
78
|
-
* @type {boolean}
|
|
79
|
-
* @default true
|
|
80
|
-
* @description Make CodeBlock container corners appear rounded
|
|
81
|
-
*/
|
|
82
59
|
get isStandalone(): boolean;
|
|
83
|
-
/**
|
|
84
|
-
* @param hasLineWrapping
|
|
85
|
-
* @type {boolean}
|
|
86
|
-
* @default false
|
|
87
|
-
* @description Make text content wrap on multiple lines
|
|
88
|
-
*/
|
|
89
60
|
get hasLineWrapping(): boolean;
|
|
90
61
|
get copyButtonText(): HdsCopyButtonSignature['Args']['text'];
|
|
91
62
|
setPrismCode(element: HTMLElement): void;
|
|
92
|
-
|
|
93
|
-
* Get the class names to apply to the component.
|
|
94
|
-
* @method classNames
|
|
95
|
-
* @return {string} The "class" attribute to apply to the component.
|
|
96
|
-
*/
|
|
63
|
+
toggleExpanded(): void;
|
|
97
64
|
get classNames(): string;
|
|
98
65
|
}
|
|
@@ -6,7 +6,7 @@ import { precompileTemplate } from '@ember/template-compilation';
|
|
|
6
6
|
import { g, i, n } from 'decorator-transforms/runtime';
|
|
7
7
|
import { setComponentTemplate } from '@ember/component';
|
|
8
8
|
|
|
9
|
-
var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n{{! IMPORTANT: we need to add \"squishies\" here (~) because otherwise the whitespace added by Ember causes the empty element to still have visible padding - See https://handlebarsjs.com/guide/expressions.html#whitespace-control }}\n<div\n class={{this.classNames}}\n ...attributes\n {{on \"transitionstart\" (fn this.setTransition \"start\")}}\n {{on \"transitionend\" (fn this.setTransition \"end\")}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this.shouldTrapFocus}}\n {{did-insert this.didInsert}}\n>\n <h2 class=\"sr-only\" id=\"hds-app-side-nav-header\">Application local navigation</h2>\n\n <div class=\"hds-app-side-nav__wrapper\">\n {{#if this.showToggleButton}}\n {{! template-lint-disable no-invalid-interactive}}\n <div class=\"hds-app-side-nav__overlay\" {{on \"click\" this.toggleMinimizedStatus}} />\n {{! template-lint-enable no-invalid-interactive}}\n <Hds::AppSideNav::ToggleButton\n aria-labelledby=\"hds-app-side-nav-header\"\n aria-expanded={{if this._isMinimized \"false\" \"true\"}}\n @icon={{if this._isMinimized \"chevrons-right\" \"chevrons-left\"}}\n {{on \"click\" this.toggleMinimizedStatus}}\n />\n {{/if}}\n\n <div class=\"hds-app-side-nav__wrapper-body\">\n {{~yield~}}\n </div>\n </div>\n</div>");
|
|
9
|
+
var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n{{! IMPORTANT: we need to add \"squishies\" here (~) because otherwise the whitespace added by Ember causes the empty element to still have visible padding - See https://handlebarsjs.com/guide/expressions.html#whitespace-control }}\n<div\n class={{this.classNames}}\n ...attributes\n {{on \"transitionstart\" (fn this.setTransition \"start\")}}\n {{on \"transitionend\" (fn this.setTransition \"end\")}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this.shouldTrapFocus}}\n {{did-insert this.didInsert}}\n>\n <h2 class=\"sr-only\" id=\"hds-app-side-nav-header\">Application local navigation</h2>\n\n <div class=\"hds-app-side-nav__wrapper\">\n {{#if this.showToggleButton}}\n {{! template-lint-disable no-invalid-interactive}}\n <div class=\"hds-app-side-nav__overlay\" {{on \"click\" this.toggleMinimizedStatus}} />\n {{! template-lint-enable no-invalid-interactive}}\n <Hds::AppSideNav::ToggleButton\n aria-labelledby=\"hds-app-side-nav-header\"\n aria-expanded={{if this._isMinimized \"false\" \"true\"}}\n @icon={{if this._isMinimized \"chevrons-right\" \"chevrons-left\"}}\n {{on \"click\" this.toggleMinimizedStatus}}\n />\n {{/if}}\n\n <div class=\"hds-app-side-nav__wrapper-body hds-app-side-nav-hide-when-minimized\">\n {{~yield~}}\n </div>\n </div>\n</div>");
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Copyright (c) HashiCorp, Inc.
|
|
@@ -137,6 +137,7 @@ class HdsAppSideNav extends Component {
|
|
|
137
137
|
if (event.key === 'Escape' && !this._isMinimized && !this._isDesktop) {
|
|
138
138
|
this._isMinimized = true;
|
|
139
139
|
this.synchronizeInert();
|
|
140
|
+
this.unlockBodyScroll();
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
static {
|
|
@@ -151,10 +152,12 @@ class HdsAppSideNav extends Component {
|
|
|
151
152
|
if (typeof onToggleMinimizedStatus === 'function') {
|
|
152
153
|
onToggleMinimizedStatus(this._isMinimized);
|
|
153
154
|
}
|
|
154
|
-
if (this.
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
if (!this._isDesktop) {
|
|
156
|
+
if (this._isMinimized) {
|
|
157
|
+
this.unlockBodyScroll();
|
|
158
|
+
} else {
|
|
159
|
+
this.lockBodyScroll();
|
|
160
|
+
}
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
static {
|
|
@@ -189,6 +192,10 @@ class HdsAppSideNav extends Component {
|
|
|
189
192
|
// automatically minimize on narrow viewports (when not in desktop mode)
|
|
190
193
|
this._isMinimized = !this._isDesktop;
|
|
191
194
|
this.synchronizeInert();
|
|
195
|
+
if (this._isDesktop) {
|
|
196
|
+
// make sure scrolling is enabled if the user resizes the window from mobile to desktop
|
|
197
|
+
this.unlockBodyScroll();
|
|
198
|
+
}
|
|
192
199
|
const {
|
|
193
200
|
onDesktopViewportChange
|
|
194
201
|
} = this.args;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/hds/app-side-nav/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 { registerDestructor } from '@ember/destroyable';\nimport type Owner from '@ember/owner';\n\nexport interface HdsAppSideNavSignature {\n Args: {\n isResponsive?: boolean;\n isCollapsible?: boolean;\n isMinimized?: boolean;\n onToggleMinimizedStatus?: (arg: boolean) => void;\n onDesktopViewportChange?: (arg: boolean) => void;\n };\n Blocks: {\n default?: [];\n };\n Element: HTMLDivElement;\n}\n\nexport default class HdsAppSideNav extends Component<HdsAppSideNavSignature> {\n @tracked private _isMinimized;\n @tracked private _isAnimating = false;\n @tracked private _isDesktop = true;\n\n private _body!: HTMLElement;\n private _bodyInitialOverflowValue = '';\n private _desktopMQ: MediaQueryList;\n private _containersToHide!: NodeListOf<Element>;\n\n private _desktopMQVal = getComputedStyle(\n document.documentElement\n ).getPropertyValue('--hds-app-desktop-breakpoint');\n\n constructor(owner: Owner, args: HdsAppSideNavSignature['Args']) {\n super(owner, args);\n this._isMinimized = this.args.isMinimized ?? false; // sets the default state on 'desktop' viewports\n this._desktopMQ = window.matchMedia(`(min-width:${this._desktopMQVal})`);\n this.addEventListeners();\n registerDestructor(this, (): void => {\n this.removeEventListeners();\n });\n }\n\n addEventListeners(): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n document.addEventListener('keydown', this.escapePress, true);\n this._desktopMQ.addEventListener(\n 'change',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.updateDesktopVariable,\n true\n );\n // if not instantiated as minimized via arguments\n if (!this.args.isMinimized) {\n // set initial state based on viewport using a \"synthetic\" event\n const syntheticEvent = new MediaQueryListEvent('change', {\n matches: this._desktopMQ.matches,\n media: this._desktopMQ.media,\n });\n this.updateDesktopVariable(syntheticEvent);\n }\n }\n\n removeEventListeners(): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n document.removeEventListener('keydown', this.escapePress, true);\n this._desktopMQ.removeEventListener(\n 'change',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.updateDesktopVariable,\n true\n );\n }\n\n // controls if the component reacts to viewport changes\n get isResponsive(): boolean {\n return this.args.isResponsive ?? true;\n }\n\n // controls if users can collapse the appsidenav on 'desktop' viewports\n get isCollapsible(): boolean {\n return this.args.isCollapsible ?? false;\n }\n\n get shouldTrapFocus(): boolean {\n return this.isResponsive && !this._isDesktop && !this._isMinimized;\n }\n\n get showToggleButton(): boolean {\n return (this.isResponsive && !this._isDesktop) || this.isCollapsible;\n }\n\n get classNames(): string {\n const classes = [`hds-app-side-nav`];\n\n // add specific class names for the different possible states\n if (this.isResponsive) {\n classes.push('hds-app-side-nav--is-responsive');\n }\n if (!this._isDesktop && this.isResponsive) {\n classes.push('hds-app-side-nav--is-mobile');\n } else {\n classes.push('hds-app-side-nav--is-desktop');\n }\n if (this._isMinimized && this.isResponsive) {\n classes.push('hds-app-side-nav--is-minimized');\n } else {\n classes.push('hds-app-side-nav--is-not-minimized');\n }\n if (this._isAnimating) {\n classes.push('hds-app-side-nav--is-animating');\n }\n\n return classes.join(' ');\n }\n\n synchronizeInert(): void {\n this._containersToHide?.forEach((element): void => {\n if (this._isMinimized) {\n element.setAttribute('inert', '');\n } else {\n element.removeAttribute('inert');\n }\n });\n }\n\n lockBodyScroll(): void {\n if (this._body) {\n // Prevent page from scrolling when the dialog is open\n this._body.style.setProperty('overflow', 'hidden');\n }\n }\n\n unlockBodyScroll(): void {\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\n @action\n escapePress(event: KeyboardEvent): void {\n if (event.key === 'Escape' && !this._isMinimized && !this._isDesktop) {\n this._isMinimized = true;\n this.synchronizeInert();\n }\n }\n\n @action\n toggleMinimizedStatus(): void {\n this._isMinimized = !this._isMinimized;\n this.synchronizeInert();\n\n const { onToggleMinimizedStatus } = this.args;\n\n if (typeof onToggleMinimizedStatus === 'function') {\n onToggleMinimizedStatus(this._isMinimized);\n }\n\n if (this._isMinimized) {\n this.unlockBodyScroll();\n } else {\n this.lockBodyScroll();\n }\n }\n\n @action\n didInsert(element: HTMLElement): void {\n this._containersToHide = element.querySelectorAll(\n '.hds-app-side-nav-hide-when-minimized'\n );\n this._body = document.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 @action\n setTransition(phase: string, event: TransitionEvent): void {\n // we only want to respond to `width` animation/transitions\n if (event.propertyName !== 'width') {\n return;\n }\n if (phase === 'start') {\n this._isAnimating = true;\n } else {\n this._isAnimating = false;\n }\n }\n\n @action\n updateDesktopVariable(event: MediaQueryListEvent): void {\n this._isDesktop = event.matches;\n\n // automatically minimize on narrow viewports (when not in desktop mode)\n this._isMinimized = !this._isDesktop;\n\n this.synchronizeInert();\n\n const { onDesktopViewportChange } = this.args;\n\n if (typeof onDesktopViewportChange === 'function') {\n onDesktopViewportChange(this._isDesktop);\n }\n }\n}\n"],"names":["HdsAppSideNav","Component","g","prototype","tracked","i","void 0","_body","_bodyInitialOverflowValue","_desktopMQ","_containersToHide","_desktopMQVal","getComputedStyle","document","documentElement","getPropertyValue","constructor","owner","args","_isMinimized","isMinimized","window","matchMedia","addEventListeners","registerDestructor","removeEventListeners","addEventListener","escapePress","updateDesktopVariable","syntheticEvent","MediaQueryListEvent","matches","media","removeEventListener","isResponsive","isCollapsible","shouldTrapFocus","_isDesktop","showToggleButton","classNames","classes","push","_isAnimating","join","synchronizeInert","forEach","element","setAttribute","removeAttribute","lockBodyScroll","style","setProperty","unlockBodyScroll","removeProperty","length","event","key","n","action","toggleMinimizedStatus","onToggleMinimizedStatus","didInsert","querySelectorAll","body","setTransition","phase","propertyName","onDesktopViewportChange","setComponentTemplate","TEMPLATE"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/hds/app-side-nav/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 { registerDestructor } from '@ember/destroyable';\nimport type Owner from '@ember/owner';\n\nexport interface HdsAppSideNavSignature {\n Args: {\n isResponsive?: boolean;\n isCollapsible?: boolean;\n isMinimized?: boolean;\n onToggleMinimizedStatus?: (arg: boolean) => void;\n onDesktopViewportChange?: (arg: boolean) => void;\n };\n Blocks: {\n default?: [];\n };\n Element: HTMLDivElement;\n}\n\nexport default class HdsAppSideNav extends Component<HdsAppSideNavSignature> {\n @tracked private _isMinimized;\n @tracked private _isAnimating = false;\n @tracked private _isDesktop = true;\n\n private _body!: HTMLElement;\n private _bodyInitialOverflowValue = '';\n private _desktopMQ: MediaQueryList;\n private _containersToHide!: NodeListOf<Element>;\n\n private _desktopMQVal = getComputedStyle(\n document.documentElement\n ).getPropertyValue('--hds-app-desktop-breakpoint');\n\n constructor(owner: Owner, args: HdsAppSideNavSignature['Args']) {\n super(owner, args);\n this._isMinimized = this.args.isMinimized ?? false; // sets the default state on 'desktop' viewports\n this._desktopMQ = window.matchMedia(`(min-width:${this._desktopMQVal})`);\n this.addEventListeners();\n registerDestructor(this, (): void => {\n this.removeEventListeners();\n });\n }\n\n addEventListeners(): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n document.addEventListener('keydown', this.escapePress, true);\n this._desktopMQ.addEventListener(\n 'change',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.updateDesktopVariable,\n true\n );\n // if not instantiated as minimized via arguments\n if (!this.args.isMinimized) {\n // set initial state based on viewport using a \"synthetic\" event\n const syntheticEvent = new MediaQueryListEvent('change', {\n matches: this._desktopMQ.matches,\n media: this._desktopMQ.media,\n });\n this.updateDesktopVariable(syntheticEvent);\n }\n }\n\n removeEventListeners(): void {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n document.removeEventListener('keydown', this.escapePress, true);\n this._desktopMQ.removeEventListener(\n 'change',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n this.updateDesktopVariable,\n true\n );\n }\n\n // controls if the component reacts to viewport changes\n get isResponsive(): boolean {\n return this.args.isResponsive ?? true;\n }\n\n // controls if users can collapse the appsidenav on 'desktop' viewports\n get isCollapsible(): boolean {\n return this.args.isCollapsible ?? false;\n }\n\n get shouldTrapFocus(): boolean {\n return this.isResponsive && !this._isDesktop && !this._isMinimized;\n }\n\n get showToggleButton(): boolean {\n return (this.isResponsive && !this._isDesktop) || this.isCollapsible;\n }\n\n get classNames(): string {\n const classes = [`hds-app-side-nav`];\n\n // add specific class names for the different possible states\n if (this.isResponsive) {\n classes.push('hds-app-side-nav--is-responsive');\n }\n if (!this._isDesktop && this.isResponsive) {\n classes.push('hds-app-side-nav--is-mobile');\n } else {\n classes.push('hds-app-side-nav--is-desktop');\n }\n if (this._isMinimized && this.isResponsive) {\n classes.push('hds-app-side-nav--is-minimized');\n } else {\n classes.push('hds-app-side-nav--is-not-minimized');\n }\n if (this._isAnimating) {\n classes.push('hds-app-side-nav--is-animating');\n }\n\n return classes.join(' ');\n }\n\n synchronizeInert(): void {\n this._containersToHide?.forEach((element): void => {\n if (this._isMinimized) {\n element.setAttribute('inert', '');\n } else {\n element.removeAttribute('inert');\n }\n });\n }\n\n lockBodyScroll(): void {\n if (this._body) {\n // Prevent page from scrolling when the dialog is open\n this._body.style.setProperty('overflow', 'hidden');\n }\n }\n\n unlockBodyScroll(): void {\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\n @action\n escapePress(event: KeyboardEvent): void {\n if (event.key === 'Escape' && !this._isMinimized && !this._isDesktop) {\n this._isMinimized = true;\n this.synchronizeInert();\n this.unlockBodyScroll();\n }\n }\n\n @action\n toggleMinimizedStatus(): void {\n this._isMinimized = !this._isMinimized;\n this.synchronizeInert();\n\n const { onToggleMinimizedStatus } = this.args;\n\n if (typeof onToggleMinimizedStatus === 'function') {\n onToggleMinimizedStatus(this._isMinimized);\n }\n\n if (!this._isDesktop) {\n if (this._isMinimized) {\n this.unlockBodyScroll();\n } else {\n this.lockBodyScroll();\n }\n }\n }\n\n @action\n didInsert(element: HTMLElement): void {\n this._containersToHide = element.querySelectorAll(\n '.hds-app-side-nav-hide-when-minimized'\n );\n this._body = document.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 @action\n setTransition(phase: string, event: TransitionEvent): void {\n // we only want to respond to `width` animation/transitions\n if (event.propertyName !== 'width') {\n return;\n }\n if (phase === 'start') {\n this._isAnimating = true;\n } else {\n this._isAnimating = false;\n }\n }\n\n @action\n updateDesktopVariable(event: MediaQueryListEvent): void {\n this._isDesktop = event.matches;\n\n // automatically minimize on narrow viewports (when not in desktop mode)\n this._isMinimized = !this._isDesktop;\n\n this.synchronizeInert();\n\n if (this._isDesktop) {\n // make sure scrolling is enabled if the user resizes the window from mobile to desktop\n this.unlockBodyScroll();\n }\n\n const { onDesktopViewportChange } = this.args;\n\n if (typeof onDesktopViewportChange === 'function') {\n onDesktopViewportChange(this._isDesktop);\n }\n }\n}\n"],"names":["HdsAppSideNav","Component","g","prototype","tracked","i","void 0","_body","_bodyInitialOverflowValue","_desktopMQ","_containersToHide","_desktopMQVal","getComputedStyle","document","documentElement","getPropertyValue","constructor","owner","args","_isMinimized","isMinimized","window","matchMedia","addEventListeners","registerDestructor","removeEventListeners","addEventListener","escapePress","updateDesktopVariable","syntheticEvent","MediaQueryListEvent","matches","media","removeEventListener","isResponsive","isCollapsible","shouldTrapFocus","_isDesktop","showToggleButton","classNames","classes","push","_isAnimating","join","synchronizeInert","forEach","element","setAttribute","removeAttribute","lockBodyScroll","style","setProperty","unlockBodyScroll","removeProperty","length","event","key","n","action","toggleMinimizedStatus","onToggleMinimizedStatus","didInsert","querySelectorAll","body","setTransition","phase","propertyName","onDesktopViewportChange","setComponentTemplate","TEMPLATE"],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ import { precompileTemplate } from '@ember/template-compilation';
|
|
|
23
23
|
import { g, i, n } from 'decorator-transforms/runtime';
|
|
24
24
|
import { setComponentTemplate } from '@ember/component';
|
|
25
25
|
|
|
26
|
-
var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n\n<div class={{this.classNames}} ...attributes>\n <div class=\"hds-code-block__header\">\n {{~yield (hash Title=(component \"hds/code-block/title\"))~}}\n {{~yield (hash Description=(component \"hds/code-block/description\"))~}}\n </div>\n <div class=\"hds-code-block__body\">\n {{! content within pre tag is whitespace-sensitive; do not add new lines! }}\n <pre\n class=\"hds-code-block__code\"\n {{style maxHeight
|
|
26
|
+
var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n\n<div class={{this.classNames}} ...attributes>\n <div class=\"hds-code-block__header\">\n {{~yield (hash Title=(component \"hds/code-block/title\"))~}}\n {{~yield (hash Description=(component \"hds/code-block/description\"))~}}\n </div>\n <div class=\"hds-code-block__body\">\n {{! content within pre tag is whitespace-sensitive; do not add new lines! }}\n <pre\n class=\"hds-code-block__code\"\n {{style maxHeight=this.maxHeight}}\n data-line={{@highlightLines}}\n data-start={{@lineNumberStart}}\n id={{this._preCodeId}}\n tabindex=\"0\"\n ><code {{did-insert this.setPrismCode}} {{did-update this.setPrismCode this.code @language}}>\n {{~this._prismCode~}}\n </code></pre>\n\n {{#if @hasCopyButton}}\n <Hds::CodeBlock::CopyButton\n @targetToCopy=\"#{{this._preCodeId}}\"\n aria-describedby={{this._preCodeId}}\n @text={{this.copyButtonText}}\n @onCopy={{@onCopy}}\n />\n {{/if}}\n </div>\n {{#if this.showFooter}}\n <div class=\"hds-code-block__overlay-footer\">\n <Hds::Button\n class=\"hds-code-block__height-toggle-button\"\n @text={{if this._isExpanded \"Show less code\" \"Show more code\"}}\n @color=\"secondary\"\n @icon={{if this._isExpanded \"unfold-close\" \"unfold-open\"}}\n @size=\"small\"\n {{on \"click\" this.toggleExpanded}}\n />\n </div>\n {{/if}}\n</div>");
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Copyright (c) HashiCorp, Inc.
|
|
@@ -38,18 +38,28 @@ class HdsCodeBlock extends Component {
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
#_prismCode = (i(this, "_prismCode"), void 0);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
static {
|
|
42
|
+
g(this.prototype, "_isExpanded", [tracked], function () {
|
|
43
|
+
return false;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
#_isExpanded = (i(this, "_isExpanded"), void 0);
|
|
47
|
+
static {
|
|
48
|
+
g(this.prototype, "_codeContentHeight", [tracked], function () {
|
|
49
|
+
return 0;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
#_codeContentHeight = (i(this, "_codeContentHeight"), void 0);
|
|
53
|
+
static {
|
|
54
|
+
g(this.prototype, "_codeContainerHeight", [tracked], function () {
|
|
55
|
+
return 0;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
#_codeContainerHeight = (i(this, "_codeContainerHeight"), void 0);
|
|
59
|
+
// Generates a unique ID for the code content
|
|
46
60
|
_preCodeId = 'pre-code-' + guidFor(this);
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
* @param code
|
|
50
|
-
* @type {string}
|
|
51
|
-
* @description code text content for the CodeBlock
|
|
52
|
-
*/
|
|
62
|
+
// code text content for the CodeBlock
|
|
53
63
|
get code() {
|
|
54
64
|
const code = this.args.value;
|
|
55
65
|
assert('@code for "Hds::CodeBlock" must have a valid value', code !== undefined);
|
|
@@ -59,43 +69,34 @@ class HdsCodeBlock extends Component {
|
|
|
59
69
|
}
|
|
60
70
|
return code;
|
|
61
71
|
}
|
|
72
|
+
get maxHeight() {
|
|
73
|
+
return this._isExpanded ? 'none' : this.args.maxHeight;
|
|
74
|
+
}
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
// Shows overlay footer if maxHeight is set and the pre tag content height is greater than the pre tag height
|
|
77
|
+
get showFooter() {
|
|
78
|
+
if (this.args.maxHeight) {
|
|
79
|
+
return this._codeContentHeight > this._codeContainerHeight;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Name of coding language used within CodeBlock for syntax highlighting
|
|
69
85
|
get language() {
|
|
70
86
|
return this.args.language ?? undefined;
|
|
71
87
|
}
|
|
72
88
|
|
|
73
|
-
|
|
74
|
-
* @param hasLineNumbers
|
|
75
|
-
* @type {boolean}
|
|
76
|
-
* @default true
|
|
77
|
-
* @description Displays line numbers if true
|
|
78
|
-
*/
|
|
89
|
+
// Displays line numbers if true
|
|
79
90
|
get hasLineNumbers() {
|
|
80
91
|
return this.args.hasLineNumbers ?? true;
|
|
81
92
|
}
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
* @param isStandalone
|
|
85
|
-
* @type {boolean}
|
|
86
|
-
* @default true
|
|
87
|
-
* @description Make CodeBlock container corners appear rounded
|
|
88
|
-
*/
|
|
94
|
+
// Make CodeBlock container corners appear rounded (the standalone variation)
|
|
89
95
|
get isStandalone() {
|
|
90
96
|
return this.args.isStandalone ?? true;
|
|
91
97
|
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
* @param hasLineWrapping
|
|
95
|
-
* @type {boolean}
|
|
96
|
-
* @default false
|
|
97
|
-
* @description Make text content wrap on multiple lines
|
|
98
|
-
*/
|
|
99
|
+
// Make text content wrap to multiple lines
|
|
99
100
|
get hasLineWrapping() {
|
|
100
101
|
return this.args.hasLineWrapping ?? false;
|
|
101
102
|
}
|
|
@@ -123,6 +124,14 @@ class HdsCodeBlock extends Component {
|
|
|
123
124
|
element
|
|
124
125
|
});
|
|
125
126
|
|
|
127
|
+
// Get the actual height & the content height of the preCodeElement
|
|
128
|
+
// eslint-disable-next-line ember/no-runloop
|
|
129
|
+
schedule('afterRender', () => {
|
|
130
|
+
const preCodeElement = document.getElementById(this._preCodeId);
|
|
131
|
+
this._codeContentHeight = preCodeElement?.scrollHeight ?? 0;
|
|
132
|
+
this._codeContainerHeight = preCodeElement?.clientHeight ?? 0;
|
|
133
|
+
});
|
|
134
|
+
|
|
126
135
|
// Force prism-line-highlight plugin initialization
|
|
127
136
|
// Context: https://github.com/hashicorp/design-system/pull/1749#discussion_r1374288785
|
|
128
137
|
if (this.args.highlightLines) {
|
|
@@ -136,15 +145,15 @@ class HdsCodeBlock extends Component {
|
|
|
136
145
|
});
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get the class names to apply to the component.
|
|
142
|
-
* @method classNames
|
|
143
|
-
* @return {string} The "class" attribute to apply to the component.
|
|
144
|
-
*/
|
|
145
148
|
static {
|
|
146
149
|
n(this.prototype, "setPrismCode", [action]);
|
|
147
150
|
}
|
|
151
|
+
toggleExpanded() {
|
|
152
|
+
this._isExpanded = !this._isExpanded;
|
|
153
|
+
}
|
|
154
|
+
static {
|
|
155
|
+
n(this.prototype, "toggleExpanded", [action]);
|
|
156
|
+
}
|
|
148
157
|
get classNames() {
|
|
149
158
|
// Currently there is only one theme so the class name is hard-coded.
|
|
150
159
|
// In the future, additional themes such as a "light" theme could be added.
|
|
@@ -163,6 +172,12 @@ class HdsCodeBlock extends Component {
|
|
|
163
172
|
if (this.hasLineNumbers) {
|
|
164
173
|
classes.push('line-numbers');
|
|
165
174
|
}
|
|
175
|
+
if (this.showFooter) {
|
|
176
|
+
classes.push('hds-code-block--has-overlay-footer');
|
|
177
|
+
}
|
|
178
|
+
if (this._isExpanded) {
|
|
179
|
+
classes.push('hds-code-block--is-expanded');
|
|
180
|
+
}
|
|
166
181
|
return classes.join(' ');
|
|
167
182
|
}
|
|
168
183
|
}
|
|
@@ -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';\n\nimport Prism from 'prismjs';\n\nimport type { SafeString } from '@ember/template';\nimport type { ComponentLike } 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 '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: string[] = Object.values(HdsCodeBlockLanguageValues);\n\nexport interface HdsCodeBlockSignature {\n Args: {\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?: ComponentLike<HdsCodeBlockTitleSignature>;\n Description?: ComponentLike<HdsCodeBlockDescriptionSignature>;\n },\n ];\n };\n Element: HTMLDivElement;\n}\n\nexport default class HdsCodeBlock extends Component<HdsCodeBlockSignature> {\n @tracked private _prismCode: SafeString = htmlSafe('');\n\n /**\n * Generates a unique ID for the code content\n *\n * @param _preCodeId\n */\n private _preCodeId = 'pre-code-' + guidFor(this);\n\n /**\n * @param code\n * @type {string}\n * @description code text content for the CodeBlock\n */\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 /**\n * @param language\n * @type {string}\n * @default undefined\n * @description name of coding language used within CodeBlock for syntax highlighting\n */\n get language(): HdsCodeBlockLanguages | undefined {\n return this.args.language ?? undefined;\n }\n\n /**\n * @param hasLineNumbers\n * @type {boolean}\n * @default true\n * @description Displays line numbers if true\n */\n get hasLineNumbers(): boolean {\n return this.args.hasLineNumbers ?? true;\n }\n\n /**\n * @param isStandalone\n * @type {boolean}\n * @default true\n * @description Make CodeBlock container corners appear rounded\n */\n get isStandalone(): boolean {\n return this.args.isStandalone ?? true;\n }\n\n /**\n * @param hasLineWrapping\n * @type {boolean}\n * @default false\n * @description Make text content wrap on multiple lines\n */\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 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(() => {\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 // 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 // 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 need to delay re-evaluating the context for prism-line-highlight for as much as possible, and `afterRender` is the 'latest' we can use in the component lifecycle\n // eslint-disable-next-line ember/no-runloop\n schedule('afterRender', () => {\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 }\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 // 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 return classes.join(' ');\n }\n}\n"],"names":["LANGUAGES","Object","values","HdsCodeBlockLanguageValues","HdsCodeBlock","Component","g","prototype","tracked","htmlSafe","i","void 0","_preCodeId","guidFor","code","args","value","assert","undefined","Prism","plugins","normalize","language","hasLineNumbers","isStandalone","hasLineWrapping","copyButtonText","setPrismCode","element","grammar","languages","next","_prismCode","highlight","util","encode","toString","hooks","run","highlightLines","schedule","window","dispatchEvent","Event","n","action","classNames","classes","push","join","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';\n\nimport Prism from 'prismjs';\n\nimport type { SafeString } from '@ember/template';\nimport type { ComponentLike } 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 '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: string[] = Object.values(HdsCodeBlockLanguageValues);\n\nexport interface HdsCodeBlockSignature {\n Args: {\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?: ComponentLike<HdsCodeBlockTitleSignature>;\n Description?: ComponentLike<HdsCodeBlockDescriptionSignature>;\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\n // Generates a unique ID for the code content\n private _preCodeId = 'pre-code-' + guidFor(this);\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 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 // 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 // Get the actual height & the content height of the preCodeElement\n // eslint-disable-next-line ember/no-runloop\n schedule('afterRender', (): void => {\n const preCodeElement = document.getElementById(this._preCodeId);\n this._codeContentHeight = preCodeElement?.scrollHeight ?? 0;\n this._codeContainerHeight = preCodeElement?.clientHeight ?? 0;\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 need to delay re-evaluating the context for prism-line-highlight for as much as possible, and `afterRender` is the 'latest' we can use in the component lifecycle\n // eslint-disable-next-line ember/no-runloop\n schedule('afterRender', (): void => {\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 }\n }\n\n @action\n toggleExpanded(): void {\n this._isExpanded = !this._isExpanded;\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","code","args","value","assert","undefined","Prism","plugins","normalize","maxHeight","_isExpanded","showFooter","_codeContentHeight","_codeContainerHeight","language","hasLineNumbers","isStandalone","hasLineWrapping","copyButtonText","setPrismCode","element","grammar","languages","next","_prismCode","highlight","util","encode","toString","hooks","run","schedule","preCodeElement","document","getElementById","scrollHeight","clientHeight","highlightLines","window","dispatchEvent","Event","n","action","toggleExpanded","classNames","classes","push","join","setComponentTemplate","TEMPLATE"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import Component from '@glimmer/component';
|
|
|
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<label class={{this.classNames}} for
|
|
5
|
+
var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n<label class={{this.classNames}} for=\"{{@controlId}}\" id={{this.id}} ...attributes>\n {{yield}}\n <Hds::Form::Indicator @isRequired={{@isRequired}} @isOptional={{@isOptional}} />\n</label>");
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Copyright (c) HashiCorp, Inc.
|
|
@@ -3493,7 +3493,6 @@ button.hds-button[href]::after {
|
|
|
3493
3493
|
word-spacing: normal;
|
|
3494
3494
|
tab-size: 4;
|
|
3495
3495
|
hyphens: none;
|
|
3496
|
-
scrollbar-width: thin;
|
|
3497
3496
|
}
|
|
3498
3497
|
@media print {
|
|
3499
3498
|
.hds-code-block pre,
|
|
@@ -3503,11 +3502,13 @@ button.hds-button[href]::after {
|
|
|
3503
3502
|
}
|
|
3504
3503
|
|
|
3505
3504
|
.hds-code-block--is-standalone {
|
|
3505
|
+
overflow: hidden;
|
|
3506
3506
|
border-radius: var(--token-border-radius-medium);
|
|
3507
3507
|
}
|
|
3508
3508
|
|
|
3509
3509
|
.hds-code-block--has-line-wrapping .hds-code-block__code,
|
|
3510
3510
|
.hds-code-block--has-line-wrapping .hds-code-block__code code {
|
|
3511
|
+
display: block;
|
|
3511
3512
|
white-space: pre-wrap;
|
|
3512
3513
|
overflow-wrap: break-word;
|
|
3513
3514
|
}
|
|
@@ -3566,10 +3567,13 @@ button.hds-button[href]::after {
|
|
|
3566
3567
|
.hds-code-block__code {
|
|
3567
3568
|
outline-style: solid;
|
|
3568
3569
|
outline-color: transparent;
|
|
3569
|
-
|
|
3570
|
+
position: relative;
|
|
3571
|
+
display: grid;
|
|
3570
3572
|
margin: 0;
|
|
3571
|
-
padding: 16px;
|
|
3573
|
+
padding: 16px 0 16px 16px;
|
|
3572
3574
|
overflow: auto;
|
|
3575
|
+
scrollbar-width: thin;
|
|
3576
|
+
scrollbar-color: var(--token-color-palette-neutral-400) var(--token-color-palette-neutral-500);
|
|
3573
3577
|
font-size: 0.8125rem;
|
|
3574
3578
|
font-family: var(--token-typography-code-200-font-family);
|
|
3575
3579
|
border-radius: inherit;
|
|
@@ -3590,38 +3594,60 @@ button.hds-button[href]::after {
|
|
|
3590
3594
|
color: var(--hds-code-block-color-foreground-selection);
|
|
3591
3595
|
background-color: var(--hds-code-block-color-surface-selection);
|
|
3592
3596
|
}
|
|
3597
|
+
.hds-code-block__code code {
|
|
3598
|
+
display: inline-block;
|
|
3599
|
+
padding-right: 16px;
|
|
3600
|
+
}
|
|
3593
3601
|
|
|
3602
|
+
.hds-code-block__height-toggle-button,
|
|
3594
3603
|
.hds-code-block__copy-button {
|
|
3595
|
-
position: absolute;
|
|
3596
|
-
top: 11px;
|
|
3597
|
-
right: 12px;
|
|
3598
3604
|
color: var(--hds-code-block-color-foreground-primary);
|
|
3599
3605
|
background-color: var(--hds-code-block-color-surface-faint);
|
|
3600
3606
|
border: 1px solid var(--hds-code-block-color-border-strong);
|
|
3601
3607
|
}
|
|
3602
|
-
.hds-code-
|
|
3608
|
+
.hds-code-block__height-toggle-button:hover, .hds-code-block__height-toggle-button.mock-hover,
|
|
3609
|
+
.hds-code-block__copy-button:hover,
|
|
3610
|
+
.hds-code-block__copy-button.mock-hover {
|
|
3611
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
3603
3612
|
background-color: var(--hds-code-block-color-surface-primary);
|
|
3604
3613
|
border-color: var(--hds-code-block-color-border-strong);
|
|
3605
3614
|
}
|
|
3606
|
-
.hds-code-
|
|
3615
|
+
.hds-code-block__height-toggle-button:active, .hds-code-block__height-toggle-button.mock-active,
|
|
3616
|
+
.hds-code-block__copy-button:active,
|
|
3617
|
+
.hds-code-block__copy-button.mock-active {
|
|
3618
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
3607
3619
|
background-color: var(--hds-code-block-color-surface-interactive-active);
|
|
3608
3620
|
}
|
|
3609
|
-
.hds-code-
|
|
3621
|
+
.hds-code-block__height-toggle-button:focus, .hds-code-block__height-toggle-button.mock-focus, .hds-code-block__height-toggle-button:focus-visible,
|
|
3622
|
+
.hds-code-block__copy-button:focus,
|
|
3623
|
+
.hds-code-block__copy-button.mock-focus,
|
|
3624
|
+
.hds-code-block__copy-button:focus-visible {
|
|
3625
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
3610
3626
|
background-color: var(--hds-code-block-color-surface-faint);
|
|
3611
3627
|
border-color: var(--hds-code-block-color-focus-action-internal);
|
|
3612
3628
|
}
|
|
3613
|
-
.hds-code-
|
|
3629
|
+
.hds-code-block__height-toggle-button:focus::before, .hds-code-block__height-toggle-button.mock-focus::before, .hds-code-block__height-toggle-button:focus-visible::before,
|
|
3630
|
+
.hds-code-block__copy-button:focus::before,
|
|
3631
|
+
.hds-code-block__copy-button.mock-focus::before,
|
|
3632
|
+
.hds-code-block__copy-button:focus-visible::before {
|
|
3614
3633
|
border-color: var(--hds-code-block-color-focus-action-external);
|
|
3615
3634
|
}
|
|
3635
|
+
.hds-code-block__height-toggle-button .hds-icon,
|
|
3636
|
+
.hds-code-block__copy-button .hds-icon {
|
|
3637
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
.hds-code-block__copy-button {
|
|
3641
|
+
position: absolute;
|
|
3642
|
+
top: 11px;
|
|
3643
|
+
right: 12px;
|
|
3644
|
+
}
|
|
3616
3645
|
.hds-code-block__copy-button.hds-copy-button--status-success .hds-icon {
|
|
3617
3646
|
color: var(--hds-code-block-color-foreground-success);
|
|
3618
3647
|
}
|
|
3619
3648
|
.hds-code-block__copy-button.hds-copy-button--status-error .hds-icon {
|
|
3620
3649
|
color: var(--hds-code-block-color-foreground-critical);
|
|
3621
3650
|
}
|
|
3622
|
-
.hds-code-block__copy-button .hds-icon {
|
|
3623
|
-
color: var(--hds-code-block-color-foreground-primary);
|
|
3624
|
-
}
|
|
3625
3651
|
|
|
3626
3652
|
.hds-code-block.line-numbers {
|
|
3627
3653
|
counter-reset: linenumber;
|
|
@@ -3630,6 +3656,9 @@ button.hds-button[href]::after {
|
|
|
3630
3656
|
position: relative;
|
|
3631
3657
|
padding-left: calc(49px + 16px);
|
|
3632
3658
|
}
|
|
3659
|
+
.hds-code-block.line-numbers .hds-code-block__overlay-footer {
|
|
3660
|
+
margin-left: 49px;
|
|
3661
|
+
}
|
|
3633
3662
|
.hds-code-block.line-numbers .line-numbers-rows {
|
|
3634
3663
|
position: absolute;
|
|
3635
3664
|
top: 0;
|
|
@@ -3679,6 +3708,50 @@ button.hds-button[href]::after {
|
|
|
3679
3708
|
font-style: italic;
|
|
3680
3709
|
}
|
|
3681
3710
|
|
|
3711
|
+
.hds-code-block__overlay-footer {
|
|
3712
|
+
position: absolute;
|
|
3713
|
+
right: 0;
|
|
3714
|
+
bottom: 0;
|
|
3715
|
+
left: 0;
|
|
3716
|
+
display: flex;
|
|
3717
|
+
align-items: center;
|
|
3718
|
+
justify-content: center;
|
|
3719
|
+
padding: 10px 16px 10px 16px;
|
|
3720
|
+
pointer-events: none;
|
|
3721
|
+
}
|
|
3722
|
+
.hds-code-block__overlay-footer > * {
|
|
3723
|
+
pointer-events: auto;
|
|
3724
|
+
}
|
|
3725
|
+
|
|
3726
|
+
.hds-code-block--has-overlay-footer .hds-code-block__code::after {
|
|
3727
|
+
position: sticky;
|
|
3728
|
+
bottom: -16px;
|
|
3729
|
+
left: 0;
|
|
3730
|
+
display: block;
|
|
3731
|
+
height: 48px;
|
|
3732
|
+
margin: 0 0 -16px -1000px;
|
|
3733
|
+
background: linear-gradient(360deg, #0d0e12 37.07%, rgba(13, 14, 18, 0.25) 100%);
|
|
3734
|
+
content: "";
|
|
3735
|
+
pointer-events: none;
|
|
3736
|
+
}
|
|
3737
|
+
.hds-code-block--has-overlay-footer .line-numbers .line-numbers-rows {
|
|
3738
|
+
padding-bottom: 48px;
|
|
3739
|
+
}
|
|
3740
|
+
.hds-code-block--has-overlay-footer .line-numbers-rows {
|
|
3741
|
+
z-index: 1;
|
|
3742
|
+
isolation: isolate;
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3745
|
+
.hds-code-block--is-expanded .hds-code-block__code {
|
|
3746
|
+
padding-bottom: 48px;
|
|
3747
|
+
}
|
|
3748
|
+
.hds-code-block--is-expanded .hds-code-block__code::after {
|
|
3749
|
+
content: none;
|
|
3750
|
+
}
|
|
3751
|
+
.hds-code-block--is-expanded .hds-code-block__overlay-footer {
|
|
3752
|
+
background: none;
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3682
3755
|
/**
|
|
3683
3756
|
* Copyright (c) HashiCorp, Inc.
|
|
3684
3757
|
* SPDX-License-Identifier: MPL-2.0
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
// DIMENSIONS
|
|
16
16
|
$hds-code-block-line-numbers-width: 49px; // 3em ≈ 49px
|
|
17
17
|
$hds-code-block-code-padding: 16px;
|
|
18
|
+
$hds-code-block-code-footer-height: 48px;
|
|
18
19
|
|
|
19
20
|
// CODE-BLOCK PARENT/WRAPPER
|
|
20
21
|
|
|
@@ -35,7 +36,6 @@ $hds-code-block-code-padding: 16px;
|
|
|
35
36
|
word-spacing: normal;
|
|
36
37
|
tab-size: 4;
|
|
37
38
|
hyphens: none;
|
|
38
|
-
scrollbar-width: thin;
|
|
39
39
|
|
|
40
40
|
@media print {
|
|
41
41
|
text-shadow: none;
|
|
@@ -47,6 +47,7 @@ $hds-code-block-code-padding: 16px;
|
|
|
47
47
|
|
|
48
48
|
// isStandalone
|
|
49
49
|
.hds-code-block--is-standalone {
|
|
50
|
+
overflow: hidden; // hide corners of scrollbar that poke out
|
|
50
51
|
border-radius: var(--token-border-radius-medium);
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -54,6 +55,7 @@ $hds-code-block-code-padding: 16px;
|
|
|
54
55
|
.hds-code-block--has-line-wrapping {
|
|
55
56
|
.hds-code-block__code,
|
|
56
57
|
.hds-code-block__code code {
|
|
58
|
+
display: block;
|
|
57
59
|
white-space: pre-wrap;
|
|
58
60
|
overflow-wrap: break-word;
|
|
59
61
|
}
|
|
@@ -128,10 +130,13 @@ $hds-code-block-code-padding: 16px;
|
|
|
128
130
|
// Code
|
|
129
131
|
.hds-code-block__code {
|
|
130
132
|
@include hds-focus-ring-basic();
|
|
131
|
-
|
|
133
|
+
position: relative;
|
|
134
|
+
display: grid;
|
|
132
135
|
margin: 0;
|
|
133
|
-
padding: $hds-code-block-code-padding;
|
|
136
|
+
padding: $hds-code-block-code-padding 0 $hds-code-block-code-padding $hds-code-block-code-padding;
|
|
134
137
|
overflow: auto;
|
|
138
|
+
scrollbar-width: thin;
|
|
139
|
+
scrollbar-color: var(--token-color-palette-neutral-400) var(--token-color-palette-neutral-500);
|
|
135
140
|
font-size: 0.8125rem;
|
|
136
141
|
font-family: var(--token-typography-code-200-font-family);
|
|
137
142
|
border-radius: inherit;
|
|
@@ -140,13 +145,16 @@ $hds-code-block-code-padding: 16px;
|
|
|
140
145
|
color: var(--hds-code-block-color-foreground-selection);
|
|
141
146
|
background-color: var(--hds-code-block-color-surface-selection);
|
|
142
147
|
}
|
|
148
|
+
|
|
149
|
+
code {
|
|
150
|
+
display: inline-block;
|
|
151
|
+
padding-right: $hds-code-block-code-padding;
|
|
152
|
+
}
|
|
143
153
|
}
|
|
144
154
|
|
|
145
|
-
//
|
|
155
|
+
// General dark button styles
|
|
156
|
+
.hds-code-block__height-toggle-button,
|
|
146
157
|
.hds-code-block__copy-button {
|
|
147
|
-
position: absolute;
|
|
148
|
-
top: 11px; // 12px -1px accounting for border
|
|
149
|
-
right: 12px; // 12px -1px accounting for border
|
|
150
158
|
// Overriding default colors
|
|
151
159
|
color: var(--hds-code-block-color-foreground-primary);
|
|
152
160
|
background-color: var(--hds-code-block-color-surface-faint);
|
|
@@ -154,18 +162,21 @@ $hds-code-block-code-padding: 16px;
|
|
|
154
162
|
|
|
155
163
|
&:hover,
|
|
156
164
|
&.mock-hover {
|
|
165
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
157
166
|
background-color: var(--hds-code-block-color-surface-primary);
|
|
158
167
|
border-color: var(--hds-code-block-color-border-strong);
|
|
159
168
|
}
|
|
160
169
|
|
|
161
170
|
&:active,
|
|
162
171
|
&.mock-active {
|
|
172
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
163
173
|
background-color: var(--hds-code-block-color-surface-interactive-active);
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
&:focus,
|
|
167
177
|
&.mock-focus,
|
|
168
178
|
&:focus-visible {
|
|
179
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
169
180
|
background-color: var(--hds-code-block-color-surface-faint);
|
|
170
181
|
border-color: var(--hds-code-block-color-focus-action-internal);
|
|
171
182
|
|
|
@@ -174,6 +185,17 @@ $hds-code-block-code-padding: 16px;
|
|
|
174
185
|
}
|
|
175
186
|
}
|
|
176
187
|
|
|
188
|
+
.hds-icon {
|
|
189
|
+
color: var(--hds-code-block-color-foreground-primary);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// CopyButton
|
|
194
|
+
.hds-code-block__copy-button {
|
|
195
|
+
position: absolute;
|
|
196
|
+
top: 11px; // 12px -1px accounting for border
|
|
197
|
+
right: 12px;
|
|
198
|
+
|
|
177
199
|
&.hds-copy-button--status-success {
|
|
178
200
|
.hds-icon {
|
|
179
201
|
color: var(--hds-code-block-color-foreground-success);
|
|
@@ -185,12 +207,9 @@ $hds-code-block-code-padding: 16px;
|
|
|
185
207
|
color: var(--hds-code-block-color-foreground-critical);
|
|
186
208
|
}
|
|
187
209
|
}
|
|
188
|
-
|
|
189
|
-
.hds-icon {
|
|
190
|
-
color: var(--hds-code-block-color-foreground-primary);
|
|
191
|
-
}
|
|
192
210
|
}
|
|
193
211
|
|
|
212
|
+
// Prism.js plugins
|
|
194
213
|
.hds-code-block {
|
|
195
214
|
// LineNumbers plugin styles ---------------
|
|
196
215
|
// Note: Prism.js is using the specific class name "line-numbers" to determine implementation of line numbers in the UI
|
|
@@ -203,6 +222,11 @@ $hds-code-block-code-padding: 16px;
|
|
|
203
222
|
padding-left: calc(#{$hds-code-block-line-numbers-width} + #{$hds-code-block-code-padding});
|
|
204
223
|
}
|
|
205
224
|
|
|
225
|
+
.hds-code-block__overlay-footer {
|
|
226
|
+
// match horizontal padding of the code block
|
|
227
|
+
margin-left: $hds-code-block-line-numbers-width;
|
|
228
|
+
}
|
|
229
|
+
|
|
206
230
|
.line-numbers-rows {
|
|
207
231
|
position: absolute;
|
|
208
232
|
top: 0;
|
|
@@ -262,3 +286,64 @@ $hds-code-block-code-padding: 16px;
|
|
|
262
286
|
font-style: italic;
|
|
263
287
|
}
|
|
264
288
|
}
|
|
289
|
+
|
|
290
|
+
// Footer
|
|
291
|
+
.hds-code-block__overlay-footer {
|
|
292
|
+
position: absolute;
|
|
293
|
+
right: 0;
|
|
294
|
+
bottom: 0;
|
|
295
|
+
left: 0;
|
|
296
|
+
display: flex;
|
|
297
|
+
align-items: center;
|
|
298
|
+
justify-content: center;
|
|
299
|
+
padding: 10px $hds-code-block-code-padding 10px $hds-code-block-code-padding;
|
|
300
|
+
pointer-events: none; // fix issue with scrolling when hovering over the footer
|
|
301
|
+
|
|
302
|
+
// re-enable pointer events for the button (or any content inside the footer)
|
|
303
|
+
> * {
|
|
304
|
+
pointer-events: auto;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Usage of sticky positioning, negative margins, and z-index are required to prevent styling issues
|
|
309
|
+
// when horizontal scrolling is present.
|
|
310
|
+
// https://hashicorp.slack.com/archives/C025N5V4PFZ/p1746659338984369
|
|
311
|
+
.hds-code-block--has-overlay-footer {
|
|
312
|
+
.hds-code-block__code::after {
|
|
313
|
+
// gradient element
|
|
314
|
+
position: sticky; // prevent gradient from scrolling together with content
|
|
315
|
+
bottom: -$hds-code-block-code-padding;
|
|
316
|
+
left: 0;
|
|
317
|
+
display: block;
|
|
318
|
+
height: $hds-code-block-code-footer-height;
|
|
319
|
+
margin: 0 0 -#{$hds-code-block-code-padding} -1000px; // cover line highlights when line numbers are enabled
|
|
320
|
+
background: linear-gradient(360deg, #0d0e12 37.07%, rgba(13, 14, 18, 25%) 100%);
|
|
321
|
+
content: "";
|
|
322
|
+
pointer-events: none;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.line-numbers .line-numbers-rows {
|
|
326
|
+
padding-bottom: $hds-code-block-code-footer-height;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// place line numbers on top of footer gradient
|
|
330
|
+
.line-numbers-rows {
|
|
331
|
+
z-index: 1;
|
|
332
|
+
isolation: isolate;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.hds-code-block--is-expanded {
|
|
337
|
+
.hds-code-block__code {
|
|
338
|
+
// account for the footer at the bottom of the code block
|
|
339
|
+
padding-bottom: $hds-code-block-code-footer-height;
|
|
340
|
+
|
|
341
|
+
&::after {
|
|
342
|
+
content: none;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.hds-code-block__overlay-footer {
|
|
347
|
+
background: none;
|
|
348
|
+
}
|
|
349
|
+
}
|