@hashicorp/mds-react 0.9.3 → 0.9.4
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/components/accordion/index.js +9 -0
- package/components/accordion/index.js.map +1 -0
- package/components/accordion/item/button.js +44 -0
- package/components/accordion/item/button.js.map +1 -0
- package/components/accordion/item/index.js +59 -0
- package/components/accordion/item/index.js.map +1 -0
- package/components/accordion/style.module.scss.js +24 -0
- package/components/accordion/style.module.scss.js.map +1 -0
- package/components/alert/alert.module.scss.js +29 -0
- package/components/alert/alert.module.scss.js.map +1 -0
- package/components/alert/icon.js +34 -0
- package/components/alert/icon.js.map +1 -0
- package/components/alert/index.js +97 -0
- package/components/alert/index.js.map +1 -0
- package/components/badge/index.js +50 -0
- package/components/badge/index.js.map +1 -0
- package/components/badge/style.module.scss.js +22 -0
- package/components/badge/style.module.scss.js.map +1 -0
- package/components/badge-count/index.js +29 -0
- package/components/badge-count/index.js.map +1 -0
- package/components/badge-count/style.module.scss.js +15 -0
- package/components/badge-count/style.module.scss.js.map +1 -0
- package/components/breadcrumbs/index.js +38 -0
- package/components/breadcrumbs/index.js.map +1 -0
- package/components/breadcrumbs/item/index.js +32 -0
- package/components/breadcrumbs/item/index.js.map +1 -0
- package/components/breadcrumbs/style.module.scss.js +27 -0
- package/components/breadcrumbs/style.module.scss.js.map +1 -0
- package/components/breadcrumbs/truncation-button/index.js +25 -0
- package/components/breadcrumbs/truncation-button/index.js.map +1 -0
- package/components/button/index.d.ts +2 -1
- package/components/button/index.js +119 -0
- package/components/button/index.js.map +1 -0
- package/components/button/styles.module.scss.js +32 -0
- package/components/button/styles.module.scss.js.map +1 -0
- package/components/card/card-thumbnail/card-thumbnail.module.css.js +8 -0
- package/components/card/card-thumbnail/card-thumbnail.module.css.js.map +1 -0
- package/components/card/card-thumbnail/index.js +23 -0
- package/components/card/card-thumbnail/index.js.map +1 -0
- package/components/card/index.d.ts +2 -1
- package/components/card/index.js +160 -0
- package/components/card/index.js.map +1 -0
- package/components/card/styles.module.css.js +29 -0
- package/components/card/styles.module.css.js.map +1 -0
- package/components/card/types.d.ts +1 -0
- package/components/code-block/code-block.module.scss.js +34 -0
- package/components/code-block/code-block.module.scss.js.map +1 -0
- package/components/code-block/code-lines/index.js +59 -0
- package/components/code-block/code-lines/index.js.map +1 -0
- package/components/code-block/code-lines/utils/split-html-into-lines.js +19 -0
- package/components/code-block/code-lines/utils/split-html-into-lines.js.map +1 -0
- package/components/code-block/code-lines/utils/split-jsx-into-lines.js +31 -0
- package/components/code-block/code-lines/utils/split-jsx-into-lines.js.map +1 -0
- package/components/code-block/hidden-copy-content/index.js +13 -0
- package/components/code-block/hidden-copy-content/index.js.map +1 -0
- package/components/code-block/index.js +88 -0
- package/components/code-block/index.js.map +1 -0
- package/components/code-block/utils/parse-highlighted-lines.js +39 -0
- package/components/code-block/utils/parse-highlighted-lines.js.map +1 -0
- package/components/code-block/utils/process-snippet.js +20 -0
- package/components/code-block/utils/process-snippet.js.map +1 -0
- package/components/code-block/utils/shellwords.js +33 -0
- package/components/code-block/utils/shellwords.js.map +1 -0
- package/components/combo-box-primitive/index.js +302 -0
- package/components/combo-box-primitive/index.js.map +1 -0
- package/components/dialog-primitive/dialog.module.scss.js +12 -0
- package/components/dialog-primitive/dialog.module.scss.js.map +1 -0
- package/components/dialog-primitive/index.js +15 -0
- package/components/dialog-primitive/index.js.map +1 -0
- package/components/disclosure-primitive/index.js +57 -0
- package/components/disclosure-primitive/index.js.map +1 -0
- package/components/disclosure-primitive/styles.module.css.js +7 -0
- package/components/disclosure-primitive/styles.module.css.js.map +1 -0
- package/components/disclosure-primitive/use-disclosure-primitive.js +17 -0
- package/components/disclosure-primitive/use-disclosure-primitive.js.map +1 -0
- package/components/dismiss-button/index.js +22 -0
- package/components/dismiss-button/index.js.map +1 -0
- package/components/dismiss-button/styles.module.scss.js +7 -0
- package/components/dismiss-button/styles.module.scss.js.map +1 -0
- package/components/dropdown/index.js +79 -0
- package/components/dropdown/index.js.map +1 -0
- package/components/dropdown/list-item/custom.js +9 -0
- package/components/dropdown/list-item/custom.js.map +1 -0
- package/components/dropdown/list-item/index.js +14 -0
- package/components/dropdown/list-item/index.js.map +1 -0
- package/components/dropdown/list-item/interactive.js +49 -0
- package/components/dropdown/list-item/interactive.js.map +1 -0
- package/components/dropdown/list-item/separator.js +17 -0
- package/components/dropdown/list-item/separator.js.map +1 -0
- package/components/dropdown/list-item/styles.module.css.js +26 -0
- package/components/dropdown/list-item/styles.module.css.js.map +1 -0
- package/components/dropdown/list-item/title.js +9 -0
- package/components/dropdown/list-item/title.js.map +1 -0
- package/components/dropdown/styles.module.css.js +24 -0
- package/components/dropdown/styles.module.css.js.map +1 -0
- package/components/dropdown/toggle-button/index.js +54 -0
- package/components/dropdown/toggle-button/index.js.map +1 -0
- package/components/dropdown/toggle-button/styles.module.scss.js +14 -0
- package/components/dropdown/toggle-button/styles.module.scss.js.map +1 -0
- package/components/flight-icon/flight-icon.module.css.js +12 -0
- package/components/flight-icon/flight-icon.module.css.js.map +1 -0
- package/components/flight-icon/index.js +58 -0
- package/components/flight-icon/index.js.map +1 -0
- package/components/form/checkbox/form-checkbox.module.css.js +8 -0
- package/components/form/checkbox/form-checkbox.module.css.js.map +1 -0
- package/components/form/checkbox/index.js +109 -0
- package/components/form/checkbox/index.js.map +1 -0
- package/components/form/error/form-error.module.css.js +14 -0
- package/components/form/error/form-error.module.css.js.map +1 -0
- package/components/form/error/index.js +22 -0
- package/components/form/error/index.js.map +1 -0
- package/components/form/field/form-field.module.css.js +17 -0
- package/components/form/field/form-field.module.css.js.map +1 -0
- package/components/form/field/index.js +46 -0
- package/components/form/field/index.js.map +1 -0
- package/components/form/fieldset/form-fieldset.module.css.js +19 -0
- package/components/form/fieldset/form-fieldset.module.css.js.map +1 -0
- package/components/form/fieldset/index.js +65 -0
- package/components/form/fieldset/index.js.map +1 -0
- package/components/form/file-input/form-file-input.module.scss.js +7 -0
- package/components/form/file-input/form-file-input.module.scss.js.map +1 -0
- package/components/form/file-input/index.js +68 -0
- package/components/form/file-input/index.js.map +1 -0
- package/components/form/helper-text/form-helper-text.module.css.js +7 -0
- package/components/form/helper-text/form-helper-text.module.css.js.map +1 -0
- package/components/form/helper-text/index.js +22 -0
- package/components/form/helper-text/index.js.map +1 -0
- package/components/form/indicator/form-indicator.module.css.js +8 -0
- package/components/form/indicator/form-indicator.module.css.js.map +1 -0
- package/components/form/indicator/index.js +23 -0
- package/components/form/indicator/index.js.map +1 -0
- package/components/form/label/form-label.module.css.js +10 -0
- package/components/form/label/form-label.module.css.js.map +1 -0
- package/components/form/label/index.js +33 -0
- package/components/form/label/index.js.map +1 -0
- package/components/form/legend/form-legend.module.css.js +10 -0
- package/components/form/legend/form-legend.module.css.js.map +1 -0
- package/components/form/legend/index.js +19 -0
- package/components/form/legend/index.js.map +1 -0
- package/components/form/radio/form-radio.module.scss.js +8 -0
- package/components/form/radio/form-radio.module.scss.js.map +1 -0
- package/components/form/radio/index.js +100 -0
- package/components/form/radio/index.js.map +1 -0
- package/components/form/radio-card/description.js +10 -0
- package/components/form/radio-card/description.js.map +1 -0
- package/components/form/radio-card/form-radio-card.module.css.js +30 -0
- package/components/form/radio-card/form-radio-card.module.css.js.map +1 -0
- package/components/form/radio-card/group.js +31 -0
- package/components/form/radio-card/group.js.map +1 -0
- package/components/form/radio-card/index.js +67 -0
- package/components/form/radio-card/index.js.map +1 -0
- package/components/form/radio-card/label.js +10 -0
- package/components/form/radio-card/label.js.map +1 -0
- package/components/form/select/form-select.module.css.js +14 -0
- package/components/form/select/form-select.module.css.js.map +1 -0
- package/components/form/select/index.js +79 -0
- package/components/form/select/index.js.map +1 -0
- package/components/form/super-select/form-super-select.module.css.js +22 -0
- package/components/form/super-select/form-super-select.module.css.js.map +1 -0
- package/components/form/super-select/index.js +170 -0
- package/components/form/super-select/index.js.map +1 -0
- package/components/form/text-input/index.js +91 -0
- package/components/form/text-input/index.js.map +1 -0
- package/components/form/text-input/styles.module.css.js +15 -0
- package/components/form/text-input/styles.module.css.js.map +1 -0
- package/components/form/textarea/form-textarea.module.css.js +14 -0
- package/components/form/textarea/form-textarea.module.css.js.map +1 -0
- package/components/form/textarea/index.js +74 -0
- package/components/form/textarea/index.js.map +1 -0
- package/components/form/toggle/form-toggle.module.scss.js +12 -0
- package/components/form/toggle/form-toggle.module.scss.js.map +1 -0
- package/components/form/toggle/index.js +102 -0
- package/components/form/toggle/index.js.map +1 -0
- package/components/hds/wrappers/tooltip.js +51 -0
- package/components/hds/wrappers/tooltip.js.map +1 -0
- package/components/icon-tile/index.js +50 -0
- package/components/icon-tile/index.js.map +1 -0
- package/components/icon-tile/style.module.scss.js +29 -0
- package/components/icon-tile/style.module.scss.js.map +1 -0
- package/components/index.d.ts +1 -1
- package/components/index.js +116 -73
- package/components/index.js.map +1 -1
- package/components/inline-link/index.js +33 -0
- package/components/inline-link/index.js.map +1 -0
- package/components/inline-link/inline-link.module.css.js +11 -0
- package/components/inline-link/inline-link.module.css.js.map +1 -0
- package/components/interactive/index.js +59 -0
- package/components/interactive/index.js.map +1 -0
- package/components/legacy-button/index.js +65 -0
- package/components/legacy-button/index.js.map +1 -0
- package/components/legacy-button/utils.js +39 -0
- package/components/legacy-button/utils.js.map +1 -0
- package/components/menu-primitive/index.js +68 -0
- package/components/menu-primitive/index.js.map +1 -0
- package/components/menu-primitive/styles.module.css.js +12 -0
- package/components/menu-primitive/styles.module.css.js.map +1 -0
- package/components/menu-primitive/use-menu-primitive.js +17 -0
- package/components/menu-primitive/use-menu-primitive.js.map +1 -0
- package/components/modal/index.js +61 -0
- package/components/modal/index.js.map +1 -0
- package/components/modal/modal.module.css.js +8 -0
- package/components/modal/modal.module.css.js.map +1 -0
- package/components/modal/use-modal.js +17 -0
- package/components/modal/use-modal.js.map +1 -0
- package/components/separator/index.js +15 -0
- package/components/separator/index.js.map +1 -0
- package/components/separator/separator.module.css.js +10 -0
- package/components/separator/separator.module.css.js.map +1 -0
- package/components/standalone-link/index.js +54 -0
- package/components/standalone-link/index.js.map +1 -0
- package/components/standalone-link/styles.module.scss.js +17 -0
- package/components/standalone-link/styles.module.scss.js.map +1 -0
- package/components/table/index.js +52 -0
- package/components/table/index.js.map +1 -0
- package/components/table/table.module.scss.js +33 -0
- package/components/table/table.module.scss.js.map +1 -0
- package/components/table/td.js +28 -0
- package/components/table/td.js.map +1 -0
- package/components/table/th-button-tooltip.js +24 -0
- package/components/table/th-button-tooltip.js.map +1 -0
- package/components/table/th.js +43 -0
- package/components/table/th.js.map +1 -0
- package/components/table/tr.js +9 -0
- package/components/table/tr.js.map +1 -0
- package/components/table/utils.js +28 -0
- package/components/table/utils.js.map +1 -0
- package/components/tabs/index.js +117 -0
- package/components/tabs/index.js.map +1 -0
- package/components/tabs/tab-panel.js +35 -0
- package/components/tabs/tab-panel.js.map +1 -0
- package/components/tabs/tab.js +70 -0
- package/components/tabs/tab.js.map +1 -0
- package/components/tabs/tabs.module.scss.js +22 -0
- package/components/tabs/tabs.module.scss.js.map +1 -0
- package/components/tabs/use-tabs-context.js +16 -0
- package/components/tabs/use-tabs-context.js.map +1 -0
- package/components/text/index.js +112 -0
- package/components/text/index.js.map +1 -0
- package/components/text/style.module.scss.js +9 -0
- package/components/text/style.module.scss.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/dataset-value/index.js +62 -0
- package/components/visualizations/bar-chart/horizontal-chart/dataset-value/index.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/dataset-value/style.module.css.js +20 -0
- package/components/visualizations/bar-chart/horizontal-chart/dataset-value/style.module.css.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/index.js +104 -0
- package/components/visualizations/bar-chart/horizontal-chart/index.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/legend/index.js +13 -0
- package/components/visualizations/bar-chart/horizontal-chart/legend/index.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/legend/style.module.css.js +14 -0
- package/components/visualizations/bar-chart/horizontal-chart/legend/style.module.css.js.map +1 -0
- package/components/visualizations/bar-chart/horizontal-chart/style.module.css.js +28 -0
- package/components/visualizations/bar-chart/horizontal-chart/style.module.css.js.map +1 -0
- package/components/visualizations/bar-chart/index.js +37 -0
- package/components/visualizations/bar-chart/index.js.map +1 -0
- package/components/visualizations/bar-chart/style.module.css.js +12 -0
- package/components/visualizations/bar-chart/style.module.css.js.map +1 -0
- package/components/visualizations/donut-chart/components/arc-tooltip/index.js +14 -0
- package/components/visualizations/donut-chart/components/arc-tooltip/index.js.map +1 -0
- package/components/visualizations/donut-chart/components/arc-tooltip/styles.module.css.js +10 -0
- package/components/visualizations/donut-chart/components/arc-tooltip/styles.module.css.js.map +1 -0
- package/components/visualizations/donut-chart/components/external-arc-label/index.js +58 -0
- package/components/visualizations/donut-chart/components/external-arc-label/index.js.map +1 -0
- package/components/visualizations/donut-chart/components/external-arc-label/styles.module.css.js +16 -0
- package/components/visualizations/donut-chart/components/external-arc-label/styles.module.css.js.map +1 -0
- package/components/visualizations/donut-chart/components/internal-arc-label/index.js +42 -0
- package/components/visualizations/donut-chart/components/internal-arc-label/index.js.map +1 -0
- package/components/visualizations/donut-chart/components/internal-arc-label/styles.module.css.js +14 -0
- package/components/visualizations/donut-chart/components/internal-arc-label/styles.module.css.js.map +1 -0
- package/components/visualizations/donut-chart/index.js +90 -0
- package/components/visualizations/donut-chart/index.js.map +1 -0
- package/components/visualizations/donut-chart/styles.module.css.js +20 -0
- package/components/visualizations/donut-chart/styles.module.css.js.map +1 -0
- package/hooks/use-media-query/index.js +16 -0
- package/hooks/use-media-query/index.js.map +1 -0
- package/index.js +155 -101
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/patterns/card/newsroom-card/index.js +26 -0
- package/patterns/card/newsroom-card/index.js.map +1 -0
- package/patterns/card/newsroom-card/style.module.css.js +8 -0
- package/patterns/card/newsroom-card/style.module.css.js.map +1 -0
- package/patterns/card/partner-card/index.js +42 -0
- package/patterns/card/partner-card/index.js.map +1 -0
- package/patterns/card/partner-card/style.module.css.js +12 -0
- package/patterns/card/partner-card/style.module.css.js.map +1 -0
- package/patterns/card/person-card/index.js +52 -0
- package/patterns/card/person-card/index.js.map +1 -0
- package/patterns/card/person-card/style.module.css.js +12 -0
- package/patterns/card/person-card/style.module.css.js.map +1 -0
- package/patterns/card/primitives.js +77 -0
- package/patterns/card/primitives.js.map +1 -0
- package/patterns/card/promo-card/index.js +36 -0
- package/patterns/card/promo-card/index.js.map +1 -0
- package/patterns/card/resource-card/index.js +26 -0
- package/patterns/card/resource-card/index.js.map +1 -0
- package/patterns/card/style.module.css.js +30 -0
- package/patterns/card/style.module.css.js.map +1 -0
- package/patterns/card/thumbnails/index.js +25 -0
- package/patterns/card/thumbnails/index.js.map +1 -0
- package/patterns/card/unified-card/index.js +37 -0
- package/patterns/card/unified-card/index.js.map +1 -0
- package/patterns/copy-button/clipboard.js +78 -0
- package/patterns/copy-button/clipboard.js.map +1 -0
- package/patterns/copy-button/index.js +57 -0
- package/patterns/copy-button/index.js.map +1 -0
- package/patterns/copy-button/style.module.css.js +13 -0
- package/patterns/copy-button/style.module.css.js.map +1 -0
- package/patterns/index.js +32 -22
- package/patterns/index.js.map +1 -1
- package/patterns/layout/index.js +47 -0
- package/patterns/layout/index.js.map +1 -0
- package/patterns/layout/layout.module.css.js +20 -0
- package/patterns/layout/layout.module.css.js.map +1 -0
- package/patterns/product-badge/index.js +22 -0
- package/patterns/product-badge/index.js.map +1 -0
- package/patterns/product-badge/style.module.css.js +8 -0
- package/patterns/product-badge/style.module.css.js.map +1 -0
- package/patterns/product-logo/index.js +130 -0
- package/patterns/product-logo/index.js.map +1 -0
- package/patterns/product-logo/product-logo.module.css.js +13 -0
- package/patterns/product-logo/product-logo.module.css.js.map +1 -0
- package/patterns/related-content/index.js +65 -0
- package/patterns/related-content/index.js.map +1 -0
- package/patterns/related-content/style.module.css.js +22 -0
- package/patterns/related-content/style.module.css.js.map +1 -0
- package/style.css +1 -1
- package/utils/get-contrast-yiq.js +13 -0
- package/utils/get-contrast-yiq.js.map +1 -0
- package/utils/hooks/use-screen-size.js +10 -0
- package/utils/hooks/use-screen-size.js.map +1 -0
- package/utils/i18n/constants/index.js +98 -0
- package/utils/i18n/constants/index.js.map +1 -0
- package/utils/i18n/helpers/locale-provider.js +9 -0
- package/utils/i18n/helpers/locale-provider.js.map +1 -0
- package/utils/i18n/helpers/to-smart-sentence-case.js +12 -0
- package/utils/i18n/helpers/to-smart-sentence-case.js.map +1 -0
- package/utils/i18n/helpers/to-smart-title-case.js +10 -0
- package/utils/i18n/helpers/to-smart-title-case.js.map +1 -0
- package/utils/i18n/helpers/use-locale.js +14 -0
- package/utils/i18n/helpers/use-locale.js.map +1 -0
- package/utils/i18n/index.js +41 -0
- package/utils/i18n/index.js.map +1 -0
- package/utils/i18n/index2.js +33 -0
- package/utils/i18n/index2.js.map +1 -0
- package/utils/index.js +7 -7
- package/utils/make-normalizer/index.js +34 -0
- package/utils/make-normalizer/index.js.map +1 -0
- package/{index-DBjAbGt7.js → utils/mds-context/index.js} +20 -19
- package/utils/mds-context/index.js.map +1 -0
- package/index-B9mPJh9w.js +0 -579
- package/index-B9mPJh9w.js.map +0 -1
- package/index-BHBlMMNF.js +0 -16
- package/index-BHBlMMNF.js.map +0 -1
- package/index-C4GBbW3N.js +0 -3567
- package/index-C4GBbW3N.js.map +0 -1
- package/index-DBjAbGt7.js.map +0 -1
- package/index-WkGIywHj.js +0 -767
- package/index-WkGIywHj.js.map +0 -1
- package/use-screen-size-BOnkX_K-.js +0 -9
- package/use-screen-size-BOnkX_K-.js.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Children as f } from "react";
|
|
2
|
+
function h(u) {
|
|
3
|
+
const i = f.toArray(u).map((e) => typeof e == "object" && "props" in e && e.props.className?.includes("empty-line") ? `
|
|
4
|
+
` : e);
|
|
5
|
+
return i.reduce(
|
|
6
|
+
(e, n, o) => {
|
|
7
|
+
const s = o === i.length - 1, t = n === `
|
|
8
|
+
`, r = n !== `
|
|
9
|
+
`;
|
|
10
|
+
t && e.consecutiveNewlines++;
|
|
11
|
+
const p = t && s, N = e.consecutiveNewlines > 0;
|
|
12
|
+
if ((r || p) && N) {
|
|
13
|
+
e.currentLine.length > 0 && (e.lines.push(e.currentLine), e.currentLine = []);
|
|
14
|
+
for (let l = 1; l < e.consecutiveNewlines; l++)
|
|
15
|
+
e.lines.push("");
|
|
16
|
+
e.consecutiveNewlines = 0;
|
|
17
|
+
}
|
|
18
|
+
return r && (e.currentLine.push(n), s && e.lines.push(e.currentLine)), e;
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
lines: [],
|
|
22
|
+
currentLine: [],
|
|
23
|
+
consecutiveNewlines: 1
|
|
24
|
+
// Start at 1 to handle leading newlines
|
|
25
|
+
}
|
|
26
|
+
).lines;
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
h as default
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=split-jsx-into-lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-jsx-into-lines.js","sources":["../../../../../src/components/code-block/code-lines/utils/split-jsx-into-lines.ts"],"sourcesContent":["import { Children, type ReactNode } from 'react'\n\n/**\n * Given an array of React children,\n * split the array on newlines, grouping consecutive\n * non-newline tokens in individual line elements,\n * and return an array of React <span> elements,\n * each of which will contain a single line.\n *\n * Note that JSX tokens should not be multi-line,\n * ie, all newline characters should be surfaced\n * to the top level rather than nested in syntax\n * highlighting tokens (otherwise the line-by-line\n * markup we render would be invalid). We have\n * a rehype plugin we include with our markdown defaults\n * to ensure newlines are surfaced in this way.\n *\n * @param {*} codeJsx Array of JSX elements, some of which may be newline strings\n * @returns Array of JSX <span> elements representing individual lines\n */\nfunction splitJsxIntoLines(codeJsx: React.ReactNode | React.ReactNode[]) {\n\tconst linesArray = Children.toArray(codeJsx)\n\t/**\n\t * Many newlines take the form of a literal newline string, `\\n`.\n\t * However, some newlines take different forms. We expect these to be tagged\n\t * with an `empty-line` className by our rehype code plugins.\n\t * Here we detect the latter types of newline, and convert them to the former.\n\t */\n\tconst withNormalizedNewlines = linesArray.map((token) => {\n\t\t// If our token has an `empty-line` className, use a literal newline\n\t\t// rather than the token itself (which would render, but with zero height)\n\t\tif (typeof token === 'object' && 'props' in token) {\n\t\t\tif (token.props.className?.includes('empty-line')) {\n\t\t\t\treturn '\\n'\n\t\t\t}\n\t\t}\n\t\t// Otherwise, return the token unmodified\n\t\treturn token\n\t})\n\t// Filter out any surfaces newlines, that are \"in between\"\n\t// other lines of code. Special exceptions should be made for:\n\t// 1. newlines at start or end of array - should be rendered as blank lines\n\t// 2. consecutive newlines - \"n\" consecutive newlines should be rendered\n\t// as \"n - 1\" blank lines.\n\tconst accumulatedLines = withNormalizedNewlines.reduce(\n\t\t(acc, token, idx) => {\n\t\t\tconst isLastLine = idx === withNormalizedNewlines.length - 1\n\t\t\tconst isNewline = token === '\\n'\n\t\t\tconst isInlineToken = token !== '\\n'\n\t\t\t// For newlines, increment the consecutive newline counter\n\t\t\tif (isNewline) acc.consecutiveNewlines++\n\t\t\t// If this token is an inline token, and we have\n\t\t\t// pending newlines, then start a new line,\n\t\t\t// adding blank lines for consecutive newlines as needed\n\t\t\tconst isFinalNewline = isNewline && isLastLine\n\t\t\tconst hasNewlines = acc.consecutiveNewlines > 0\n\t\t\tconst needsNewlines = (isInlineToken || isFinalNewline) && hasNewlines\n\t\t\tif (needsNewlines) {\n\t\t\t\t// If there are any tokens in the current line, add them as a new line\n\t\t\t\tif (acc.currentLine.length > 0) {\n\t\t\t\t\tacc.lines.push(acc.currentLine)\n\t\t\t\t\tacc.currentLine = []\n\t\t\t\t}\n\t\t\t\t// Add blank lines for each consecutive newline, then reset the counter\n\t\t\t\tfor (let i = 1; i < acc.consecutiveNewlines; i++) {\n\t\t\t\t\tacc.lines.push('')\n\t\t\t\t}\n\t\t\t\tacc.consecutiveNewlines = 0\n\t\t\t}\n\t\t\t// If this token is an inline token,\n\t\t\t// append it to the current line\n\t\t\tif (isInlineToken) {\n\t\t\t\tacc.currentLine.push(token)\n\t\t\t\t// If this is the last line,\n\t\t\t\t// then ensure the current line\n\t\t\t\t// has been pushed to the lines array\n\t\t\t\tif (isLastLine) acc.lines.push(acc.currentLine)\n\t\t\t}\n\t\t\treturn acc\n\t\t},\n\t\t{\n\t\t\tlines: [] as ReactNode[],\n\t\t\tcurrentLine: [] as ReactNode[],\n\t\t\tconsecutiveNewlines: 1, // Start at 1 to handle leading newlines\n\t\t}\n\t)\n\treturn accumulatedLines.lines\n}\n\nexport default splitJsxIntoLines\n"],"names":["splitJsxIntoLines","codeJsx","withNormalizedNewlines","Children","token","acc","idx","isLastLine","isNewline","isInlineToken","isFinalNewline","hasNewlines","i"],"mappings":";AAoBA,SAASA,EAAkBC,GAA8C;AAQxE,QAAMC,IAPaC,EAAS,QAAQF,CAAO,EAOD,IAAI,CAACG,MAG1C,OAAOA,KAAU,YAAY,WAAWA,KACvCA,EAAM,MAAM,WAAW,SAAS,YAAY,IACxC;AAAA,IAIFA,CACP;AAgDD,SA1CyBF,EAAuB;AAAA,IAC/C,CAACG,GAAKD,GAAOE,MAAQ;AACpB,YAAMC,IAAaD,MAAQJ,EAAuB,SAAS,GACrDM,IAAYJ,MAAU;AAAA,GACtBK,IAAgBL,MAAU;AAAA;AAEhC,MAAII,KAAWH,EAAI;AAInB,YAAMK,IAAiBF,KAAaD,GAC9BI,IAAcN,EAAI,sBAAsB;AAE9C,WADuBI,KAAiBC,MAAmBC,GACxC;AAElB,QAAIN,EAAI,YAAY,SAAS,MAC5BA,EAAI,MAAM,KAAKA,EAAI,WAAW,GAC9BA,EAAI,cAAc,CAAA;AAGnB,iBAASO,IAAI,GAAGA,IAAIP,EAAI,qBAAqBO;AAC5C,UAAAP,EAAI,MAAM,KAAK,EAAE;AAElB,QAAAA,EAAI,sBAAsB;AAAA,MAC3B;AAGA,aAAII,MACHJ,EAAI,YAAY,KAAKD,CAAK,GAItBG,KAAYF,EAAI,MAAM,KAAKA,EAAI,WAAW,IAExCA;AAAA,IACR;AAAA,IACA;AAAA,MACC,OAAO,CAAA;AAAA,MACP,aAAa,CAAA;AAAA,MACb,qBAAqB;AAAA;AAAA,IAAA;AAAA,EACtB,EAEuB;AACzB;"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as s, useState as i, useEffect as l } from "react";
|
|
4
|
+
const f = ({ code: e }, n) => {
|
|
5
|
+
const [r, o] = i(!1);
|
|
6
|
+
return l(() => {
|
|
7
|
+
o(!0);
|
|
8
|
+
}, []), r ? /* @__PURE__ */ t("pre", { ref: n, style: { display: "none" }, children: typeof e == "string" ? /* @__PURE__ */ t("span", { dangerouslySetInnerHTML: { __html: e } }) : e }) : null;
|
|
9
|
+
}, C = s(f);
|
|
10
|
+
export {
|
|
11
|
+
C as HiddenCopyContent
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/code-block/hidden-copy-content/index.tsx"],"sourcesContent":["'use client'\n\nimport { forwardRef, useEffect, useState, type ReactNode } from 'react'\n\n/**\n * This hidden element acts solely as a container\n * that we can fetch textContent to copy to clipboard.\n * This allows to ignore the \"how will we copy this cleanly\"\n * concern when splitting code into lines, and adding\n * line numbers and so on in other parts of code-block.\n */\nconst HiddenCopyContentComponent = (\n\t{ code }: { code: ReactNode },\n\tcopyRef: React.ForwardedRef<HTMLPreElement>\n) => {\n\tconst [isClient, setIsClient] = useState(false)\n\n\tuseEffect(() => {\n\t\tsetIsClient(true)\n\t}, [])\n\n\t/**\n\t * We are avoiding SSR here as this component is only used for the copy-to-clipboard interaction, and so rendering\n\t * the text content of the code introduces duplicate markup and some difficult-to-debug hydration mismatches.\n\t * By the time someone interacts with the copy-to-clipboard functionality, this should be rendered.\n\t */\n\tif (!isClient) return null\n\n\treturn (\n\t\t<pre ref={copyRef} style={{ display: 'none' }}>\n\t\t\t{typeof code === 'string' ? (\n\t\t\t\t<span dangerouslySetInnerHTML={{ __html: code }} />\n\t\t\t) : (\n\t\t\t\tcode\n\t\t\t)}\n\t\t</pre>\n\t)\n}\n\nconst HiddenCopyContent = forwardRef(HiddenCopyContentComponent)\n\nexport { HiddenCopyContent }\n"],"names":["HiddenCopyContentComponent","code","copyRef","isClient","setIsClient","useState","useEffect","jsx"],"mappings":";;;AAeC,MAAAA,IAAgC,CAAA,EAAA,MAAAC,EAAS,GAAAC,MAAK;AAE9C,QAAA,CAAAC,GAAgBC,CAAA,IAAAC,EAAA,EAAA;AAWhB,SAVCC,EAAA,MAAY;AACb,IAAAF,EAAK,EAAA;AAAA,EAOL,GAAA,CAAI,CAAC,OAWN,gBAAAG,EAAA,OAAA,EAAA,KAAAL,GAAA,OAAA,EAAA,SAAA,OAAA,GAAA,UAAA,OAAAD,KAAA,WAAA,gBAAAM,EAAA,QAAA,EAAA,yBAAA,EAAA,QAAAN,EAAA,EAAA,CAAA,IAAAA,EAAA,CAAA;AAEA;"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as t, jsx as o } from "react/jsx-runtime";
|
|
3
|
+
import { useRef as h, useId as x } from "react";
|
|
4
|
+
import N from "classnames";
|
|
5
|
+
import { Text as a } from "../text/index.js";
|
|
6
|
+
import { CodeLines as b } from "./code-lines/index.js";
|
|
7
|
+
import { HiddenCopyContent as k } from "./hidden-copy-content/index.js";
|
|
8
|
+
import B from "./utils/process-snippet.js";
|
|
9
|
+
import { CopyButton as g } from "../../patterns/copy-button/index.js";
|
|
10
|
+
import e from "./code-block.module.scss.js";
|
|
11
|
+
const w = ({
|
|
12
|
+
title: r,
|
|
13
|
+
description: s,
|
|
14
|
+
language: c,
|
|
15
|
+
value: i,
|
|
16
|
+
isStandalone: p = !0,
|
|
17
|
+
hasCopyButton: f,
|
|
18
|
+
hasLineNumbers: n = !0,
|
|
19
|
+
highlightLines: u,
|
|
20
|
+
maxHeight: y = "auto",
|
|
21
|
+
className: C
|
|
22
|
+
}) => {
|
|
23
|
+
const d = h(null), l = x();
|
|
24
|
+
return /* @__PURE__ */ t(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
className: N(
|
|
28
|
+
e["code-block"],
|
|
29
|
+
e.dark,
|
|
30
|
+
{
|
|
31
|
+
[e[`language-${c}`]]: c,
|
|
32
|
+
[e["is-standalone"]]: p,
|
|
33
|
+
[e["line-numbers"]]: n
|
|
34
|
+
},
|
|
35
|
+
C
|
|
36
|
+
),
|
|
37
|
+
children: [
|
|
38
|
+
/* @__PURE__ */ t("div", { className: e.header, children: [
|
|
39
|
+
r && /* @__PURE__ */ o(
|
|
40
|
+
a.HDSBody,
|
|
41
|
+
{
|
|
42
|
+
size: "200",
|
|
43
|
+
tag: "p",
|
|
44
|
+
weight: "semibold",
|
|
45
|
+
className: e.title,
|
|
46
|
+
children: r
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
s && /* @__PURE__ */ o(a.HDSBody, { tag: "p", size: "100", className: e.description, children: s })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ t("div", { className: e.body, children: [
|
|
52
|
+
/* @__PURE__ */ o(k, { code: i, ref: d }),
|
|
53
|
+
/* @__PURE__ */ o("pre", { className: e.code, id: l, style: { maxHeight: y }, children: /* @__PURE__ */ o("code", { children: /* @__PURE__ */ o(
|
|
54
|
+
b,
|
|
55
|
+
{
|
|
56
|
+
value: i,
|
|
57
|
+
highlightLines: u,
|
|
58
|
+
hasLineNumbers: n
|
|
59
|
+
}
|
|
60
|
+
) }) }),
|
|
61
|
+
f && /* @__PURE__ */ o(
|
|
62
|
+
g,
|
|
63
|
+
{
|
|
64
|
+
className: e["copy-button"],
|
|
65
|
+
"aria-describedby": l,
|
|
66
|
+
getTextFn: () => {
|
|
67
|
+
const m = d.current?.textContent;
|
|
68
|
+
if (!m)
|
|
69
|
+
throw new Error(
|
|
70
|
+
"`code-block` - Couldn't find text content to copy."
|
|
71
|
+
);
|
|
72
|
+
return B(m);
|
|
73
|
+
},
|
|
74
|
+
text: "Copy",
|
|
75
|
+
isIconOnly: !0,
|
|
76
|
+
size: "small"
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
] })
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
w.displayName = "CodeBlock";
|
|
85
|
+
export {
|
|
86
|
+
w as CodeBlock
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/code-block/index.tsx"],"sourcesContent":["'use client'\n\nimport { useId, useRef, type ReactNode } from 'react'\nimport classNames from 'classnames'\nimport { Text } from '../text'\nimport { CodeLines } from './code-lines'\nimport { HiddenCopyContent } from './hidden-copy-content'\nimport processSnippet from './utils/process-snippet'\nimport { CopyButton } from '../../patterns/copy-button'\nimport s from './code-block.module.scss'\n\n/**\n * ALERT: This component is a combination of logic from the official HashiCorp\n * Design System CodeBlock component and the CodeBlock component written by the\n * Web Presence Team. The official component relies on client-side rendering\n * for the calculation of line-heights for line numbers, but this is something\n * we want to be able to achieve without client-side rendering.\n */\n\ninterface CodeBlockProps {\n\t/**\n\t * The text/code content for the CodeBlock. The component encodes this\n\t * argument before displaying it. Should be a pre-highlighted string\n\t * generated by Prism.js or Shiki.\n\t */\n\tvalue: ReactNode\n\n\t/**\n\t * The coding language to use for syntax highlighting. If you need\n\t * additional languages contact the Design Systems Team.\n\t */\n\tlanguage?: string\n\n\t/**\n\t * Applies rounded borders to the component. When used within another\n\t * component or when the context requires it, you can turn it off.\n\t */\n\tisStandalone?: boolean\n\n\t/**\n\t * Used to control whether a copy button for copying the code/text content\n\t * will be displayed.\n\t */\n\thasCopyButton?: boolean\n\n\t/**\n\t * Used to control display of line numbers.\n\t */\n\thasLineNumbers?: boolean\n\n\t/**\n\t * Accepts a list or range of line numbers to highlight.\n\t * (Examples: `2, 4`,`6-10`)\n\t */\n\thighlightLines?: string\n\n\t/**\n\t * Accepts any valid CSS unit. If the CodeBlock content exceeds the maximum\n\t * height a vertical scrollbar is enabled. This value applies to the code\n\t * content only and does not include the header element (title and/or description).\n\t */\n\tmaxHeight?: string\n\ttitle?: ReactNode\n\tdescription?: ReactNode\n\tclassName?: string\n}\n\nconst CodeBlock = ({\n\ttitle,\n\tdescription,\n\tlanguage,\n\tvalue,\n\tisStandalone = true,\n\thasCopyButton,\n\thasLineNumbers = true,\n\thighlightLines,\n\tmaxHeight = 'auto',\n\tclassName,\n}: CodeBlockProps) => {\n\tconst copyRef = useRef<HTMLPreElement>(null)\n\tconst preCodeId = useId()\n\n\treturn (\n\t\t<div\n\t\t\tclassName={classNames(\n\t\t\t\ts['code-block'],\n\t\t\t\ts.dark,\n\t\t\t\t{\n\t\t\t\t\t[s[`language-${language}`]]: language,\n\t\t\t\t\t[s['is-standalone']]: isStandalone,\n\t\t\t\t\t[s['line-numbers']]: hasLineNumbers,\n\t\t\t\t},\n\t\t\t\tclassName\n\t\t\t)}\n\t\t>\n\t\t\t<div className={s.header}>\n\t\t\t\t{title && (\n\t\t\t\t\t<Text.HDSBody\n\t\t\t\t\t\tsize=\"200\"\n\t\t\t\t\t\ttag=\"p\"\n\t\t\t\t\t\tweight=\"semibold\"\n\t\t\t\t\t\tclassName={s.title}\n\t\t\t\t\t>\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</Text.HDSBody>\n\t\t\t\t)}\n\t\t\t\t{description && (\n\t\t\t\t\t<Text.HDSBody tag=\"p\" size=\"100\" className={s.description}>\n\t\t\t\t\t\t{description}\n\t\t\t\t\t</Text.HDSBody>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<div className={s.body}>\n\t\t\t\t{/**\n\t\t\t\t * NOTE: ideally we'd keep the markup of this component in lockstep\n\t\t\t\t * with the markup of the Helios code block. However, we also need\n\t\t\t\t * to support \"clever\" copying of snippets, parsing out shell\n\t\t\t\t * prompt characters like `$` from output, as this is a common\n\t\t\t\t * practice in our tutorial and documentation content. So, this\n\t\t\t\t * HiddenCopyContent component is one divergence from the markup\n\t\t\t\t * of the Helios code block.\n\t\t\t\t */}\n\t\t\t\t<HiddenCopyContent code={value} ref={copyRef} />\n\t\t\t\t<pre className={s.code} id={preCodeId} style={{ maxHeight }}>\n\t\t\t\t\t<code>\n\t\t\t\t\t\t<CodeLines\n\t\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\t\thighlightLines={highlightLines}\n\t\t\t\t\t\t\thasLineNumbers={hasLineNumbers}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</code>\n\t\t\t\t</pre>\n\t\t\t\t{hasCopyButton && (\n\t\t\t\t\t<CopyButton\n\t\t\t\t\t\tclassName={s['copy-button']}\n\t\t\t\t\t\taria-describedby={preCodeId}\n\t\t\t\t\t\tgetTextFn={() => {\n\t\t\t\t\t\t\tconst rawSnippet = copyRef.current?.textContent\n\t\t\t\t\t\t\tif (!rawSnippet) {\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t\"`code-block` - Couldn't find text content to copy.\"\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn processSnippet(rawSnippet)\n\t\t\t\t\t\t}}\n\t\t\t\t\t\ttext=\"Copy\"\n\t\t\t\t\t\tisIconOnly\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nCodeBlock.displayName = 'CodeBlock'\n\nexport type { CodeBlockProps }\nexport { CodeBlock }\n"],"names":["CodeBlock","title","description","language","value","isStandalone","hasCopyButton","hasLineNumbers","highlightLines","maxHeight","className","copyRef","jsxs","classNames","s","jsx","Text","HiddenCopyContent","preCodeId","CodeLines","CopyButton","rawSnippet","processSnippet"],"mappings":";;;;;;;;;;AAmEmB,MAClBA,IAAA,CAAA;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC,IAAA;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC,IAAA;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC,IAAA;AAAA,EACD,WAAAC;AACC;AACA,QAAMC,MAAY,IAAM,SAGvB;AAAA,SAAC,gBAAAC;AAAA,IAAA;AAAA,IAAA;AAAA,MACW,WACRC;AAAA,QACFC,EAAE,YAAA;AAAA,QACFA,EAAA;AAAA,QAAA;AAAA,UAEC,CAACA,EAAE,YAAAX,CAAmB,EAAA,CAAA,GAAAA;AAAA,UACtB,CAACW,EAAE,eAAe,CAAA,GAAGT;AAAA,UACtB,CAAAS,EAAA,cAAA,CAAA,GAAAP;AAAA,QACA;AAAA,QACDG;AAAA,MAEA;AAAA,MAAA,UAAA;AAAA,iCAEE,EAAA,WAAAI,EAAA,QAAA,UAAA;AAAA,UAAAb,KAAM,gBAAAc;AAAA,YAALC,EAAA;AAAA,YAAA;AAAA,cAEA,MAAI;AAAA,cACJ,KAAA;AAAA,cACA,QAAA;AAAA,cAEC,WAAAF,EAAA;AAAA,cAAA,UAAAb;AAAA,YACF;AAAA,UAEA;AAAA,eAKF,gBAAAc,EAAAC,EAAA,SAAA,EAAA,KAAA,KAAA,MAAA,OAAA,WAAAF,EAAA,aAAA,UAAAZ,EAAA,CAAA;AAAA,QAAA,EAAA,CAAA;AAAA,QAWC,gBAAAU,EAAA,OAAC,EAAA,WAAAE,EAAkB,MAAM,UAAO;AAAA,UAChC,gBAAAC,EAACE,GAAI,EAAW,MAAEb,GAAU,KAAAO,EAAW,CAAA;AAAA,UAEpC,gBAAAI,EAAA,OAAA,EAAA,WAAAD,EAAA,MAAA,IAAAI,GAAA,OAAA,EAAA,WAAAT,EAAA,GAAA,UAAA,gBAAAM,EAAA,QAAA,EAAA,UAAA,gBAAAA;AAAA,YAAAI;AAAA,YAAA;AAAA,cAEA,OAAAf;AAAA,cACA,gBAAAI;AAAA,cAAA,gBAAAD;AAAA;UAIF,EAAA,CAAA,EAAA,CAAA;AAAA,UACAD,KAAC,gBAAAS;AAAA,YAAAK;AAAA,YAAA;AAAA,cAEA,WAAAN,EAAA,aAAkB;AAAA,cAClB,oBAAiBI;AAAA,cAChB,WAAM,MAAA;AACN,sBAAKG,IAAYV,EAAA,SAAA;AAChB,oBAAA,CAAAU;AAAU,wBACT,IAAA;AAAA,oBACD;AAAA,kBACD;AAED,uBAAAC,EAAAD,CAAA;AAAA,cACA;AAAA,cACA,MAAA;AAAA,cACA,YAAK;AAAA,cAAA,MAAA;AAAA,YAAA;AAAA,UACN;AAAA,QAEF,EAAA,CAAA;AAAA,MAAA;AAAA,IACD;AAAA,EAEF;AAEA;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function g(e) {
|
|
2
|
+
if (typeof e > "u" || e === !1 || e === "")
|
|
3
|
+
return [];
|
|
4
|
+
if (typeof e != "string")
|
|
5
|
+
throw new Error(
|
|
6
|
+
`The highlight prop must be a string. Received a value of type "${typeof e}" instead.`
|
|
7
|
+
);
|
|
8
|
+
if (!/^[-,0-9\s]+$/.test(e))
|
|
9
|
+
throw new Error(
|
|
10
|
+
`The highlight prop must be a comma-separated list of single integers or ranges with a single dash between two integers. Found invalid characters: "${e}".`
|
|
11
|
+
);
|
|
12
|
+
return e.split(",").reduce((t, r) => t.concat(i(r)), []);
|
|
13
|
+
}
|
|
14
|
+
function i(e) {
|
|
15
|
+
const s = e.split("-");
|
|
16
|
+
if (s.length > 2)
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a value with multiple dashes: "${e}".`
|
|
19
|
+
);
|
|
20
|
+
if (s.length == 1) {
|
|
21
|
+
const a = parseInt(e);
|
|
22
|
+
if (a !== a)
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a value that parsed to NaN: "${e === "" ? "<empty string>" : e}".`
|
|
25
|
+
);
|
|
26
|
+
return [a];
|
|
27
|
+
}
|
|
28
|
+
const [t, r] = s.map((a) => parseInt(a));
|
|
29
|
+
if (t !== t || r !== r)
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a range that produced a NaN: "${e}".`
|
|
32
|
+
);
|
|
33
|
+
const h = r - t + 1;
|
|
34
|
+
return [...Array(h).keys()].map((a) => a + t);
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
g as default
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=parse-highlighted-lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-highlighted-lines.js","sources":["../../../../src/components/code-block/utils/parse-highlighted-lines.ts"],"sourcesContent":["function parseHighlightedLines(string?: string | boolean) {\n\tif (typeof string == 'undefined' || string === false || string === '') {\n\t\treturn []\n\t}\n\n\tif (typeof string !== 'string') {\n\t\tthrow new Error(\n\t\t\t`The highlight prop must be a string. Received a value of type \"${typeof string}\" instead.`\n\t\t)\n\t}\n\n\tconst hasValidChars = /^[-,0-9\\s]+$/.test(string)\n\tif (!hasValidChars) {\n\t\tthrow new Error(\n\t\t\t`The highlight prop must be a comma-separated list of single integers or ranges with a single dash between two integers. Found invalid characters: \"${string}\".`\n\t\t)\n\t}\n\n\tconst parts = string.split(',')\n\treturn parts.reduce((acc, part) => {\n\t\treturn acc.concat(parsePart(part))\n\t}, [] as number[])\n}\n\nfunction parsePart(string: string): number[] {\n\tconst dashParts = string.split('-')\n\tif (dashParts.length > 2) {\n\t\tthrow new Error(\n\t\t\t`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a value with multiple dashes: \"${string}\".`\n\t\t)\n\t}\n\t// Single integers are easy, just parse and return\n\tconst isSingle = dashParts.length == 1\n\tif (isSingle) {\n\t\tconst parsedInt = parseInt(string)\n\t\tconst isNaN = parsedInt !== parsedInt\n\t\tif (isNaN) {\n\t\t\tthrow new Error(\n\t\t\t\t`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a value that parsed to NaN: \"${\n\t\t\t\t\tstring === '' ? '<empty string>' : string\n\t\t\t\t}\".`\n\t\t\t)\n\t\t}\n\t\treturn [parsedInt]\n\t}\n\t// Ranges require a little more logic\n\tconst [startVal, endVal] = dashParts.map((v) => parseInt(v))\n\tconst hasNaNStart = startVal !== startVal\n\tconst hasNaNEnd = endVal !== endVal\n\tif (hasNaNStart || hasNaNEnd) {\n\t\tthrow new Error(\n\t\t\t`Each comma-separated value in the highlight prop must be either a single integer, or a range with a single dash between two integers. Found a range that produced a NaN: \"${string}\".`\n\t\t)\n\t}\n\tconst length = endVal - startVal + 1\n\tconst values = [...Array(length).keys()].map((int) => int + startVal)\n\treturn values\n}\n\nexport default parseHighlightedLines\n"],"names":["parseHighlightedLines","string","acc","part","parsePart","dashParts","parsedInt","startVal","endVal","v","length","int"],"mappings":"AAAA,SAASA,EAAsBC,GAA2B;AACzD,MAAI,OAAOA,IAAU,OAAeA,MAAW,MAASA,MAAW;AAClE,WAAO,CAAA;AAGR,MAAI,OAAOA,KAAW;AACrB,UAAM,IAAI;AAAA,MACT,kEAAkE,OAAOA,CAAM;AAAA,IAAA;AAKjF,MAAI,CADkB,eAAe,KAAKA,CAAM;AAE/C,UAAM,IAAI;AAAA,MACT,sJAAsJA,CAAM;AAAA,IAAA;AAK9J,SADcA,EAAO,MAAM,GAAG,EACjB,OAAO,CAACC,GAAKC,MAClBD,EAAI,OAAOE,EAAUD,CAAI,CAAC,GAC/B,CAAA,CAAc;AAClB;AAEA,SAASC,EAAUH,GAA0B;AAC5C,QAAMI,IAAYJ,EAAO,MAAM,GAAG;AAClC,MAAII,EAAU,SAAS;AACtB,UAAM,IAAI;AAAA,MACT,8KAA8KJ,CAAM;AAAA,IAAA;AAKtL,MADiBI,EAAU,UAAU,GACvB;AACb,UAAMC,IAAY,SAASL,CAAM;AAEjC,QADcK,MAAcA;AAE3B,YAAM,IAAI;AAAA,QACT,4KACCL,MAAW,KAAK,mBAAmBA,CACpC;AAAA,MAAA;AAGF,WAAO,CAACK,CAAS;AAAA,EAClB;AAEA,QAAM,CAACC,GAAUC,CAAM,IAAIH,EAAU,IAAI,CAACI,MAAM,SAASA,CAAC,CAAC;AAG3D,MAFoBF,MAAaA,KACfC,MAAWA;AAE5B,UAAM,IAAI;AAAA,MACT,6KAA6KP,CAAM;AAAA,IAAA;AAGrL,QAAMS,IAASF,IAASD,IAAW;AAEnC,SADe,CAAC,GAAG,MAAMG,CAAM,EAAE,MAAM,EAAE,IAAI,CAACC,MAAQA,IAAMJ,CAAQ;AAErE;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { escape as l, split as o } from "./shellwords.js";
|
|
2
|
+
function m(t) {
|
|
3
|
+
return t.split(`
|
|
4
|
+
`)[0].startsWith("$ ") ? r(t) : t;
|
|
5
|
+
}
|
|
6
|
+
function r(t) {
|
|
7
|
+
const e = t.split(`
|
|
8
|
+
`), i = e[0];
|
|
9
|
+
if (i.endsWith("\\") || i.endsWith("EOF")) {
|
|
10
|
+
const n = l(t).replace("\\$\\", "");
|
|
11
|
+
return o(n).join(" ");
|
|
12
|
+
}
|
|
13
|
+
const s = /^\$ /;
|
|
14
|
+
return e.filter((n) => n.match(s)).map((n) => n.replace(s, "")).join(`
|
|
15
|
+
`);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
m as default
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=process-snippet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-snippet.js","sources":["../../../../src/components/code-block/utils/process-snippet.ts"],"sourcesContent":["/**\n * Copyright (c) HashiCorp, Inc.\n * SPDX-License-Identifier: MPL-2.0\n */\n\nimport { escape, split } from './shellwords'\n\n/**\n * Given a snippet of code,\n * process it based on the detected language,\n * returning a modified snippet that has is\n * more suited to direct execution.\n */\nfunction processSnippet(snippet: string): string {\n\tconst isShell = snippet.split('\\n')[0].startsWith('$ ')\n\treturn isShell ? parseShellSnippet(snippet) : snippet\n}\n\n/**\n * Given a snippet of shell code that begins with `$ `,\n * return the snippet with all non-executable shell-symbols removed\n */\nfunction parseShellSnippet(snippet: string): string {\n\tconst lines = snippet.split('\\n')\n\t/**\n\t * Handle multi-line snippets.\n\t *\n\t * TODO: ideally we would detect many multi-line commands throughout\n\t * a snippet. We could potentially build some complex string-based logic to\n\t * do this... but it might be more efficient and effective to instead\n\t * process the `code` passed to `HiddenCopyContent`:\n\t * - We have incoming highlighted HTML or JSX, so we might be able to use\n\t * the highlight token classes (eg \"shell-symbol\") to only copy commands.\n\t * - However, our highlighter currently doesn't distinguish between\n\t * \"commands\" and \"output\" tokens for the \"shell-session\" language...\n\t * So maybe complex string-based logic would be the way to go if\n\t * we want to support multiple multi-line commands in a single snippet?\n\t * - Or maybe just need to look into `shellwords` use here?\n\t * (Full disclosure, I didn't set it up, so am not familiar.\n\t * it seems like it could be part of some solution?)\n\t *\n\t * ref: https://github.com/jimmycuadra/shellwords (really light on docs)\n\t * ref: https://ruby-doc.org/stdlib-1.9.3/libdoc/shellwords/rdoc/Shellwords.html\n\t * (ruby module of same name, seems to have better docs)\n\t *\n\t * Related task:\n\t * https://app.asana.com/0/1100423001970639/1199504357822173/f\n\t *\n\t */\n\tconst firstLine = lines[0]\n\tconst isMultiLineCommand =\n\t\tfirstLine.endsWith('\\\\') || firstLine.endsWith('EOF')\n\tif (isMultiLineCommand) {\n\t\t/**\n\t\t * If this is a multi-line snippet, return it formatted with\n\t\t * shellwords escape & split\n\t\t */\n\t\tconst multiLineFmt = escape(snippet).replace('\\\\$\\\\', '')\n\t\treturn split(multiLineFmt).join(' ')\n\t}\n\t/**\n\t * Otherwise, we return only lines of the shell snippet that start with `$`.\n\t * We remove the `$ ` at the start of each line.\n\t * We lines that don't start with `$ ` - these are assumed to be output lines.\n\t */\n\tconst commandRegex = /^\\$ /\n\treturn lines\n\t\t.filter((line) => line.match(commandRegex))\n\t\t.map((line) => line.replace(commandRegex, ''))\n\t\t.join('\\n')\n}\n\nexport default processSnippet\n"],"names":["processSnippet","snippet","parseShellSnippet","lines","firstLine","multiLineFmt","escape","split","commandRegex","line"],"mappings":";AAaA,SAASA,EAAeC,GAAyB;AAEhD,SADgBA,EAAQ,MAAM;AAAA,CAAI,EAAE,CAAC,EAAE,WAAW,IAAI,IACrCC,EAAkBD,CAAO,IAAIA;AAC/C;AAMA,SAASC,EAAkBD,GAAyB;AACnD,QAAME,IAAQF,EAAQ,MAAM;AAAA,CAAI,GA0B1BG,IAAYD,EAAM,CAAC;AAGzB,MADCC,EAAU,SAAS,IAAI,KAAKA,EAAU,SAAS,KAAK,GAC7B;AAKvB,UAAMC,IAAeC,EAAOL,CAAO,EAAE,QAAQ,SAAS,EAAE;AACxD,WAAOM,EAAMF,CAAY,EAAE,KAAK,GAAG;AAAA,EACpC;AAMA,QAAMG,IAAe;AACrB,SAAOL,EACL,OAAO,CAACM,MAASA,EAAK,MAAMD,CAAY,CAAC,EACzC,IAAI,CAACC,MAASA,EAAK,QAAQD,GAAc,EAAE,CAAC,EAC5C,KAAK;AAAA,CAAI;AACZ;"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const f = (e, t, l) => {
|
|
2
|
+
let n = "";
|
|
3
|
+
for (; e.length > 0; ) {
|
|
4
|
+
const s = e.match(t);
|
|
5
|
+
s && s.index != null && s[0] != null ? (n += e.slice(0, s.index), n += l(s), e = e.slice(s.index + s[0].length)) : (n += e, e = "");
|
|
6
|
+
}
|
|
7
|
+
return n;
|
|
8
|
+
}, p = (e = "") => {
|
|
9
|
+
const t = [];
|
|
10
|
+
let l = "";
|
|
11
|
+
return f(
|
|
12
|
+
e,
|
|
13
|
+
/\s*(?:([^\s\\'"]+)|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)"|(\\.?)|(\S))(\s|$)?/,
|
|
14
|
+
(n) => {
|
|
15
|
+
const [s, a, r, o, i, u, d] = n;
|
|
16
|
+
if (u != null)
|
|
17
|
+
throw new Error(`Unmatched quote: ${e}`);
|
|
18
|
+
if (a)
|
|
19
|
+
l += a;
|
|
20
|
+
else {
|
|
21
|
+
let c;
|
|
22
|
+
r ? c = r : o ? c = o : i && (c = i), c && (l += c.replace(/\\(?=.)/, ""));
|
|
23
|
+
}
|
|
24
|
+
d != null && (t.push(l), l = "");
|
|
25
|
+
}
|
|
26
|
+
), l && t.push(l), t;
|
|
27
|
+
}, h = (e = "") => e.replace(/([^A-Za-z0-9_\-.,:/@\n])/g, "\\$1").replace(/\n/g, `'
|
|
28
|
+
'`);
|
|
29
|
+
export {
|
|
30
|
+
h as escape,
|
|
31
|
+
p as split
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=shellwords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shellwords.js","sources":["../../../../src/components/code-block/utils/shellwords.ts"],"sourcesContent":["const scan = (\n\tstring: string,\n\tpattern: RegExp,\n\tcallback: (match: RegExpMatchArray) => void\n) => {\n\tlet result = ''\n\n\twhile (string.length > 0) {\n\t\tconst match = string.match(pattern)\n\n\t\tif (match && match.index != null && match[0] != null) {\n\t\t\tresult += string.slice(0, match.index)\n\t\t\tresult += callback(match)\n\t\t\tstring = string.slice(match.index + match[0].length)\n\t\t} else {\n\t\t\tresult += string\n\t\t\tstring = ''\n\t\t}\n\t}\n\n\treturn result\n}\n\n/**\n * Splits a string into an array of tokens in the same way the UNIX Bourne shell does.\n *\n * @param line A string to split.\n * @returns An array of the split tokens.\n */\nexport const split = (line = '') => {\n\tconst words: string[] = []\n\tlet field = ''\n\tscan(\n\t\tline,\n\t\t/\\s*(?:([^\\s\\\\'\"]+)|'((?:[^'\\\\]|\\\\.)*)'|\"((?:[^\"\\\\]|\\\\.)*)\"|(\\\\.?)|(\\S))(\\s|$)?/,\n\t\t(match) => {\n\t\t\tconst [_raw, word, sq, dq, escape, garbage, separator] = match\n\n\t\t\tif (garbage != null) {\n\t\t\t\tthrow new Error(`Unmatched quote: ${line}`)\n\t\t\t}\n\n\t\t\tif (word) {\n\t\t\t\tfield += word\n\t\t\t} else {\n\t\t\t\tlet addition\n\n\t\t\t\tif (sq) {\n\t\t\t\t\taddition = sq\n\t\t\t\t} else if (dq) {\n\t\t\t\t\taddition = dq\n\t\t\t\t} else if (escape) {\n\t\t\t\t\taddition = escape\n\t\t\t\t}\n\n\t\t\t\tif (addition) {\n\t\t\t\t\tfield += addition.replace(/\\\\(?=.)/, '')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (separator != null) {\n\t\t\t\twords.push(field)\n\t\t\t\tfield = ''\n\t\t\t}\n\t\t}\n\t)\n\n\tif (field) {\n\t\twords.push(field)\n\t}\n\n\treturn words\n}\n\n/**\n * Escapes a string so that it can be safely used in a Bourne shell command line.\n *\n * @param str A string to escape.\n * @returns The escaped string.\n */\nexport const escape = (str = '') => {\n\treturn str.replace(/([^A-Za-z0-9_\\-.,:/@\\n])/g, '\\\\$1').replace(/\\n/g, \"'\\n'\")\n}\n"],"names":["scan","string","pattern","callback","result","match","split","line","words","field","_raw","word","sq","dq","escape","garbage","separator","addition","str"],"mappings":"AAAA,MAAMA,IAAO,CACZC,GACAC,GACAC,MACI;AACJ,MAAIC,IAAS;AAEb,SAAOH,EAAO,SAAS,KAAG;AACzB,UAAMI,IAAQJ,EAAO,MAAMC,CAAO;AAElC,IAAIG,KAASA,EAAM,SAAS,QAAQA,EAAM,CAAC,KAAK,QAC/CD,KAAUH,EAAO,MAAM,GAAGI,EAAM,KAAK,GACrCD,KAAUD,EAASE,CAAK,GACxBJ,IAASA,EAAO,MAAMI,EAAM,QAAQA,EAAM,CAAC,EAAE,MAAM,MAEnDD,KAAUH,GACVA,IAAS;AAAA,EAEX;AAEA,SAAOG;AACR,GAQaE,IAAQ,CAACC,IAAO,OAAO;AACnC,QAAMC,IAAkB,CAAA;AACxB,MAAIC,IAAQ;AACZ,SAAAT;AAAA,IACCO;AAAA,IACA;AAAA,IACA,CAACF,MAAU;AACV,YAAM,CAACK,GAAMC,GAAMC,GAAIC,GAAIC,GAAQC,GAASC,CAAS,IAAIX;AAEzD,UAAIU,KAAW;AACd,cAAM,IAAI,MAAM,oBAAoBR,CAAI,EAAE;AAG3C,UAAII;AACH,QAAAF,KAASE;AAAA,WACH;AACN,YAAIM;AAEJ,QAAIL,IACHK,IAAWL,IACDC,IACVI,IAAWJ,IACDC,MACVG,IAAWH,IAGRG,MACHR,KAASQ,EAAS,QAAQ,WAAW,EAAE;AAAA,MAEzC;AAEA,MAAID,KAAa,SAChBR,EAAM,KAAKC,CAAK,GAChBA,IAAQ;AAAA,IAEV;AAAA,EAAA,GAGGA,KACHD,EAAM,KAAKC,CAAK,GAGVD;AACR,GAQaM,IAAS,CAACI,IAAM,OACrBA,EAAI,QAAQ,6BAA6B,MAAM,EAAE,QAAQ,OAAO;AAAA,EAAM;"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as b, Fragment as X } from "react/jsx-runtime";
|
|
3
|
+
import { useId as F, useEffect as V, useRef as B, useState as R, useCallback as p, createContext as Y, useContext as Z } from "react";
|
|
4
|
+
import { TextInputBase as ee } from "../form/text-input/index.js";
|
|
5
|
+
const E = (s, t) => `${s}__${t}`, x = -1;
|
|
6
|
+
function te(s) {
|
|
7
|
+
const t = /* @__PURE__ */ new Map();
|
|
8
|
+
for (const [o, r] of Object.entries(s)) {
|
|
9
|
+
if (!r) continue;
|
|
10
|
+
const l = t.get(r) || [];
|
|
11
|
+
t.set(r, [...l, o]);
|
|
12
|
+
}
|
|
13
|
+
for (const [o, r] of t)
|
|
14
|
+
if (r.length > 1)
|
|
15
|
+
throw new Error(
|
|
16
|
+
`ComboBox: id '${o}' is duplicated in ${r.join(", ")}`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const U = Y(null), y = () => {
|
|
20
|
+
const s = Z(U);
|
|
21
|
+
if (!s)
|
|
22
|
+
throw new Error("useComboBox must be used within a ComboBoxProvider");
|
|
23
|
+
return s;
|
|
24
|
+
}, oe = ({
|
|
25
|
+
children: s,
|
|
26
|
+
keyboardFocusLoop: t = !0,
|
|
27
|
+
ids: o = {},
|
|
28
|
+
onChangeVFocusedOption: r,
|
|
29
|
+
onChangeSelectedOption: l
|
|
30
|
+
}) => {
|
|
31
|
+
te(o);
|
|
32
|
+
const n = B([]), c = B(/* @__PURE__ */ new Set()), [f, m] = R(null), [a, w] = R(x), h = B(null), u = B(null), [g, I] = R(!1), K = B(null), _ = E("hashi-combo-box-toggle", F()), j = E("hashi-combo-box-popover", F()), M = E("hashi-combo-box-listbox", F()), T = p(
|
|
33
|
+
(e) => {
|
|
34
|
+
m(e), l?.(e);
|
|
35
|
+
},
|
|
36
|
+
[l]
|
|
37
|
+
), v = p(
|
|
38
|
+
(e) => {
|
|
39
|
+
w(e), r?.(n.current[e]);
|
|
40
|
+
},
|
|
41
|
+
[r]
|
|
42
|
+
), q = B({
|
|
43
|
+
toggle: o.toggle ?? _,
|
|
44
|
+
popover: o.popover ?? j,
|
|
45
|
+
listbox: o.listbox ?? M
|
|
46
|
+
}), C = p(
|
|
47
|
+
(e) => {
|
|
48
|
+
v(e);
|
|
49
|
+
},
|
|
50
|
+
[v]
|
|
51
|
+
), A = p(() => {
|
|
52
|
+
const e = n.current;
|
|
53
|
+
if (a === x) return 0;
|
|
54
|
+
const i = a + 1, d = i >= e.length;
|
|
55
|
+
let k;
|
|
56
|
+
d && t ? (k = x, I(!1)) : k = d ? a : i, C(k);
|
|
57
|
+
}, [t, a, C]), D = p(() => {
|
|
58
|
+
if (a === x) return 0;
|
|
59
|
+
const e = a - 1, i = e < 0;
|
|
60
|
+
let d;
|
|
61
|
+
i && t ? (d = x, I(!1)) : d = i ? a : e, C(d);
|
|
62
|
+
}, [t, a, C]), W = p(
|
|
63
|
+
(e) => {
|
|
64
|
+
const i = n.current.findIndex((d) => d.id === e.id);
|
|
65
|
+
if (i === -1) {
|
|
66
|
+
console.error("ComboBox: Item not found", e);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
v(i);
|
|
70
|
+
},
|
|
71
|
+
[v]
|
|
72
|
+
), P = p(() => a === x ? null : n.current[a] || null, [a]), $ = p(
|
|
73
|
+
(e) => {
|
|
74
|
+
if (n.current.findIndex((d) => d.id === e.id) === -1) {
|
|
75
|
+
console.error(
|
|
76
|
+
"ComboBox: Item not found, Selected item not updated",
|
|
77
|
+
e
|
|
78
|
+
);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
T(e), I(!1);
|
|
82
|
+
},
|
|
83
|
+
[T]
|
|
84
|
+
), L = p(() => f, [f]), z = p((e) => {
|
|
85
|
+
if (c.current.has(e.id)) {
|
|
86
|
+
const i = n.current.find((S) => S.id === e.id), N = `Each ComboBox.Item must have a unique id.
|
|
87
|
+
Found items with duplicate ids: ${JSON.stringify({
|
|
88
|
+
existing: i,
|
|
89
|
+
attemptedToAdd: e
|
|
90
|
+
})}`;
|
|
91
|
+
throw Error(N);
|
|
92
|
+
}
|
|
93
|
+
c.current.add(e.id), n.current.push(e);
|
|
94
|
+
}, []), G = p(() => n.current, []), H = p((e) => {
|
|
95
|
+
c.current.delete(e.id), n.current = n.current.filter((i) => i.id !== e.id);
|
|
96
|
+
}, []);
|
|
97
|
+
V(() => {
|
|
98
|
+
g && u.current?.focus();
|
|
99
|
+
}, [g, u, h]), V(() => {
|
|
100
|
+
const e = P(), i = K.current;
|
|
101
|
+
e && i && i.querySelector(
|
|
102
|
+
`[data-combo-box-item-id="${e.id}"]`
|
|
103
|
+
)?.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
104
|
+
}, [P]);
|
|
105
|
+
const O = p(() => {
|
|
106
|
+
I(!1), v(x);
|
|
107
|
+
}, [v]), J = p(() => {
|
|
108
|
+
I(!0);
|
|
109
|
+
}, []), Q = (e) => {
|
|
110
|
+
const i = e.key === "ArrowDown" || e.key === "ArrowUp", d = e.key === " ", k = u.current !== null;
|
|
111
|
+
switch ((i || d && !k) && e.preventDefault(), e.key) {
|
|
112
|
+
case "Escape": {
|
|
113
|
+
O();
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "ArrowDown": {
|
|
117
|
+
const S = P() === null;
|
|
118
|
+
g && S ? C(0) : A();
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
case "ArrowUp": {
|
|
122
|
+
D();
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "Enter": {
|
|
126
|
+
const S = P();
|
|
127
|
+
S && $(S), O();
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return /* @__PURE__ */ b(
|
|
133
|
+
U.Provider,
|
|
134
|
+
{
|
|
135
|
+
value: {
|
|
136
|
+
addItem: z,
|
|
137
|
+
selectItem: $,
|
|
138
|
+
vFocus: W,
|
|
139
|
+
vFocusByIdx: C,
|
|
140
|
+
vFocusNext: A,
|
|
141
|
+
vFocusPrev: D,
|
|
142
|
+
getSelectedItem: L,
|
|
143
|
+
getVFocusedItem: P,
|
|
144
|
+
getItems: G,
|
|
145
|
+
removeItem: H,
|
|
146
|
+
searchInputRef: u,
|
|
147
|
+
toggleRef: h,
|
|
148
|
+
listRef: K,
|
|
149
|
+
isOpen: g,
|
|
150
|
+
closePopover: O,
|
|
151
|
+
openPopover: J,
|
|
152
|
+
ids: q,
|
|
153
|
+
handleVFocusKeyboardControls: Q
|
|
154
|
+
},
|
|
155
|
+
children: s
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
}, ne = ({
|
|
159
|
+
id: s,
|
|
160
|
+
value: t,
|
|
161
|
+
label: o,
|
|
162
|
+
children: r,
|
|
163
|
+
...l
|
|
164
|
+
}) => {
|
|
165
|
+
const n = E("hashi-combo-box-item", F()), c = s ?? n, { addItem: f, removeItem: m, getVFocusedItem: a, vFocus: w, selectItem: h } = y();
|
|
166
|
+
V(() => (f({ id: c, value: t, label: o }), () => m({ id: c, value: t, label: o })), [f, c, m, t, o]);
|
|
167
|
+
const u = a()?.id === c;
|
|
168
|
+
return /* @__PURE__ */ b(
|
|
169
|
+
"li",
|
|
170
|
+
{
|
|
171
|
+
"data-combo-box-item-id": c,
|
|
172
|
+
role: "option",
|
|
173
|
+
"aria-selected": u,
|
|
174
|
+
"data-vfocused": u,
|
|
175
|
+
onClick: () => h({ id: c, value: t, label: o }),
|
|
176
|
+
onMouseEnter: () => w({ id: c, value: t, label: o }),
|
|
177
|
+
...l,
|
|
178
|
+
children: r
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}, se = ({ children: s, className: t }) => {
|
|
182
|
+
const {
|
|
183
|
+
toggleRef: o,
|
|
184
|
+
openPopover: r,
|
|
185
|
+
closePopover: l,
|
|
186
|
+
isOpen: n,
|
|
187
|
+
ids: c,
|
|
188
|
+
handleVFocusKeyboardControls: f,
|
|
189
|
+
searchInputRef: m
|
|
190
|
+
} = y(), a = (u) => {
|
|
191
|
+
u.stopPropagation(), n ? l() : r();
|
|
192
|
+
}, w = (u) => {
|
|
193
|
+
if ((u.key === "Enter" || u.key === "ArrowDown" || u.key === " ") && n === !1) {
|
|
194
|
+
u.preventDefault(), r();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
!(m.current !== null) && n && f(u);
|
|
198
|
+
}, h = () => (u) => {
|
|
199
|
+
if (u.relatedTarget?.closest("[data-combo-box-popover]")) return;
|
|
200
|
+
m.current !== null || l();
|
|
201
|
+
};
|
|
202
|
+
return /* @__PURE__ */ b(
|
|
203
|
+
"div",
|
|
204
|
+
{
|
|
205
|
+
role: "combobox",
|
|
206
|
+
onClick: a,
|
|
207
|
+
onKeyDown: w,
|
|
208
|
+
tabIndex: 0,
|
|
209
|
+
ref: o,
|
|
210
|
+
"aria-haspopup": "listbox",
|
|
211
|
+
"aria-expanded": n,
|
|
212
|
+
"aria-controls": c.current.popover,
|
|
213
|
+
className: t,
|
|
214
|
+
onBlur: h(),
|
|
215
|
+
children: s
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
}, re = ({
|
|
219
|
+
placeholder: s = "Select an option"
|
|
220
|
+
}) => {
|
|
221
|
+
const { getSelectedItem: t } = y();
|
|
222
|
+
return /* @__PURE__ */ b(X, { children: t()?.label ?? s });
|
|
223
|
+
}, ce = ({ children: s, className: t }) => {
|
|
224
|
+
const { isOpen: o, ids: r, closePopover: l } = y();
|
|
225
|
+
return V(() => {
|
|
226
|
+
const n = (c) => {
|
|
227
|
+
!o || c.target.closest("[data-combo-box-popover]") || l();
|
|
228
|
+
};
|
|
229
|
+
return document.addEventListener("click", n), () => {
|
|
230
|
+
document.removeEventListener("click", n);
|
|
231
|
+
};
|
|
232
|
+
}, [o, l]), o ? /* @__PURE__ */ b("div", { id: r.current.popover, "data-combo-box-popover": !0, className: t, children: s }) : null;
|
|
233
|
+
}, ie = ({
|
|
234
|
+
label: s,
|
|
235
|
+
children: t,
|
|
236
|
+
className: o = "",
|
|
237
|
+
maxHeight: r,
|
|
238
|
+
onScroll: l
|
|
239
|
+
}) => {
|
|
240
|
+
const { ids: n, listRef: c } = y();
|
|
241
|
+
return /* @__PURE__ */ b(
|
|
242
|
+
"ul",
|
|
243
|
+
{
|
|
244
|
+
id: n.current.listbox,
|
|
245
|
+
"aria-label": s,
|
|
246
|
+
role: "listbox",
|
|
247
|
+
tabIndex: -1,
|
|
248
|
+
ref: c,
|
|
249
|
+
className: o,
|
|
250
|
+
style: { maxHeight: r },
|
|
251
|
+
onScroll: l,
|
|
252
|
+
children: t
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
}, ue = ({
|
|
256
|
+
placeholder: s = "Search",
|
|
257
|
+
value: t,
|
|
258
|
+
onChange: o,
|
|
259
|
+
onBlur: r
|
|
260
|
+
}) => {
|
|
261
|
+
const {
|
|
262
|
+
searchInputRef: l,
|
|
263
|
+
getVFocusedItem: n,
|
|
264
|
+
handleVFocusKeyboardControls: c,
|
|
265
|
+
closePopover: f
|
|
266
|
+
} = y();
|
|
267
|
+
return /* @__PURE__ */ b(
|
|
268
|
+
ee,
|
|
269
|
+
{
|
|
270
|
+
field: {
|
|
271
|
+
type: "search",
|
|
272
|
+
ref: l,
|
|
273
|
+
autoComplete: "off",
|
|
274
|
+
"aria-haspopup": "listbox",
|
|
275
|
+
"aria-autocomplete": "list",
|
|
276
|
+
role: "combobox",
|
|
277
|
+
"aria-activedescendant": n()?.id ?? "",
|
|
278
|
+
placeholder: s,
|
|
279
|
+
value: t,
|
|
280
|
+
onChange: o,
|
|
281
|
+
onKeyDown: c,
|
|
282
|
+
onBlur: (m) => {
|
|
283
|
+
m.stopPropagation(), !m.relatedTarget?.closest(
|
|
284
|
+
"[data-combo-box-popover]"
|
|
285
|
+
) && (f(), r?.());
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
}, pe = Object.freeze({
|
|
291
|
+
Root: oe,
|
|
292
|
+
Trigger: se,
|
|
293
|
+
Popover: ce,
|
|
294
|
+
SearchInput: ue,
|
|
295
|
+
List: ie,
|
|
296
|
+
Item: ne,
|
|
297
|
+
Value: re
|
|
298
|
+
});
|
|
299
|
+
export {
|
|
300
|
+
pe as ComboBox
|
|
301
|
+
};
|
|
302
|
+
//# sourceMappingURL=index.js.map
|