1 var __defProp = Object.defineProperty;
2 var __defProps = Object.defineProperties;
3 var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4 var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5 var __hasOwnProp = Object.prototype.hasOwnProperty;
6 var __propIsEnum = Object.prototype.propertyIsEnumerable;
7 var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8 var __spreadValues = (a, b) => {
9 for (var prop in b || (b = {}))
10 if (__hasOwnProp.call(b, prop))
11 __defNormalProp(a, prop, b[prop]);
12 if (__getOwnPropSymbols)
13 for (var prop of __getOwnPropSymbols(b)) {
14 if (__propIsEnum.call(b, prop))
15 __defNormalProp(a, prop, b[prop]);
19 var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20 var __objRest = (source, exclude) => {
22 for (var prop in source)
23 if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24 target[prop] = source[prop];
25 if (source != null && __getOwnPropSymbols)
26 for (var prop of __getOwnPropSymbols(source)) {
27 if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28 target[prop] = source[prop];
32 var __publicField = (obj, key, value) => {
33 __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
36 var __async = (__this, __arguments, generator) => {
37 return new Promise((resolve, reject) => {
38 var fulfilled = (value) => {
40 step(generator.next(value));
45 var rejected = (value) => {
47 step(generator.throw(value));
52 var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
53 step((generator = generator.apply(__this, __arguments)).next());
56 import { ref, onMounted, defineComponent, computed, openBlock, createElementBlock, normalizeClass, toDisplayString, createCommentVNode, Comment, warn, watch, withKeys, withModifiers, renderSlot, resolveComponent, createElementVNode, createBlock, resolveDynamicComponent, withCtx, createVNode, toRef, Fragment, renderList, createTextVNode, Transition, normalizeStyle, inject, mergeProps, getCurrentInstance, withDirectives, vModelCheckbox, createSlots, nextTick, vModelDynamic, onUnmounted, toHandlers, vShow, unref, shallowRef, getCurrentScope, onScopeDispose, shallowReadonly, Teleport, toRefs, provide, vModelRadio, vModelText } from "vue";
57 const g = '<path d="M11.53 2.3A1.85 1.85 0 0010 1.21 1.85 1.85 0 008.48 2.3L.36 16.36C-.48 17.81.21 19 1.88 19h16.24c1.67 0 2.36-1.19 1.52-2.64zM11 16H9v-2h2zm0-4H9V6h2z"/>', q = '<path d="M12.43 14.34A5 5 0 0110 15a5 5 0 113.95-2L17 16.09V3a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h10a2 2 0 001.45-.63z"/><circle cx="10" cy="10" r="3"/>', s1 = '<path d="M7 14.17 2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z"/>', n1 = '<path d="M10 0a10 10 0 1010 10A10 10 0 0010 0m5.66 14.24-1.41 1.41L10 11.41l-4.24 4.25-1.42-1.42L8.59 10 4.34 5.76l1.42-1.42L10 8.59l4.24-4.24 1.41 1.41L11.41 10z"/>', d1 = '<path d="m4.34 2.93 12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34 4.34 17.07l-1.41-1.41L15.66 2.93z"/>', g1 = '<path d="M10 15 2 5h16z"/>', k1 = '<path d="M13.728 1H6.272L1 6.272v7.456L6.272 19h7.456L19 13.728V6.272zM11 15H9v-2h2zm0-4H9V5h2z"/>', F1 = '<path d="m17.5 4.75-7.5 7.5-7.5-7.5L1 6.25l9 9 9-9z"/>', t0 = '<path d="M19 3H1v14h18zM3 14l3.5-4.5 2.5 3L12.5 8l4.5 6z"/><path d="M19 5H1V3h18zm0 12H1v-2h18z"/>', p = '<path d="M8 19a1 1 0 001 1h2a1 1 0 001-1v-1H8zm9-12a7 7 0 10-12 4.9S7 14 7 15v1a1 1 0 001 1h4a1 1 0 001-1v-1c0-1 2-3.1 2-3.1A7 7 0 0017 7"/>', e0 = '<path d="M10 0C4.477 0 0 4.477 0 10s4.477 10 10 10 10-4.477 10-10S15.523 0 10 0M9 5h2v2H9zm0 4h2v6H9z"/>', z2 = '<path d="M3 1h2v18H3zm13.5 1.5L15 1l-9 9 9 9 1.5-1.5L9 10z"/>', i2 = '<path d="M15 1h2v18h-2zM3.5 2.5 11 10l-7.5 7.5L5 19l9-9-9-9z"/>', V2 = '<path d="M7 1 5.6 2.5 13 10l-7.4 7.5L7 19l9-9z"/>', b2 = '<path d="m4 10 9 9 1.4-1.5L7 10l7.4-7.5L13 1z"/>', Y2 = '<path d="M12.2 13.6a7 7 0 111.4-1.4l5.4 5.4-1.4 1.4zM3 8a5 5 0 1010 0A5 5 0 003 8"/>', o5 = '<path d="M10 0 3 8h14zm0 18-7-8h14z"/>', H5 = '<path d="M10 20a10 10 0 010-20 10 10 0 110 20m-2-5 9-8.5L15.5 5 8 12 4.5 8.5 3 10z"/>', K5 = '<path d="m10 5 8 10H2z"/>', H3 = g, b3 = q, J3 = s1, j3 = n1, _3 = d1, n4 = g1, p4 = k1, M4 = F1, N4 = t0, j4 = {
74 }, k7 = Y2, Z7 = o5, G7 = H5, u8 = K5;
75 function Q8(c, s, h) {
76 if (typeof c == "string" || "path" in c)
78 if ("shouldFlip" in c)
81 return h === "rtl" ? c.rtl : c.ltr;
82 const n = s in c.langCodeMap ? c.langCodeMap[s] : c.default;
83 return typeof n == "string" || "path" in n ? n : n.ltr;
86 if (typeof c == "string")
88 if ("langCodeMap" in c) {
89 const h = s in c.langCodeMap ? c.langCodeMap[s] : c.default;
90 if (typeof h == "string")
94 if ("shouldFlipExceptions" in c && Array.isArray(c.shouldFlipExceptions)) {
95 const h = c.shouldFlipExceptions.indexOf(s);
96 return h === void 0 || h === -1;
98 return "shouldFlip" in c ? c.shouldFlip : false;
100 function useComputedDirection(root) {
101 const computedDir = ref(null);
103 const dir = window.getComputedStyle(root.value).direction;
104 computedDir.value = dir === "ltr" || dir === "rtl" ? dir : null;
108 function useComputedLanguage(root) {
109 const computedLang = ref("");
111 let ancestor = root.value;
112 while (ancestor && ancestor.lang === "") {
113 ancestor = ancestor.parentElement;
115 computedLang.value = ancestor ? ancestor.lang : null;
119 function makeStringTypeValidator(allowedValues) {
120 return (s) => typeof s === "string" && allowedValues.indexOf(s) !== -1;
122 const LibraryPrefix = "cdx";
123 const ButtonActions = [
128 const ButtonWeights = [
133 const ButtonSizes = [
142 const StatusTypes = [
148 const statusTypeValidator = makeStringTypeValidator(StatusTypes);
149 const TextInputTypes = [
163 const ValidationStatusTypes = [
169 const TableTextAlignments = [
173 // Numbers should be aligned to the right in all reading directionalities.
176 const DebounceInterval = 120;
177 const PendingDelay = 500;
178 const MenuFooterValue = "cdx-menu-footer-item";
179 const TabsKey = Symbol("CdxTabs");
180 const ActiveTabKey = Symbol("CdxActiveTab");
181 const AllowArbitraryKey = Symbol("CdxAllowArbitrary");
182 const FieldInputIdKey = Symbol("CdxFieldInputId");
183 const FieldDescriptionIdKey = Symbol("CdxFieldDescriptionId");
184 const FieldStatusKey = Symbol("CdxFieldStatus");
185 const DisabledKey = Symbol("CdxDisabled");
186 const NoInvertClass = "".concat(LibraryPrefix, "-no-invert");
187 const TableRowIdentifier = Symbol("CdxTableRowIdentifier");
188 const TablePaginationPositions = [
193 const iconSizeValidator = makeStringTypeValidator(IconSizes);
194 const _sfc_main$y = defineComponent({
197 /** The SVG path or an object containing that path plus other data. */
199 type: [String, Object],
203 * Accessible label for the icon. If not included, the icon will be hidden from screen
204 * readers via `aria-hidden="true"`. Browsers also display this label as a tooltip when the
205 * user hovers over the icon. Note that this label is not rendered as visible text next
213 * Explicitly set the language code to use for the icon. See
214 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/lang.
215 * Defaults to the lang attribute of the nearest ancestor at mount time.
222 * Explicitly set the direction to use for the icon. See
223 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dir.
224 * Defaults to the computed direction at mount time.
231 * Specify icon size by choosing one of several pre-defined size
232 * options. See the type documentation for supported size options.
233 * The `medium` size is used by default if no size prop is provided.
238 validator: iconSizeValidator
242 const rootElement = ref();
243 const computedDir = useComputedDirection(rootElement);
244 const computedLang = useComputedLanguage(rootElement);
245 const overriddenDir = computed(() => {
247 return (_a = props.dir) != null ? _a : computedDir.value;
249 const overriddenLang = computed(() => {
251 return (_a = props.lang) != null ? _a : computedLang.value;
253 const rootClasses = computed(() => ({
254 "cdx-icon--flipped": overriddenDir.value === "rtl" && overriddenLang.value !== null && G8(props.icon, overriddenLang.value),
255 ["cdx-icon--".concat(props.size)]: true
257 const resolvedIcon = computed(
260 return Q8(props.icon, (_a = overriddenLang.value) != null ? _a : "", (_b = overriddenDir.value) != null ? _b : "ltr");
263 const iconSvg = computed(() => typeof resolvedIcon.value === "string" ? resolvedIcon.value : "");
264 const iconPath = computed(() => typeof resolvedIcon.value !== "string" ? resolvedIcon.value.path : "");
273 const _export_sfc = (sfc, props) => {
274 const target = sfc.__vccOpts || sfc;
275 for (const [key, val] of props) {
280 const _hoisted_1$v = ["aria-hidden"];
281 const _hoisted_2$l = { key: 0 };
282 const _hoisted_3$e = ["innerHTML"];
283 const _hoisted_4$a = ["d"];
284 function _sfc_render$y(_ctx, _cache, $props, $setup, $data, $options) {
285 return openBlock(), createElementBlock(
289 class: normalizeClass(["cdx-icon", _ctx.rootClasses])
292 (openBlock(), createElementBlock("svg", {
293 xmlns: "http://www.w3.org/2000/svg",
294 "xmlns:xlink": "http://www.w3.org/1999/xlink",
297 viewBox: "0 0 20 20",
298 "aria-hidden": _ctx.iconLabel ? void 0 : true
300 _ctx.iconLabel ? (openBlock(), createElementBlock(
303 toDisplayString(_ctx.iconLabel),
306 )) : createCommentVNode("v-if", true),
307 _ctx.iconSvg ? (openBlock(), createElementBlock("g", {
309 innerHTML: _ctx.iconSvg
310 }, null, 8, _hoisted_3$e)) : (openBlock(), createElementBlock("path", {
313 }, null, 8, _hoisted_4$a))
320 const CdxIcon = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["render", _sfc_render$y]]);
321 function flattenSlotContents(slotContents) {
322 const flattened = [];
323 for (const node of slotContents) {
326 typeof node.type === "string" || // Component
327 typeof node.type === "object"
329 flattened.push(node);
330 } else if (node.type !== Comment) {
331 if (typeof node.children === "string" && node.children.trim() !== "") {
332 flattened.push(node.children);
333 } else if (Array.isArray(node.children)) {
334 flattened.push(...flattenSlotContents(node.children));
340 function isComponentVNode(node, componentName) {
341 if (typeof node.type === "object" && "name" in node.type) {
342 if (componentName !== void 0) {
343 return node.type.name === componentName;
349 function isTagVNode(node, tagName) {
350 if (typeof node.type === "string") {
352 return node.type === tagName.toLowerCase();
357 function useSlotContents(slot) {
358 const slotContents = typeof slot === "function" ? slot() : slot;
359 return slotContents ? flattenSlotContents(slotContents) : [];
361 function useWarnOnce(shouldWarn, message) {
366 const stop = watch(shouldWarn, (newValue) => {
373 function useIconOnlyButton(slot, attrs, componentName) {
374 const isIconOnly = computed(() => {
375 const slotContents = useSlotContents(slot);
376 if (slotContents.length !== 1) {
379 const soleNode = slotContents[0];
380 if (typeof soleNode === "object" && (isComponentVNode(soleNode, "CdxIcon") || isTagVNode(soleNode, "svg"))) {
386 () => isIconOnly.value && !attrs["aria-label"] && !attrs["aria-hidden"],
387 "".concat(componentName, ": Icon-only buttons require one of the following attributes: aria-label or aria-hidden. See documentation at https://doc.wikimedia.org/codex/latest/components/demos/button.html#icon-only-button")
391 const buttonActionValidator = makeStringTypeValidator(ButtonActions);
392 const buttonWeightValidator = makeStringTypeValidator(ButtonWeights);
393 const buttonSizeValidator = makeStringTypeValidator(ButtonSizes);
394 const _sfc_main$x = defineComponent({
398 * The kind of action that will be taken on click.
400 * @values 'default', 'progressive', 'destructive'
405 validator: buttonActionValidator
408 * Visual prominence of the button.
410 * @values 'normal', 'primary', 'quiet'
415 validator: buttonWeightValidator
420 * Most buttons should use the default medium size. In rare cases the large size should
421 * be used, for example to make icon-only buttons larger on touchscreens.
423 * @values 'medium', 'large'
428 validator: buttonSizeValidator
432 setup(props, { emit, slots, attrs }) {
433 const button = ref();
434 const isIconOnly = useIconOnlyButton(slots.default, attrs, "CdxButton");
435 const isActive = ref(false);
436 const rootClasses = computed(() => ({
437 ["cdx-button--action-".concat(props.action)]: true,
438 ["cdx-button--weight-".concat(props.weight)]: true,
439 ["cdx-button--size-".concat(props.size)]: true,
440 "cdx-button--framed": props.weight !== "quiet",
441 "cdx-button--icon-only": isIconOnly.value,
442 "cdx-button--is-active": isActive.value
444 const onClick = (event) => {
445 emit("click", event);
447 const setActive = (active) => {
448 isActive.value = active;
450 function onKeyDown() {
456 (_a = button.value) == null ? void 0 : _a.click();
467 function _sfc_render$x(_ctx, _cache, $props, $setup, $data, $options) {
468 return openBlock(), createElementBlock(
472 class: normalizeClass(["cdx-button", _ctx.rootClasses]),
473 onKeydown: _cache[0] || (_cache[0] = withKeys(withModifiers((...args) => _ctx.onKeyDown && _ctx.onKeyDown(...args), ["prevent"]), ["space", "enter"])),
474 onKeyup: _cache[1] || (_cache[1] = withKeys((...args) => _ctx.onKeyUp && _ctx.onKeyUp(...args), ["space", "enter"])),
475 onClick: _cache[2] || (_cache[2] = (...args) => _ctx.onClick && _ctx.onClick(...args))
478 renderSlot(_ctx.$slots, "default")
481 /* CLASS, NEED_HYDRATION */
484 const CdxButton = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["render", _sfc_render$x]]);
485 const _sfc_main$w = defineComponent({
486 name: "CdxAccordion",
487 components: { CdxButton, CdxIcon },
490 * Forces the accordion to show the action icon.
492 * @values 'true', 'false'
494 actionAlwaysVisible: {
499 * The icon that will be displayed on the right side of the accordion header when expanded.
503 type: [String, Object],
507 * Label for the action button. If an action icon is being used, then a label for that icon
508 * should be provided for ARIA support.
515 * The heading level of the accordion title.
517 * @values 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
526 * When the action button is clicked.
529 "action-button-click"
531 setup(props, { attrs, emit }) {
532 const isExpanded = ref("open" in attrs);
533 const emitActionButtonClick = () => {
534 emit("action-button-click");
536 const onToggle = (e) => {
537 isExpanded.value = e.newState === "open";
539 const shouldShowActionButton = computed(
540 () => props.actionIcon && (isExpanded.value || props.actionAlwaysVisible)
542 const rootClasses = computed(() => ({
543 "cdx-accordion--has-icon": shouldShowActionButton.value
546 emitActionButtonClick,
548 shouldShowActionButton,
553 const _hoisted_1$u = { class: "cdx-accordion__header__title" };
554 const _hoisted_2$k = { class: "cdx-accordion__header__description" };
555 function _sfc_render$w(_ctx, _cache, $props, $setup, $data, $options) {
556 const _component_cdx_icon = resolveComponent("cdx-icon");
557 const _component_cdx_button = resolveComponent("cdx-button");
558 return openBlock(), createElementBlock(
561 class: normalizeClass(["cdx-accordion", _ctx.rootClasses]),
562 onToggle: _cache[1] || (_cache[1] = (...args) => _ctx.onToggle && _ctx.onToggle(...args))
565 createElementVNode("summary", null, [
566 (openBlock(), createBlock(resolveDynamicComponent(_ctx.headingLevel), { class: "cdx-accordion__header" }, {
567 default: withCtx(() => [
568 createElementVNode("span", _hoisted_1$u, [
569 renderSlot(_ctx.$slots, "title")
571 createElementVNode("span", _hoisted_2$k, [
572 renderSlot(_ctx.$slots, "description")
578 _ctx.shouldShowActionButton ? (openBlock(), createBlock(_component_cdx_button, {
580 class: "cdx-accordion__action",
581 "aria-label": _ctx.actionButtonLabel,
584 onClick: withModifiers(_ctx.emitActionButtonClick, ["stop"])
586 default: withCtx(() => [
587 createVNode(_component_cdx_icon, {
588 icon: _ctx.actionIcon,
589 "icon-label": _ctx.actionButtonLabel,
591 }, null, 8, ["icon", "icon-label"])
595 }, 8, ["aria-label", "onClick"])) : createCommentVNode("v-if", true)
597 createElementVNode("div", {
598 class: "cdx-accordion__content",
599 onClick: _cache[0] || (_cache[0] = withModifiers(() => {
602 renderSlot(_ctx.$slots, "default")
606 /* CLASS, NEED_HYDRATION */
609 const Accordion = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["render", _sfc_render$w]]);
610 function getButtonLabel(button) {
611 if (button.label === void 0) {
614 if (button.label === null) {
619 function useButtonGroupKeyboardNav(buttonsProp) {
620 const rootElement = ref();
621 const focusedButtonIndex = ref();
622 const buttonRefs = ref(/* @__PURE__ */ new Map());
623 const currentDirection = useComputedDirection(rootElement);
624 function assignTemplateRef(templateRef, index) {
625 const button = templateRef;
627 buttonRefs.value.set(index, button);
630 function onFocus(index) {
631 focusedButtonIndex.value = index;
634 focusedButtonIndex.value = void 0;
636 function focusNonDisabled(index, increment) {
638 const newIndex = index + increment;
639 const targetButton = buttonsProp.value[newIndex];
641 if (targetButton.disabled) {
642 focusNonDisabled(newIndex, increment);
644 const buttonElement = (_a = buttonRefs.value.get(newIndex)) == null ? void 0 : _a.$el;
645 buttonElement == null ? void 0 : buttonElement.focus();
651 focusNonDisabled((_a = focusedButtonIndex.value) != null ? _a : -1, 1);
655 focusNonDisabled((_a = focusedButtonIndex.value) != null ? _a : buttonsProp.value.length, -1);
657 function moveRight() {
658 if (currentDirection.value === "rtl") {
664 function moveLeft() {
665 if (currentDirection.value === "rtl") {
671 function onKeydown(e) {
699 const _sfc_main$v = defineComponent({
700 name: "CdxButtonGroup",
707 * Objects describing the buttons in the group. See the ButtonGroupItem type.
712 validator: (value) => Array.isArray(value) && value.length >= 1
715 * Whether the entire group is disabled.
717 * If this is set to true, all buttons in the group are disabled. Buttons can also be
718 * disabled individually by setting their `disabled` property to true.
727 * Emitted when a button is clicked
729 * @property {string | number} value The `value` property of the button that was clicked
740 } = useButtonGroupKeyboardNav(toRef(props, "buttons"));
751 const _hoisted_1$t = {
753 class: "cdx-button-group"
755 function _sfc_render$v(_ctx, _cache, $props, $setup, $data, $options) {
756 const _component_cdx_icon = resolveComponent("cdx-icon");
757 const _component_cdx_button = resolveComponent("cdx-button");
758 return openBlock(), createElementBlock(
762 (openBlock(true), createElementBlock(
765 renderList(_ctx.buttons, (button, index) => {
766 return openBlock(), createBlock(_component_cdx_button, {
769 ref: (ref2) => _ctx.assignTemplateRef(ref2, index),
770 disabled: button.disabled || _ctx.disabled,
771 "aria-label": button.ariaLabel,
772 onClick: ($event) => _ctx.$emit("click", button.value),
773 onFocus: ($event) => _ctx.onFocus(index),
775 onKeydown: _ctx.onKeydown
777 default: withCtx(() => [
778 renderSlot(_ctx.$slots, "default", { button }, () => [
779 button.icon ? (openBlock(), createBlock(_component_cdx_icon, {
782 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
784 " " + toDisplayString(_ctx.getButtonLabel(button)),
792 }, 1032, ["disabled", "aria-label", "onClick", "onFocus", "onBlur", "onKeydown"]);
802 const ButtonGroup = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["render", _sfc_render$v]]);
803 const _sfc_main$u = defineComponent({
804 name: "CdxThumbnail",
805 components: { CdxIcon },
811 type: [Object, null],
815 * Thumbnail placeholder icon.
818 type: [String, Object],
823 const thumbnailLoaded = ref(false);
824 const thumbnailStyle = ref({});
825 const preloadThumbnail = (url) => {
826 const escapedUrl = url.replace(/([\\"\n])/g, "\\$1");
827 const image = new Image();
828 image.onload = () => {
829 thumbnailStyle.value = { backgroundImage: 'url("'.concat(escapedUrl, '")') };
830 thumbnailLoaded.value = true;
832 image.onerror = () => {
833 thumbnailLoaded.value = false;
835 image.src = escapedUrl;
839 if ((_a = props.thumbnail) == null ? void 0 : _a.url) {
840 preloadThumbnail(props.thumbnail.url);
850 const _hoisted_1$s = { class: "cdx-thumbnail" };
851 const _hoisted_2$j = {
853 class: "cdx-thumbnail__placeholder"
855 function _sfc_render$u(_ctx, _cache, $props, $setup, $data, $options) {
856 const _component_cdx_icon = resolveComponent("cdx-icon");
857 return openBlock(), createElementBlock("span", _hoisted_1$s, [
858 !_ctx.thumbnailLoaded ? (openBlock(), createElementBlock("span", _hoisted_2$j, [
859 createVNode(_component_cdx_icon, {
860 icon: _ctx.placeholderIcon,
861 class: "cdx-thumbnail__placeholder__icon--vue"
862 }, null, 8, ["icon"])
863 ])) : createCommentVNode("v-if", true),
864 createVNode(Transition, { name: "cdx-thumbnail__image" }, {
865 default: withCtx(() => [
866 _ctx.thumbnailLoaded ? (openBlock(), createElementBlock(
870 style: normalizeStyle(_ctx.thumbnailStyle),
871 class: normalizeClass([_ctx.NoInvertClass, "cdx-thumbnail__image"])
876 )) : createCommentVNode("v-if", true)
883 const CdxThumbnail = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["render", _sfc_render$u]]);
884 const _sfc_main$t = defineComponent({
886 components: { CdxIcon, CdxThumbnail },
889 * If provided, the Card will be a link to this URL.
896 * Icon displayed at the start of the Card.
899 type: [String, Object],
903 * Thumbnail image data for the Card.
906 type: [Object, null],
910 * Option to force a thumbnail layout.
912 * When set to `true`, the Card will display a Thumbnail. If a `thumbnail` prop was also
913 * provided, the thumbnail image will display. Otherwise, a placeholder icon will display.
915 * This is useful when displaying groups of Cards when some of the cards have thumbnail
916 * images but some do not. `forceThumbnail` will provide a consistent layout for that group.
918 * Note that this prop is not needed to display a thumbnail image: if the `thumbnail` prop
919 * is provided, it will display. This prop is only needed to enable the display of the
920 * thumbnail placeholder icon when the `thumbnail` prop is not provided.
927 * Optional custom icon for the placeholder shown when `forceThumbnail` is true but no
928 * thumbnail is provided.
930 * Defaults to the default placeholder icon set in the Thumbnail component.
932 customPlaceholderIcon: {
933 type: [String, Object],
938 const isLink = computed(() => !!props.url);
939 const contentTag = computed(() => isLink.value ? "a" : "span");
940 const cardLink = computed(() => isLink.value ? props.url : void 0);
948 const _hoisted_1$r = { class: "cdx-card__text" };
949 const _hoisted_2$i = { class: "cdx-card__text__title" };
950 const _hoisted_3$d = {
952 class: "cdx-card__text__description"
954 const _hoisted_4$9 = {
956 class: "cdx-card__text__supporting-text"
958 function _sfc_render$t(_ctx, _cache, $props, $setup, $data, $options) {
959 const _component_cdx_thumbnail = resolveComponent("cdx-thumbnail");
960 const _component_cdx_icon = resolveComponent("cdx-icon");
961 return openBlock(), createBlock(resolveDynamicComponent(_ctx.contentTag), {
963 class: normalizeClass(["cdx-card", {
964 "cdx-card--is-link": _ctx.isLink,
965 // Include dynamic classes in the template so that $slots is reactive.
966 "cdx-card--title-only": !_ctx.$slots.description && !_ctx.$slots["supporting-text"]
969 default: withCtx(() => [
970 _ctx.thumbnail || _ctx.forceThumbnail ? (openBlock(), createBlock(_component_cdx_thumbnail, {
972 thumbnail: _ctx.thumbnail,
973 "placeholder-icon": _ctx.customPlaceholderIcon,
974 class: "cdx-card__thumbnail"
975 }, null, 8, ["thumbnail", "placeholder-icon"])) : _ctx.icon ? (openBlock(), createBlock(_component_cdx_icon, {
978 class: "cdx-card__icon"
979 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
980 createElementVNode("span", _hoisted_1$r, [
981 createElementVNode("span", _hoisted_2$i, [
982 renderSlot(_ctx.$slots, "title")
984 _ctx.$slots.description ? (openBlock(), createElementBlock("span", _hoisted_3$d, [
985 renderSlot(_ctx.$slots, "description")
986 ])) : createCommentVNode("v-if", true),
987 _ctx.$slots["supporting-text"] ? (openBlock(), createElementBlock("span", _hoisted_4$9, [
988 renderSlot(_ctx.$slots, "supporting-text")
989 ])) : createCommentVNode("v-if", true)
994 }, 8, ["href", "class"]);
996 const Card = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["render", _sfc_render$t]]);
997 function useComputedDisabled(disabledProp) {
998 const providedDisabled = inject(DisabledKey, ref(false));
999 return computed(() => providedDisabled.value || disabledProp.value);
1001 function useFieldData(disabledProp, statusProp, idAttr) {
1002 const computedDisabled = useComputedDisabled(disabledProp);
1003 const providedStatus = inject(FieldStatusKey, ref("default"));
1004 const computedStatus = computed(() => {
1005 if ((statusProp == null ? void 0 : statusProp.value) && statusProp.value !== "default") {
1006 return statusProp.value;
1008 return providedStatus.value;
1010 const providedId = inject(FieldInputIdKey, void 0);
1011 const computedInputId = computed(() => {
1013 return (_a = providedId == null ? void 0 : providedId.value) != null ? _a : idAttr;
1021 function useSplitAttributes(attrs, internalClasses = computed(() => ({}))) {
1022 const rootClasses = computed(() => {
1023 const classRecord = __objRest(internalClasses.value, []);
1025 const providedClasses = attrs.class.split(" ");
1026 providedClasses.forEach((className) => {
1027 classRecord[className] = true;
1032 const rootStyle = computed(() => {
1033 if ("style" in attrs) {
1038 const otherAttrs = computed(() => {
1039 const _a = attrs, { class: _ignoredClass, style: _ignoredStyle } = _a, attrsCopy = __objRest(_a, ["class", "style"]);
1048 function useI18n(messageKey, defaultValue, params = []) {
1049 const providedI18nFunc = inject("CdxI18nFunction", void 0);
1050 return computed(() => {
1051 const unwrappedParams = params.map((p2) => typeof p2 === "function" ? p2() : p2.value);
1052 const fromProvidedFunc = providedI18nFunc == null ? void 0 : providedI18nFunc(messageKey, ...unwrappedParams);
1053 if (fromProvidedFunc !== void 0 && fromProvidedFunc !== null) {
1054 return fromProvidedFunc;
1056 return typeof defaultValue === "function" ? defaultValue(...unwrappedParams) : defaultValue;
1059 function useI18nWithOverride(override, messageKey, defaultValue, params = []) {
1060 const translatedMessage = useI18n(messageKey, defaultValue, params);
1061 return computed(() => override.value || translatedMessage.value);
1063 const _sfc_main$s = defineComponent({
1065 components: { CdxIcon },
1067 * We want the label or legend to inherit attributes, not the root element.
1069 inheritAttrs: false,
1072 * Icon before the label text.
1074 * Do not use this if including a start icon within the input component.
1077 type: [String, Object],
1081 * Whether the field is optional.
1083 * This will add a flag next to the label indicating that the field is optional.
1089 // DEPRECATED: set default to '(optional)' (T368444).
1091 * Text to indicate that the field is optional.
1093 * Omit this prop to use the default value, "(optional)".
1100 * Whether the label should be visually hidden.
1107 * Whether this component should output a `<legend>` element.
1109 * Always set this to true when this component is used inside a `<fieldset>` element. Do not
1110 * set it to true otherwise.
1117 * The ID of the input/control this label is for.
1119 * Will be added as the `for` attribute of the `<label>`. Not needed for `<legend>`.
1126 * The ID of the description element.
1128 * This ID can be used for the `aria-describedby` attribute of the input.
1135 * Whether this label is for a disabled field or input.
1142 setup(props, { attrs }) {
1143 const { computedDisabled } = useFieldData(toRef(props, "disabled"));
1144 const internalClasses = computed(() => ({
1145 "cdx-label--visually-hidden": props.visuallyHidden,
1146 "cdx-label--disabled": computedDisabled.value
1152 } = useSplitAttributes(attrs, internalClasses);
1153 const translatedOptionalFlag = useI18nWithOverride(
1154 toRef(props, "optionalFlag"),
1155 "cdx-label-optional-flag",
1162 translatedOptionalFlag
1166 const _hoisted_1$q = ["for"];
1167 const _hoisted_2$h = { class: "cdx-label__label__text" };
1168 const _hoisted_3$c = {
1170 class: "cdx-label__label__optional-flag"
1172 const _hoisted_4$8 = ["id"];
1173 const _hoisted_5$8 = { class: "cdx-label__label" };
1174 const _hoisted_6$7 = { class: "cdx-label__label__text" };
1175 const _hoisted_7$3 = {
1177 class: "cdx-label__label__optional-flag"
1179 const _hoisted_8$2 = {
1181 class: "cdx-label__description"
1183 function _sfc_render$s(_ctx, _cache, $props, $setup, $data, $options) {
1184 const _component_cdx_icon = resolveComponent("cdx-icon");
1185 return !_ctx.isLegend ? (openBlock(), createElementBlock(
1189 class: normalizeClass(["cdx-label", _ctx.rootClasses]),
1190 style: normalizeStyle(_ctx.rootStyle)
1193 createElementVNode("label", mergeProps({
1194 class: "cdx-label__label",
1195 for: _ctx.inputId ? _ctx.inputId : void 0
1196 }, _ctx.otherAttrs), [
1197 _ctx.icon ? (openBlock(), createBlock(_component_cdx_icon, {
1200 class: "cdx-label__label__icon"
1201 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
1202 createElementVNode("span", _hoisted_2$h, [
1203 renderSlot(_ctx.$slots, "default")
1205 _ctx.optionalFlag || _ctx.optional ? (openBlock(), createElementBlock(
1208 toDisplayString(" ") + " " + toDisplayString(_ctx.translatedOptionalFlag),
1211 )) : createCommentVNode("v-if", true)
1212 ], 16, _hoisted_1$q),
1213 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? (openBlock(), createElementBlock("span", {
1215 id: _ctx.descriptionId || void 0,
1216 class: "cdx-label__description"
1218 renderSlot(_ctx.$slots, "description")
1219 ], 8, _hoisted_4$8)) : createCommentVNode("v-if", true)
1223 )) : (openBlock(), createElementBlock(
1227 class: ["cdx-label", _ctx.rootClasses],
1228 style: _ctx.rootStyle
1229 }, _ctx.otherAttrs),
1231 createElementVNode("span", _hoisted_5$8, [
1232 _ctx.icon ? (openBlock(), createBlock(_component_cdx_icon, {
1235 class: "cdx-label__label__icon"
1236 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
1237 createElementVNode("span", _hoisted_6$7, [
1238 renderSlot(_ctx.$slots, "default")
1240 _ctx.optionalFlag || _ctx.optional ? (openBlock(), createElementBlock(
1243 toDisplayString(" ") + " " + toDisplayString(_ctx.translatedOptionalFlag),
1246 )) : createCommentVNode("v-if", true)
1248 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? (openBlock(), createElementBlock("span", _hoisted_8$2, [
1249 renderSlot(_ctx.$slots, "description")
1250 ])) : createCommentVNode("v-if", true)
1256 const CdxLabel = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["render", _sfc_render$s]]);
1257 function useLabelChecker(slot, attrs, componentName) {
1259 () => useSlotContents(slot).length === 0 && !(attrs == null ? void 0 : attrs["aria-label"]) && !(attrs == null ? void 0 : attrs["aria-labelledby"]),
1260 "".concat(componentName, ": Inputs must have an associated label. Provide one of the following:\n - A label via the appropriate slot\n - An `aria-label` attribute set to the label text\n - An `aria-labelledby` attribute set to the ID of the label element")
1263 function useModelWrapper(modelValueRef, emit, eventName) {
1265 get: () => modelValueRef.value,
1266 // If eventName is undefined, then 'update:modelValue' must be a valid EventName,
1267 // but TypeScript's type analysis isn't clever enough to realize that
1268 set: (value) => emit(eventName || "update:modelValue", value)
1272 function useGeneratedId(identifier) {
1274 const vm = getCurrentInstance();
1275 const externalId = (_a = vm == null ? void 0 : vm.props.id) != null ? _a : vm == null ? void 0 : vm.attrs.id;
1277 return "".concat(LibraryPrefix, "-").concat(identifier, "-").concat(counter++);
1278 } else if (externalId) {
1279 return "".concat(LibraryPrefix, "-").concat(externalId, "-").concat(counter++);
1281 return "".concat(LibraryPrefix, "-").concat(counter++);
1284 const statusValidator$a = makeStringTypeValidator(ValidationStatusTypes);
1285 const _sfc_main$r = defineComponent({
1286 name: "CdxCheckbox",
1287 components: { CdxLabel },
1290 * Value of the checkbox or checkbox group.
1292 * Provided by `v-model` binding in the parent component.
1295 type: [Boolean, Array],
1299 * HTML "value" attribute to assign to the input.
1301 * Required for input groups.
1304 type: [String, Number, Boolean],
1308 * HTML "name" attribute to assign to the input.
1315 * Whether the disabled attribute should be added to the input.
1322 * Whether the indeterminate visual state should be displayed.
1324 * This is unrelated to the value provided by `v-model`, and the indeterminate visual state
1325 * will override the checked or unchecked visual state.
1332 * Whether the component should display inline.
1334 * By default, `display: block` is set and a margin exists between
1335 * sibling components, for a stacked layout.
1342 * Whether the label should be visually hidden.
1344 * When true, the label will remain accessible to assistive technology.
1351 * Validation status of the Checkbox.
1356 validator: statusValidator$a
1361 * Emitted when modelValue changes.
1363 * @property {boolean | string[] | number[]} modelValue The new model value
1367 setup(props, { emit, slots, attrs }) {
1369 useLabelChecker((_a = slots.default) == null ? void 0 : _a.call(slots), attrs, "CdxCheckbox");
1374 toRef(props, "disabled"),
1375 toRef(props, "status")
1377 const rootClasses = computed(() => ({
1378 "cdx-checkbox--inline": props.inline,
1379 ["cdx-checkbox--status-".concat(computedStatus.value)]: true
1381 const customInputClasses = computed(() => ({
1382 "cdx-checkbox__custom-input--inline": props.inline
1384 const input = ref();
1385 const checkboxId = useGeneratedId("checkbox");
1386 const descriptionId = useGeneratedId("description");
1387 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
1399 const _hoisted_1$p = { class: "cdx-checkbox__wrapper" };
1400 const _hoisted_2$g = ["id", "aria-describedby", "value", "name", "disabled", ".indeterminate"];
1401 const _hoisted_3$b = /* @__PURE__ */ createElementVNode(
1403 { class: "cdx-checkbox__icon" },
1408 function _sfc_render$r(_ctx, _cache, $props, $setup, $data, $options) {
1409 const _component_cdx_label = resolveComponent("cdx-label");
1410 return openBlock(), createElementBlock(
1413 class: normalizeClass(["cdx-checkbox", _ctx.rootClasses])
1416 createElementVNode("div", _hoisted_1$p, [
1417 withDirectives(createElementVNode("input", {
1418 id: _ctx.checkboxId,
1420 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
1421 class: "cdx-checkbox__input",
1423 "aria-describedby": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
1424 value: _ctx.inputValue,
1426 disabled: _ctx.computedDisabled,
1427 ".indeterminate": _ctx.indeterminate
1428 }, null, 40, _hoisted_2$g), [
1429 [vModelCheckbox, _ctx.wrappedModel]
1432 _ctx.$slots.default && _ctx.$slots.default().length ? (openBlock(), createBlock(_component_cdx_label, {
1434 class: "cdx-checkbox__label",
1435 "input-id": _ctx.checkboxId,
1436 "description-id": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
1437 disabled: _ctx.computedDisabled,
1438 "visually-hidden": _ctx.hideLabel
1440 default: withCtx(() => [
1441 renderSlot(_ctx.$slots, "default")
1446 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? {
1447 name: "description",
1449 renderSlot(_ctx.$slots, "description")
1453 ]), 1032, ["input-id", "description-id", "disabled", "visually-hidden"])) : createCommentVNode("v-if", true)
1455 _ctx.$slots["custom-input"] ? (openBlock(), createElementBlock(
1459 class: normalizeClass(["cdx-checkbox__custom-input", _ctx.customInputClasses])
1462 renderSlot(_ctx.$slots, "custom-input")
1466 )) : createCommentVNode("v-if", true)
1472 const CdxCheckbox = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["render", _sfc_render$r]]);
1473 const _sfc_main$q = defineComponent({
1474 name: "CdxInputChip",
1484 type: [String, Object],
1488 * Whether the input chip can be removed.
1495 * Whether the InputChip is readonly.
1507 * Emitted when a chip is removed by the user.
1509 * @property {'button'|'Backspace'|'Delete'} method How the chip was removed
1513 * Emitted when a chip is clicked by the user.
1517 * Emitted when the user presses the left arrow key.
1521 * Emitted when the user presses the right arrow key.
1525 setup(props, { emit }) {
1526 const tabIndex = computed(() => props.disabled ? -1 : 0);
1527 const rootElement = ref();
1528 const rootClasses = computed(() => ({
1529 "cdx-input-chip--disabled": props.disabled,
1530 "cdx-input-chip--readonly": props.readonly
1532 const ariaDescription = useI18n(
1533 "cdx-input-chip-aria-description",
1534 "Press Enter to edit or Delete to remove"
1536 function onKeydown(e) {
1542 e.stopPropagation();
1545 (_a = rootElement.value) == null ? void 0 : _a.blur();
1547 e.stopPropagation();
1551 emit("remove-chip", e.key);
1553 e.stopPropagation();
1558 e.stopPropagation();
1561 emit("arrow-right");
1563 e.stopPropagation();
1583 this.$refs.rootElement.focus();
1587 const _hoisted_1$o = ["tabindex", "aria-description"];
1588 const _hoisted_2$f = { class: "cdx-input-chip__text" };
1589 function _sfc_render$q(_ctx, _cache, $props, $setup, $data, $options) {
1590 const _component_cdx_icon = resolveComponent("cdx-icon");
1591 const _component_cdx_button = resolveComponent("cdx-button");
1592 return openBlock(), createElementBlock("div", {
1594 class: normalizeClass(["cdx-input-chip", _ctx.rootClasses]),
1595 tabindex: _ctx.tabIndex,
1597 "aria-description": _ctx.ariaDescription,
1598 onKeydown: _cache[1] || (_cache[1] = (...args) => _ctx.onKeydown && _ctx.onKeydown(...args)),
1599 onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("click-chip"))
1601 _ctx.icon ? (openBlock(), createBlock(_component_cdx_icon, {
1605 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
1606 createElementVNode("span", _hoisted_2$f, [
1607 renderSlot(_ctx.$slots, "default")
1609 createVNode(_component_cdx_button, {
1610 class: "cdx-input-chip__button",
1613 "aria-hidden": "true",
1614 disabled: _ctx.disabled,
1615 onClick: _cache[0] || (_cache[0] = withModifiers(($event) => _ctx.$emit("remove-chip", "button"), ["stop"]))
1617 default: withCtx(() => [
1618 createVNode(_component_cdx_icon, {
1619 icon: _ctx.cdxIconClose,
1621 }, null, 8, ["icon"])
1626 ], 42, _hoisted_1$o);
1628 const CdxInputChip = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render$q]]);
1629 function useOptionalModelWrapper(internalValueRef, modelValueRef, emit, eventName) {
1633 return (_a = modelValueRef.value) != null ? _a : internalValueRef.value;
1636 if (modelValueRef.value !== null) {
1637 emit(eventName || "update:modelValue", value);
1639 internalValueRef.value = value;
1644 const statusValidator$9 = makeStringTypeValidator(ValidationStatusTypes);
1645 const _sfc_main$p = defineComponent({
1646 name: "CdxChipInput",
1651 * We want the input to inherit attributes, not the root element.
1653 inheritAttrs: false,
1656 * Current chips present in the input.
1658 * Provided by `v-model` binding in the parent component.
1665 * Current value of the text input. This prop is optional and should only be used if you
1666 * need to keep track of the text input value for some reason (e.g. for validation).
1668 * Optionally provided by `v-model:input-value` binding in the parent component.
1671 type: [String, Number],
1675 * Whether the text input should appear below the set of input chips.
1677 * By default, the input chips are inline with the input.
1684 * `status` attribute of the input.
1689 validator: statusValidator$9
1692 * Validation function for chip text. If it returns false, the chip will not be added and
1693 * the error status will be set.
1697 // eslint-disable-next-line @typescript-eslint/no-unused-vars
1698 default: (value) => true
1701 * Whether the input is disabled.
1708 * Whether the ChipInput is readonly.
1717 * When the input chips change.
1719 * @property {ChipInputItem[]} inputChips The new set of inputChips
1721 "update:input-chips",
1723 * When the input value changes. Only emitted if the inputValue prop is provided.
1725 * @property {string | number} inputValue The new input value
1727 "update:input-value"
1729 setup(props, { emit, attrs }) {
1730 const rootElement = ref();
1731 const chipsContainer = ref();
1732 const separateInputWrapper = ref();
1733 const statusMessageContent = ref("");
1734 const computedDirection = useComputedDirection(rootElement);
1735 const input = ref();
1736 const allowArbitrary = inject(AllowArbitraryKey, ref(true));
1737 const internalInputValue = ref("");
1738 const computedInputValue = useOptionalModelWrapper(
1740 toRef(props, "inputValue"),
1742 "update:input-value"
1744 const validatedStatus = ref("default");
1745 const internalStatus = computed(() => {
1746 if (validatedStatus.value === "error" || props.status === "error") {
1751 const { computedDisabled, computedStatus } = useFieldData(toRef(props, "disabled"), internalStatus);
1752 const isFocused = ref(false);
1753 const internalClasses = computed(() => ({
1754 "cdx-chip-input--has-separate-input": props.separateInput,
1755 ["cdx-chip-input--status-".concat(computedStatus.value)]: true,
1756 // We need focused and disabled classes on the root element, which contains the
1757 // chips and the input, since it is styled to look like the input.
1758 "cdx-chip-input--focused": isFocused.value,
1759 "cdx-chip-input--disabled": computedDisabled.value,
1760 "cdx-chip-input--readonly": props.readonly
1766 } = useSplitAttributes(attrs, internalClasses);
1767 const chipRefs = [];
1768 const currentChipToRemove = ref(null);
1769 const computedChipToRemove = computed(() => currentChipToRemove.value ? currentChipToRemove.value.value : "");
1770 const chipAddedMessage = useI18n(
1771 "cdx-chip-input-chip-added",
1772 (x) => "Chip ".concat(x, " was added."),
1773 [computedInputValue]
1775 const chipRemovedMessage = useI18n(
1776 "cdx-chip-input-chip-removed",
1777 (x) => "Chip ".concat(x, " was removed."),
1778 [computedChipToRemove]
1780 function assignChipTemplateRef(chip, index) {
1781 if (chip !== null) {
1782 chipRefs[index] = chip;
1785 const focusInput = () => {
1786 input.value.focus();
1788 function addChip() {
1790 // If the input value is the same as a chip's value, or...
1791 !!props.inputChips.find((chip) => chip.value === computedInputValue.value) || // ...validation fails, set status to error.
1792 !props.chipValidator(computedInputValue.value)
1794 validatedStatus.value = "error";
1795 } else if (computedInputValue.value.toString().length > 0) {
1796 statusMessageContent.value = chipAddedMessage.value;
1797 emit("update:input-chips", props.inputChips.concat({ value: computedInputValue.value }));
1798 computedInputValue.value = "";
1801 function removeChip(chipToRemove) {
1802 if (props.readonly || computedDisabled.value) {
1805 emit("update:input-chips", props.inputChips.filter(
1806 (chip) => chip.value !== chipToRemove.value
1809 function moveChipFocus(direction, startIndex) {
1810 const resolvedDirection = (
1811 // -1 for prev (left in LTR, right in RTL), +1 for next (right in LTR, left in RTL)
1812 computedDirection.value === "ltr" && direction === "left" || computedDirection.value === "rtl" && direction === "right" ? -1 : 1
1814 const newIndex = startIndex + resolvedDirection;
1818 if (newIndex >= props.inputChips.length) {
1822 chipRefs[newIndex].focus();
1824 function handleChipClick(clickedChip) {
1825 return __async(this, null, function* () {
1827 if (props.readonly || computedDisabled.value) {
1832 removeChip(clickedChip);
1833 computedInputValue.value = (_a = clickedChip.label) != null ? _a : clickedChip.value;
1837 function handleChipRemove(chipToRemove, index, method) {
1838 currentChipToRemove.value = chipToRemove;
1839 statusMessageContent.value = chipRemovedMessage.value;
1840 if (method === "button") {
1842 } else if (method === "Backspace") {
1843 const newIndex = index === 0 ? 1 : index - 1;
1844 if (newIndex < props.inputChips.length) {
1845 chipRefs[newIndex].focus();
1849 } else if (method === "Delete") {
1850 const newIndex = index + 1;
1851 if (newIndex < props.inputChips.length) {
1852 chipRefs[newIndex].focus();
1857 removeChip(chipToRemove);
1859 function onInputKeydown(e) {
1861 const prevArrow = computedDirection.value === "rtl" ? "ArrowRight" : "ArrowLeft";
1864 if (computedInputValue.value.toString().length > 0 && allowArbitrary.value) {
1867 e.stopPropagation();
1872 (_a = input.value) == null ? void 0 : _a.blur();
1874 e.stopPropagation();
1878 if (((_b = input.value) == null ? void 0 : _b.selectionStart) === 0 && input.value.selectionEnd === 0 && props.inputChips.length > 0) {
1879 chipRefs[props.inputChips.length - 1].focus();
1881 e.stopPropagation();
1887 function onInputFocus() {
1888 isFocused.value = true;
1890 function onInputBlur() {
1891 isFocused.value = false;
1893 function onFocusOut(e) {
1895 if (!((_a = rootElement.value) == null ? void 0 : _a.contains(e.relatedTarget)) && allowArbitrary.value) {
1899 watch(toRef(props, "inputChips"), (newVal) => {
1900 const matchingChip = newVal.find((chip) => chip.value === computedInputValue.value);
1901 validatedStatus.value = matchingChip ? "error" : "default";
1903 watch(computedInputValue, () => {
1904 if (validatedStatus.value === "error") {
1905 validatedStatus.value = "default";
1911 separateInputWrapper,
1917 assignChipTemplateRef,
1927 statusMessageContent
1931 const _hoisted_1$n = {
1932 ref: "chipsContainer",
1933 class: "cdx-chip-input__chips",
1935 "aria-orientation": "horizontal"
1937 const _hoisted_2$e = ["readonly", "disabled"];
1938 const _hoisted_3$a = {
1940 ref: "separateInputWrapper",
1941 class: "cdx-chip-input__separate-input"
1943 const _hoisted_4$7 = ["readonly", "disabled"];
1944 const _hoisted_5$7 = {
1945 class: "cdx-chip-input__aria-status",
1947 "aria-live": "polite"
1949 function _sfc_render$p(_ctx, _cache, $props, $setup, $data, $options) {
1950 const _component_cdx_input_chip = resolveComponent("cdx-input-chip");
1951 return openBlock(), createElementBlock(
1955 class: normalizeClass(["cdx-chip-input", _ctx.rootClasses]),
1956 style: normalizeStyle(_ctx.rootStyle),
1957 onClick: _cache[8] || (_cache[8] = ($event) => _ctx.disabled || _ctx.readonly ? null : _ctx.focusInput),
1958 onFocusout: _cache[9] || (_cache[9] = (...args) => _ctx.onFocusOut && _ctx.onFocusOut(...args))
1965 (openBlock(true), createElementBlock(
1968 renderList(_ctx.inputChips, (chip, index) => {
1969 return openBlock(), createBlock(_component_cdx_input_chip, {
1972 ref: (ref2) => _ctx.assignChipTemplateRef(ref2, index),
1973 class: "cdx-chip-input__item",
1975 readonly: _ctx.readonly,
1976 disabled: _ctx.computedDisabled,
1977 onClickChip: ($event) => _ctx.handleChipClick(chip),
1978 onRemoveChip: (method) => _ctx.handleChipRemove(chip, index, method),
1979 onArrowLeft: ($event) => _ctx.moveChipFocus("left", index),
1980 onArrowRight: ($event) => _ctx.moveChipFocus("right", index)
1982 default: withCtx(() => {
1986 toDisplayString((_a = chip.label) != null ? _a : chip.value),
1994 }, 1032, ["icon", "readonly", "disabled", "onClickChip", "onRemoveChip", "onArrowLeft", "onArrowRight"]);
1997 /* KEYED_FRAGMENT */
1999 !_ctx.separateInput ? withDirectives((openBlock(), createElementBlock("input", mergeProps({
2002 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.computedInputValue = $event),
2003 class: "cdx-chip-input__input",
2004 readonly: _ctx.readonly,
2005 disabled: _ctx.computedDisabled
2006 }, _ctx.otherAttrs, {
2007 onBlur: _cache[1] || (_cache[1] = (...args) => _ctx.onInputBlur && _ctx.onInputBlur(...args)),
2008 onFocus: _cache[2] || (_cache[2] = (...args) => _ctx.onInputFocus && _ctx.onInputFocus(...args)),
2009 onKeydown: _cache[3] || (_cache[3] = (...args) => _ctx.onInputKeydown && _ctx.onInputKeydown(...args))
2010 }), null, 16, _hoisted_2$e)), [
2011 [vModelDynamic, _ctx.computedInputValue]
2012 ]) : createCommentVNode("v-if", true)
2017 _ctx.separateInput ? (openBlock(), createElementBlock(
2021 withDirectives(createElementVNode("input", mergeProps({
2023 "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => _ctx.computedInputValue = $event),
2024 class: "cdx-chip-input__input",
2025 readonly: _ctx.readonly,
2026 disabled: _ctx.computedDisabled
2027 }, _ctx.otherAttrs, {
2028 onBlur: _cache[5] || (_cache[5] = (...args) => _ctx.onInputBlur && _ctx.onInputBlur(...args)),
2029 onFocus: _cache[6] || (_cache[6] = (...args) => _ctx.onInputFocus && _ctx.onInputFocus(...args)),
2030 onKeydown: _cache[7] || (_cache[7] = (...args) => _ctx.onInputKeydown && _ctx.onInputKeydown(...args))
2031 }), null, 16, _hoisted_4$7), [
2032 [vModelDynamic, _ctx.computedInputValue]
2037 )) : createCommentVNode("v-if", true),
2041 toDisplayString(_ctx.statusMessageContent),
2047 /* CLASS, STYLE, NEED_HYDRATION */
2050 const CdxChipInput = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["render", _sfc_render$p]]);
2051 function regExpEscape(value) {
2052 return value.replace(/([\\{}()|.?*+\-^$[\]])/g, "\\$1");
2054 const COMBINING_MARK = "[̀-ͯ҃-҉֑-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪾ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿⃐-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯-꙲ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯]";
2055 function splitStringAtMatch(query, title) {
2057 return [title, "", ""];
2059 const sanitizedQuery = regExpEscape(query);
2060 const match = new RegExp(
2061 // Per https://www.regular-expressions.info/unicode.html, "any code point that is not a
2062 // combining mark can be followed by any number of combining marks." See also the
2063 // discussion in https://phabricator.wikimedia.org/T35242.
2064 sanitizedQuery + COMBINING_MARK + "*",
2067 if (!match || match.index === void 0) {
2068 return [title, "", ""];
2070 const matchStartIndex = match.index;
2071 const matchEndIndex = matchStartIndex + match[0].length;
2072 const highlightedTitle = title.slice(matchStartIndex, matchEndIndex);
2073 const beforeHighlight = title.slice(0, matchStartIndex);
2074 const afterHighlight = title.slice(matchEndIndex, title.length);
2075 return [beforeHighlight, highlightedTitle, afterHighlight];
2077 const stringHelpers = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2081 }, Symbol.toStringTag, { value: "Module" }));
2082 const _sfc_main$o = defineComponent({
2083 name: "CdxSearchResultTitle",
2093 * The current search query.
2101 const titleChunks = computed(
2102 () => splitStringAtMatch(props.searchQuery, String(props.title))
2109 const _hoisted_1$m = { class: "cdx-search-result-title" };
2110 const _hoisted_2$d = { class: "cdx-search-result-title__match" };
2111 function _sfc_render$o(_ctx, _cache, $props, $setup, $data, $options) {
2112 return openBlock(), createElementBlock("span", _hoisted_1$m, [
2113 createElementVNode("bdi", null, [
2115 toDisplayString(_ctx.titleChunks[0]),
2122 toDisplayString(_ctx.titleChunks[1]),
2127 toDisplayString(_ctx.titleChunks[2]),
2134 const CdxSearchResultTitle = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$o]]);
2135 const _sfc_main$n = defineComponent({
2136 name: "CdxMenuItem",
2137 components: { CdxIcon, CdxThumbnail, CdxSearchResultTitle },
2140 * ID for HTML `id` attribute.
2147 * The value provided to the parent menu component when this menu item is selected.
2150 type: [String, Number],
2154 * Whether the menu item is disabled.
2161 * Whether this menu item is selected.
2168 * Whether this menu item is being pressed.
2175 * Whether this menu item is visually highlighted due to hover or keyboard navigation.
2182 * Label for the menu item. If this isn't provided, the value will be displayed instead.
2189 * Text that matches current search query. Only used for search results and will be
2190 * displayed after the label.
2197 * Text that supports the label. Supporting text will appear next to the label in a more
2205 * URL for the menu item. If provided, the content of the menu item will be wrapped in an
2213 * Icon for the menu item.
2216 type: [String, Object],
2220 * Whether a thumbnail (or a placeholder icon) should be displayed.
2227 * Thumbnail for the menu item.
2230 type: [Object, null],
2234 * Description of the menu item.
2237 type: [String, null],
2241 * The search query to be highlighted within the menu item's title.
2248 * Whether to bold menu item labels.
2255 * Whether to hide description text overflow via an ellipsis.
2257 hideDescriptionOverflow: {
2262 * Optional language codes for label, match, supporting text, and description.
2264 * If included, that language code will be added as a `lang` attribute to the element
2265 * wrapping that text node.
2274 * MenuItems inside a MenuButton can also support an "action" prop
2281 * Whether this menu is in multiselect mode.
2290 * Emitted when the menu item becomes selected, active or highlighted in response to
2291 * user interaction. Handled in the Menu component.
2293 * @property {MenuState} menuState State to change
2294 * @property {boolean} setState Whether to set that state to this menu item
2298 setup: (props, { emit }) => {
2299 const onMouseMove = () => {
2300 if (!props.highlighted) {
2301 emit("change", "highlighted", true);
2304 const onMouseLeave = () => {
2305 emit("change", "highlighted", false);
2307 const onMouseDown = (e) => {
2308 if (e.button === 0) {
2309 emit("change", "active", true);
2312 const onClick = () => {
2313 emit("change", "selected", true);
2315 const highlightQuery = computed(() => props.searchQuery.length > 0);
2316 const rootClasses = computed(() => ({
2317 "cdx-menu-item--selected": props.selected,
2318 // Only show the active visual state when the menu item is both active and
2319 // highlighted. This means, on mousedown -> mouseleave, the menu item is still
2320 // technically tracked by the menu as active, but will not appear active to the
2321 // user. This also means in the case of mousedown -> mouseleave -> mouseenter, the
2322 // menu item will appear active again, and on click (releasing the mouse button),
2323 // the item will be selected.
2324 "cdx-menu-item--active": props.active && props.highlighted,
2325 "cdx-menu-item--highlighted": props.highlighted,
2326 "cdx-menu-item--destructive": props.action && props.action === "destructive",
2327 "cdx-menu-item--enabled": !props.disabled,
2328 "cdx-menu-item--disabled": props.disabled,
2329 "cdx-menu-item--highlight-query": highlightQuery.value,
2330 "cdx-menu-item--bold-label": props.boldLabel,
2331 "cdx-menu-item--has-description": !!props.description,
2332 "cdx-menu-item--hide-description-overflow": props.hideDescriptionOverflow
2334 const contentTag = computed(() => props.url ? "a" : "span");
2335 const title = computed(() => props.label || String(props.value));
2349 const _hoisted_1$l = ["id", "aria-disabled", "aria-selected", "aria-checked"];
2350 const _hoisted_2$c = { class: "cdx-menu-item__text" };
2351 const _hoisted_3$9 = ["lang"];
2352 const _hoisted_4$6 = ["lang"];
2353 const _hoisted_5$6 = ["lang"];
2354 const _hoisted_6$6 = ["lang"];
2355 function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
2356 const _component_cdx_thumbnail = resolveComponent("cdx-thumbnail");
2357 const _component_cdx_icon = resolveComponent("cdx-icon");
2358 const _component_cdx_search_result_title = resolveComponent("cdx-search-result-title");
2359 return openBlock(), createElementBlock("li", {
2362 class: normalizeClass(["cdx-menu-item", _ctx.rootClasses]),
2363 "aria-disabled": _ctx.disabled,
2364 "aria-selected": _ctx.selected && !_ctx.multiselect ? true : void 0,
2365 "aria-checked": _ctx.selected && _ctx.multiselect ? true : void 0,
2366 onMousemove: _cache[0] || (_cache[0] = (...args) => _ctx.onMouseMove && _ctx.onMouseMove(...args)),
2367 onMouseleave: _cache[1] || (_cache[1] = (...args) => _ctx.onMouseLeave && _ctx.onMouseLeave(...args)),
2368 onMousedown: _cache[2] || (_cache[2] = withModifiers((...args) => _ctx.onMouseDown && _ctx.onMouseDown(...args), ["prevent"])),
2369 onClick: _cache[3] || (_cache[3] = (...args) => _ctx.onClick && _ctx.onClick(...args))
2371 renderSlot(_ctx.$slots, "default", {}, () => [
2372 (openBlock(), createBlock(resolveDynamicComponent(_ctx.contentTag), {
2373 href: _ctx.url ? _ctx.url : void 0,
2374 class: "cdx-menu-item__content"
2376 default: withCtx(() => {
2377 var _a, _b, _c, _d, _e, _f;
2379 _ctx.showThumbnail ? (openBlock(), createBlock(_component_cdx_thumbnail, {
2381 thumbnail: _ctx.thumbnail,
2382 class: "cdx-menu-item__thumbnail"
2383 }, null, 8, ["thumbnail"])) : _ctx.icon ? (openBlock(), createBlock(_component_cdx_icon, {
2386 class: "cdx-menu-item__icon"
2387 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
2388 createElementVNode("span", _hoisted_2$c, [
2389 _ctx.highlightQuery ? (openBlock(), createBlock(_component_cdx_search_result_title, {
2392 "search-query": _ctx.searchQuery,
2393 lang: (_a = _ctx.language) == null ? void 0 : _a.label
2394 }, null, 8, ["title", "search-query", "lang"])) : (openBlock(), createElementBlock("span", {
2396 class: "cdx-menu-item__text__label",
2397 lang: (_b = _ctx.language) == null ? void 0 : _b.label
2402 toDisplayString(_ctx.title),
2406 ], 8, _hoisted_3$9)),
2407 _ctx.match ? (openBlock(), createElementBlock(
2411 createTextVNode(toDisplayString(" ") + " "),
2412 _ctx.highlightQuery ? (openBlock(), createBlock(_component_cdx_search_result_title, {
2415 "search-query": _ctx.searchQuery,
2416 lang: (_c = _ctx.language) == null ? void 0 : _c.match
2417 }, null, 8, ["title", "search-query", "lang"])) : (openBlock(), createElementBlock("span", {
2419 class: "cdx-menu-item__text__match",
2420 lang: (_d = _ctx.language) == null ? void 0 : _d.match
2425 toDisplayString(_ctx.match),
2429 ], 8, _hoisted_4$6))
2432 /* STABLE_FRAGMENT */
2433 )) : createCommentVNode("v-if", true),
2434 _ctx.supportingText ? (openBlock(), createElementBlock(
2438 createTextVNode(toDisplayString(" ") + " "),
2439 createElementVNode("span", {
2440 class: "cdx-menu-item__text__supporting-text",
2441 lang: (_e = _ctx.language) == null ? void 0 : _e.supportingText
2446 toDisplayString(_ctx.supportingText),
2453 /* STABLE_FRAGMENT */
2454 )) : createCommentVNode("v-if", true),
2455 _ctx.description ? (openBlock(), createElementBlock("span", {
2457 class: "cdx-menu-item__text__description",
2458 lang: (_f = _ctx.language) == null ? void 0 : _f.description
2463 toDisplayString(_ctx.description),
2467 ], 8, _hoisted_6$6)) : createCommentVNode("v-if", true)
2469 _ctx.multiselect && _ctx.selected ? (openBlock(), createBlock(_component_cdx_icon, {
2471 icon: _ctx.cdxIconCheck,
2473 class: "cdx-menu-item__selected-icon"
2474 }, null, 8, ["icon"])) : createCommentVNode("v-if", true)
2481 ], 42, _hoisted_1$l);
2483 const CdxMenuItem = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$n]]);
2484 const _sfc_main$m = defineComponent({
2485 name: "CdxProgressBar",
2488 * Whether this is the smaller, inline variant.
2495 * Whether the progress bar is disabled.
2502 setup(props, { attrs }) {
2504 () => !props.inline && !attrs["aria-label"] && !attrs["aria-hidden"],
2505 "CdxProgressBar: Progress bars require one of the following attribute, aria-label or aria-hidden. See documentation on https://doc.wikimedia.org/codex/latest/components/demos/progressbar.html"
2507 const rootClasses = computed(() => ({
2508 "cdx-progress-bar--block": !props.inline,
2509 "cdx-progress-bar--inline": props.inline,
2510 "cdx-progress-bar--enabled": !props.disabled,
2511 "cdx-progress-bar--disabled": props.disabled
2513 const computedAriaHidden = computed(
2514 // Set `aria-hidden` to `true` only when `inline` prop is true.
2515 // Otherwise, don't set the attribute.
2516 () => props.inline ? "true" : void 0
2524 const _hoisted_1$k = ["aria-hidden", "aria-disabled"];
2525 const _hoisted_2$b = /* @__PURE__ */ createElementVNode(
2527 { class: "cdx-progress-bar__bar" },
2532 const _hoisted_3$8 = [
2535 function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
2536 return openBlock(), createElementBlock("div", {
2537 class: normalizeClass(["cdx-progress-bar", _ctx.rootClasses]),
2538 role: "progressbar",
2539 "aria-hidden": _ctx.computedAriaHidden,
2540 "aria-disabled": _ctx.disabled
2541 }, _hoisted_3$8, 10, _hoisted_1$k);
2543 const CdxProgressBar = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$m]]);
2544 function useIntersectionObserver(templateRef, observerOptions) {
2545 const intersectionRef = ref(false);
2546 let mounted = false;
2547 if (typeof window !== "object") {
2548 return intersectionRef;
2550 if (!("IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype)) {
2551 return intersectionRef;
2553 const observer = new window.IntersectionObserver(
2555 const entry = entries[0];
2557 intersectionRef.value = entry.isIntersecting;
2564 if (templateRef.value) {
2565 observer.observe(templateRef.value);
2570 observer.disconnect();
2572 watch(templateRef, (newElement) => {
2576 observer.disconnect();
2577 intersectionRef.value = false;
2579 observer.observe(newElement);
2582 return intersectionRef;
2584 function selectedIsArray(selected) {
2585 return selected !== null && Array.isArray(selected);
2587 function isMenuGroupData(menuEntry) {
2588 return "items" in menuEntry;
2590 const _sfc_main$l = defineComponent({
2598 * Attributes, besides class and style, will be passed to the <ul> element.
2600 inheritAttrs: false,
2603 * Menu items and menu group definitions.
2605 * Menu groups and individual menu items will be output in the order they appear here.
2612 * Interactive footer item.
2614 * This is a special menu item which is pinned to the bottom of the menu. When scrolling is
2615 * enabled within the menu, the footer item will always be visible at the bottom of the
2616 * menu. When scrolling is not enabled, the footer item will simply appear as the last menu
2619 * The footer item is selectable, like other menu items.
2626 * Value(s) of the selected menu item(s). A single value for single-select, or an array of
2627 * values for multi-select.
2629 * Must be bound with `v-model:selected`.
2631 * The property should be initialized to `null` (for single-select) or an empty array (for
2632 * multi-select) rather than using a falsy value.
2635 // eslint-disable-next-line max-len
2636 type: [String, Number, Array, null],
2640 * Whether the menu is expanded. Must be bound with `v-model:expanded`.
2647 * Whether to display pending state indicators. Meant to indicate that new menu items are
2648 * being fetched or computed.
2650 * When true, the menu will expand if not already expanded, and an inline progress bar will
2651 * display. If there are no menu items yet, a message can be displayed in the `pending`
2652 * slot, e.g. "Loading results".
2659 * Limit the number of menu items to display before scrolling.
2661 * Setting this prop to anything falsy will show all menu items.
2663 * By default, all menu items are shown.
2670 * Whether menu item thumbnails (or a placeholder icon) should be displayed.
2677 * Whether to bold menu item labels.
2684 * Whether to hide description text overflow via an ellipsis.
2686 hideDescriptionOverflow: {
2691 * The search query to be highlighted within the menu items' titles.
2698 * Whether to show the `no-results` slot content.
2700 * The Menu component automatically shows this slot when there is content in the
2701 * `no-results` slot and there are zero menu items. However, some components may need to
2702 * customize this behavior, e.g. to show the slot even when there is at least one menu item.
2703 * This prop can be used to override the default Menu behavior.
2706 * `null` (default): the `no-results` slot will display only if there are zero menu items.
2707 * `true`: the `no-results` slot will display, regardless of number of menu items.
2708 * `false`: the `no-results` slot will not display, regardless of number of menu items.
2710 showNoResultsSlot: {
2716 // Don't remove the spaces in the "string | number | null" type below; removing these
2717 // spaces causes the documentation to render the type as "union" instead.
2718 // Keep property descriptions on a single line or they will get cut off.
2720 * When the selected menu item changes.
2722 * Property will be a single value or `null` in single-select mode, or an array of values or
2723 * an empty array in multiselect mode.
2725 * @property {MenuItemValue | MenuItemValue[] | null} selectedValue selected value or values
2729 * When the menu opens or closes.
2731 * @property {boolean} newValue The new expanded state (true for open, false for closed)
2735 * When a menu item is clicked.
2737 * Typically, components with menus will respond to the selected value change, but
2738 * occasionally, a component might want to react specifically when a menu item is clicked.
2740 * @property {MenuItemDataWithId} menuItem The menu item that was clicked
2744 * When a menu item is highlighted via keyboard navigation.
2746 * @property {MenuItemDataWithId} highlightedMenuItem The menu item
2749 "menu-item-keyboard-navigation",
2751 * When the user scrolls towards the bottom of the menu.
2753 * If it is possible to add or load more menu items, then now would be a good moment
2754 * so that the user can experience infinite scrolling.
2761 "getHighlightedMenuItem",
2762 "getHighlightedViaKeyboard",
2763 "getComputedMenuItems",
2764 "delegateKeyNavigation"
2766 setup(props, { emit, slots, attrs }) {
2767 const computedMenuEntries = computed(() => {
2768 const menuItemsWithFooter = props.footer && props.menuItems ? [...props.menuItems, props.footer] : props.menuItems;
2769 const getMenuItemWithId = (menuItem) => __spreadProps(__spreadValues({}, menuItem), {
2770 id: useGeneratedId("menu-item")
2772 return menuItemsWithFooter.map((menuEntry) => {
2773 if (isMenuGroupData(menuEntry)) {
2774 return __spreadProps(__spreadValues({}, menuEntry), {
2775 id: useGeneratedId("menu-group"),
2776 items: menuEntry.items.map((subItem) => getMenuItemWithId(subItem))
2779 return getMenuItemWithId(menuEntry);
2783 const computedMenuItems = computed(() => {
2785 computedMenuEntries.value.forEach((menuEntry) => {
2786 if (isMenuGroupData(menuEntry)) {
2787 items.push(...menuEntry.items);
2789 items.push(menuEntry);
2794 const computedShowNoResultsSlot = computed(() => {
2795 if (!slots["no-results"]) {
2798 if (props.showNoResultsSlot !== null) {
2799 return props.showNoResultsSlot;
2801 return computedMenuItems.value.length === 0;
2803 const highlightedMenuItem = ref(null);
2804 const highlightedViaKeyboard = ref(false);
2805 const activeMenuItem = ref(null);
2806 const ariaRelevant = "additions removals";
2808 let keyBufferTimeout = null;
2809 function clearKeyBuffer() {
2811 if (keyBufferTimeout !== null) {
2812 clearTimeout(keyBufferTimeout);
2813 keyBufferTimeout = null;
2816 function resetKeyBufferTimeout() {
2817 if (keyBufferTimeout !== null) {
2818 clearTimeout(keyBufferTimeout);
2820 keyBufferTimeout = setTimeout(clearKeyBuffer, 1500);
2822 function findFirstSelectedMenuItem() {
2824 return (_a = computedMenuItems.value.find(
2825 (menuItem) => selectedIsArray(props.selected) ? props.selected.indexOf(menuItem.value) !== -1 : menuItem.value === props.selected
2826 )) != null ? _a : null;
2828 const isMultiselect = computed(() => selectedIsArray(props.selected));
2829 function isItemSelected(value) {
2830 return selectedIsArray(props.selected) ? props.selected.indexOf(value) !== -1 : value === props.selected;
2832 function updateSelected(value) {
2833 if (selectedIsArray(props.selected)) {
2834 const newSelected = props.selected.indexOf(value) === -1 ? props.selected.concat(value) : props.selected.filter((item) => item !== value);
2835 emit("update:selected", newSelected);
2837 emit("update:selected", value);
2840 function handleMenuItemChange(menuState, menuItem) {
2841 if (menuItem && menuItem.disabled) {
2844 switch (menuState) {
2847 updateSelected(menuItem.value);
2849 if (!isMultiselect.value) {
2850 emit("update:expanded", false);
2852 activeMenuItem.value = null;
2855 highlightedMenuItem.value = menuItem != null ? menuItem : null;
2856 highlightedViaKeyboard.value = false;
2858 case "highlightedViaKeyboard":
2859 highlightedMenuItem.value = menuItem != null ? menuItem : null;
2860 highlightedViaKeyboard.value = true;
2863 activeMenuItem.value = menuItem != null ? menuItem : null;
2867 const highlightedMenuItemIndex = computed(() => {
2868 if (highlightedMenuItem.value === null) {
2871 return computedMenuItems.value.findIndex(
2872 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
2873 (menuItem) => menuItem.value === highlightedMenuItem.value.value
2876 function handleHighlightViaKeyboard(newHighlightedMenuItem) {
2877 if (!newHighlightedMenuItem) {
2880 handleMenuItemChange("highlightedViaKeyboard", newHighlightedMenuItem);
2881 emit("menu-item-keyboard-navigation", newHighlightedMenuItem);
2883 function highlightPrev(highlightedIndex) {
2885 const findPrevEnabled = (startIndex) => {
2886 for (let index = startIndex - 1; index >= 0; index--) {
2887 if (!computedMenuItems.value[index].disabled) {
2888 return computedMenuItems.value[index];
2892 highlightedIndex = highlightedIndex != null ? highlightedIndex : computedMenuItems.value.length;
2893 const prev = (_a = findPrevEnabled(highlightedIndex)) != null ? _a : findPrevEnabled(computedMenuItems.value.length);
2894 handleHighlightViaKeyboard(prev);
2896 function highlightNext(highlightedIndex) {
2898 const findNextEnabled = (startIndex) => computedMenuItems.value.find(
2899 (item, index) => !item.disabled && index > startIndex
2901 highlightedIndex = highlightedIndex != null ? highlightedIndex : -1;
2902 const next = (_a = findNextEnabled(highlightedIndex)) != null ? _a : findNextEnabled(-1);
2903 handleHighlightViaKeyboard(next);
2905 function handleCharacterNavigation(e) {
2906 if (e.key === "Clear") {
2910 if (e.key === "Backspace") {
2911 keyBuffer = keyBuffer.slice(0, -1);
2912 resetKeyBufferTimeout();
2915 if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {
2916 if (!props.expanded) {
2917 emit("update:expanded", true);
2919 if (e.key === " " && keyBuffer.length < 1) {
2922 keyBuffer += e.key.toLowerCase();
2923 const isRepeatedCharacter = keyBuffer.length > 1 && keyBuffer.split("").every((char) => char === keyBuffer[0]);
2924 let itemsToMatch = computedMenuItems.value;
2925 let stringToMatch = keyBuffer;
2926 if (isRepeatedCharacter && highlightedMenuItemIndex.value !== void 0) {
2927 itemsToMatch = itemsToMatch.slice(highlightedMenuItemIndex.value + 1).concat(itemsToMatch.slice(0, highlightedMenuItemIndex.value));
2928 stringToMatch = keyBuffer[0];
2930 const matchingItem = itemsToMatch.find(
2933 return !item.disabled && String((_a = item.label) != null ? _a : item.value).toLowerCase().startsWith(stringToMatch);
2937 handleMenuItemChange("highlightedViaKeyboard", matchingItem);
2938 maybeScrollIntoView();
2940 resetKeyBufferTimeout();
2945 function handleKeyNavigation(e, { prevent = true, characterNavigation = false } = {}) {
2946 if (characterNavigation) {
2947 if (handleCharacterNavigation(e)) {
2953 function maybePrevent() {
2956 e.stopPropagation();
2963 if (props.expanded) {
2964 if (highlightedMenuItem.value && highlightedViaKeyboard.value) {
2965 updateSelected(highlightedMenuItem.value.value);
2967 if (!isMultiselect.value) {
2968 emit("update:expanded", false);
2971 emit("update:expanded", true);
2975 if (props.expanded) {
2976 if (highlightedMenuItem.value && highlightedViaKeyboard.value && !isMultiselect.value) {
2977 updateSelected(highlightedMenuItem.value.value);
2978 emit("update:expanded", false);
2984 if (props.expanded) {
2985 if (highlightedMenuItem.value === null) {
2986 handleMenuItemChange("highlightedViaKeyboard", findFirstSelectedMenuItem());
2988 highlightPrev(highlightedMenuItemIndex.value);
2990 emit("update:expanded", true);
2992 maybeScrollIntoView();
2996 if (props.expanded) {
2997 if (highlightedMenuItem.value === null) {
2998 handleMenuItemChange("highlightedViaKeyboard", findFirstSelectedMenuItem());
3000 highlightNext(highlightedMenuItemIndex.value);
3002 emit("update:expanded", true);
3004 maybeScrollIntoView();
3008 if (props.expanded) {
3009 if (highlightedMenuItem.value === null) {
3010 handleMenuItemChange("highlightedViaKeyboard", findFirstSelectedMenuItem());
3014 emit("update:expanded", true);
3016 maybeScrollIntoView();
3020 if (props.expanded) {
3021 if (highlightedMenuItem.value === null) {
3022 handleMenuItemChange("highlightedViaKeyboard", findFirstSelectedMenuItem());
3026 emit("update:expanded", true);
3028 maybeScrollIntoView();
3032 emit("update:expanded", false);
3038 function onMouseUp() {
3039 handleMenuItemChange("active", null);
3041 const menuItemElements = [];
3042 const loadMoreTriggerElement = ref(void 0);
3043 const isTriggerVisible = useIntersectionObserver(
3044 loadMoreTriggerElement,
3047 watch(isTriggerVisible, (value) => {
3052 function assignTemplateRef(templateRef, index) {
3054 menuItemElements[index] = templateRef.$el;
3055 const visibleItemLimit = props.visibleItemLimit;
3056 if (!visibleItemLimit || props.menuItems.length < visibleItemLimit) {
3059 const loadMoreThreshold = Math.min(
3061 Math.max(2, Math.floor(0.2 * props.menuItems.length))
3063 if (index === props.menuItems.length - loadMoreThreshold) {
3064 loadMoreTriggerElement.value = templateRef.$el;
3068 const menuListbox = ref();
3069 function maybeScrollIntoView() {
3070 const isListboxScrollable = menuListbox.value && menuListbox.value.scrollHeight > menuListbox.value.clientHeight;
3071 if (highlightedMenuItemIndex.value === void 0 || !isListboxScrollable) {
3074 const scrollIndex = highlightedMenuItemIndex.value >= 0 ? highlightedMenuItemIndex.value : 0;
3075 menuItemElements[scrollIndex].scrollIntoView({
3080 const maxMenuHeight = ref(null);
3081 const footerHeight = ref(null);
3082 function resizeMenu() {
3083 return __async(this, null, function* () {
3085 updateFooterHeight();
3086 updateMaxMenuHeight();
3088 maybeScrollIntoView();
3091 function updateFooterHeight() {
3093 const footerElement = menuItemElements[menuItemElements.length - 1];
3094 footerHeight.value = footerElement.scrollHeight;
3096 footerHeight.value = null;
3099 function updateMaxMenuHeight() {
3100 if (!props.visibleItemLimit || menuItemElements.length <= props.visibleItemLimit) {
3101 maxMenuHeight.value = null;
3104 const firstMenuItemTop = menuItemElements[0].getBoundingClientRect().top;
3105 const firstHiddenMenuItemTop = menuItemElements[props.visibleItemLimit].getBoundingClientRect().top;
3106 maxMenuHeight.value = firstHiddenMenuItemTop - firstMenuItemTop + 2;
3108 function getGroupWrapperClasses(group) {
3110 "cdx-menu__group-wrapper--hide-label": !!group.hideLabel
3113 function getMenuItemIndex(menuItem) {
3114 return computedMenuItems.value.indexOf(menuItem);
3116 function getMenuItemBindings(menuItem) {
3118 return __spreadValues({
3119 selected: isItemSelected(menuItem.value),
3120 active: menuItem.value === ((_a = activeMenuItem.value) == null ? void 0 : _a.value),
3121 highlighted: menuItem.value === ((_b = highlightedMenuItem.value) == null ? void 0 : _b.value),
3122 showThumbnail: props.showThumbnail,
3123 boldLabel: props.boldLabel,
3124 hideDescriptionOverflow: props.hideDescriptionOverflow,
3125 searchQuery: props.searchQuery,
3126 multiselect: isMultiselect.value
3129 function getMenuItemHandlers(menuItem) {
3131 change: (menuState, setState) => handleMenuItemChange(menuState, setState ? menuItem : null),
3132 click: () => emit("menu-item-click", menuItem)
3135 function getSlotBindings(menuItem) {
3139 active: menuItem.value === ((_a = activeMenuItem.value) == null ? void 0 : _a.value) && menuItem.value === ((_b = highlightedMenuItem.value) == null ? void 0 : _b.value)
3143 document.addEventListener("mouseup", onMouseUp);
3146 document.removeEventListener("mouseup", onMouseUp);
3148 watch(toRef(props, "expanded"), (newVal) => __async(this, null, function* () {
3150 const selectedMenuItem = findFirstSelectedMenuItem();
3151 if (selectedMenuItem && !highlightedMenuItem.value) {
3152 handleMenuItemChange("highlighted", selectedMenuItem);
3156 handleMenuItemChange("highlighted", null);
3159 watch(toRef(props, "menuItems"), (newPropMenuItems) => __async(this, null, function* () {
3160 if (newPropMenuItems.length < menuItemElements.length) {
3161 menuItemElements.length = newPropMenuItems.length;
3163 if (props.expanded) {
3166 }), { deep: true });
3167 const listBoxStyle = computed(() => ({
3168 "max-height": maxMenuHeight.value ? "".concat(maxMenuHeight.value, "px") : void 0,
3169 "margin-bottom": footerHeight.value ? "".concat(footerHeight.value, "px") : void 0
3171 const internalClasses = computed(() => ({
3172 "cdx-menu--has-footer": !!props.footer
3178 } = useSplitAttributes(attrs, internalClasses);
3185 computedMenuEntries,
3187 computedShowNoResultsSlot,
3188 highlightedMenuItem,
3189 highlightedViaKeyboard,
3190 handleMenuItemChange,
3191 handleKeyNavigation,
3195 getGroupWrapperClasses,
3197 getMenuItemBindings,
3198 getMenuItemHandlers,
3204 // These must be in the methods block, not in the setup function, otherwise their documentation
3205 // won't be picked up by vue-docgen
3208 * Returns whether the menu is expanded.
3213 return this.expanded;
3216 * Get the highlighted menu item, if any.
3218 * The parent component should set `aria-activedescendant` to the `.id` property of the
3219 * object returned by this method. If this method returns null, `aria-activedescendant`
3220 * should not be set.
3223 * @return {MenuItemDataWithId|null} The highlighted menu item,
3224 * or null if no item is highlighted or if the menu is closed.
3226 getHighlightedMenuItem() {
3227 return this.expanded ? this.highlightedMenuItem : null;
3230 * Get whether the last highlighted item was highlighted via the keyboard.
3233 * @return {boolean} Whether the last highlighted menu item was highlighted via keyboard.
3235 getHighlightedViaKeyboard() {
3236 return this.highlightedViaKeyboard;
3239 * Get the computed menu items with IDs (without menu groups).
3242 * @return {MenuItemDataWithId[]} List of current menu items without menu groups.
3244 getComputedMenuItems() {
3245 return this.computedMenuItems;
3248 * Ensure no menu item is active. This unsets the active item if there is one.
3253 this.handleMenuItemChange("active", null);
3256 * Handles all necessary keyboard navigation.
3258 * The parent component should listen for keydown events on its focusable element,
3259 * and pass those events to this method. Events for arrow keys, tab and enter are handled
3260 * by this method. If a different key was pressed, this method will return false to indicate
3261 * that it didn't handle the event.
3264 * @param event {KeyboardEvent} Keydown event object
3266 * @param options.prevent {boolean} If false, do not call e.preventDefault() or
3267 * e.stopPropagation()
3268 * @param options.characterNavigation {boolean}
3269 * @return Whether the event was handled
3271 delegateKeyNavigation(event, { prevent = true, characterNavigation = false } = {}) {
3272 return this.handleKeyNavigation(event, { prevent, characterNavigation });
3276 const _hoisted_1$j = ["aria-live", "aria-relevant", "aria-multiselectable"];
3277 const _hoisted_2$a = {
3279 class: "cdx-menu__pending cdx-menu-item"
3281 const _hoisted_3$7 = {
3283 class: "cdx-menu__no-results cdx-menu-item",
3286 const _hoisted_4$5 = ["aria-labelledby", "aria-describedby"];
3287 const _hoisted_5$5 = { class: "cdx-menu__group__meta" };
3288 const _hoisted_6$5 = { class: "cdx-menu__group__meta__text" };
3289 const _hoisted_7$2 = ["id"];
3290 const _hoisted_8$1 = ["id"];
3291 function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
3292 const _component_cdx_icon = resolveComponent("cdx-icon");
3293 const _component_cdx_menu_item = resolveComponent("cdx-menu-item");
3294 const _component_cdx_progress_bar = resolveComponent("cdx-progress-bar");
3295 return withDirectives((openBlock(), createElementBlock(
3298 class: normalizeClass(["cdx-menu", _ctx.rootClasses]),
3299 style: normalizeStyle(_ctx.rootStyle)
3302 createElementVNode("ul", mergeProps({
3304 class: "cdx-menu__listbox",
3306 style: _ctx.listBoxStyle,
3307 "aria-live": _ctx.showPending ? "polite" : void 0,
3308 "aria-relevant": _ctx.showPending ? _ctx.ariaRelevant : void 0,
3309 "aria-multiselectable": _ctx.isMultiselect ? true : void 0
3310 }, _ctx.otherAttrs), [
3311 _ctx.showPending && _ctx.computedMenuItems.length === 0 && _ctx.$slots.pending ? (openBlock(), createElementBlock("li", _hoisted_2$a, [
3312 renderSlot(_ctx.$slots, "pending")
3313 ])) : createCommentVNode("v-if", true),
3314 _ctx.computedShowNoResultsSlot ? (openBlock(), createElementBlock("li", _hoisted_3$7, [
3315 renderSlot(_ctx.$slots, "no-results")
3316 ])) : createCommentVNode("v-if", true),
3317 (openBlock(true), createElementBlock(
3320 renderList(_ctx.computedMenuEntries, (menuEntry, index) => {
3321 return openBlock(), createElementBlock(
3325 _ctx.isMenuGroupData(menuEntry) ? (openBlock(), createElementBlock(
3329 class: normalizeClass(["cdx-menu__group-wrapper", _ctx.getGroupWrapperClasses(menuEntry)])
3332 createElementVNode("ul", {
3333 class: "cdx-menu__group",
3335 "aria-labelledby": menuEntry.id + "-label",
3336 "aria-describedby": menuEntry.id + "-description"
3338 createElementVNode("span", _hoisted_5$5, [
3339 menuEntry.icon ? (openBlock(), createBlock(_component_cdx_icon, {
3341 class: "cdx-menu__group__icon",
3342 icon: menuEntry.icon
3343 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
3344 createElementVNode("span", _hoisted_6$5, [
3345 createElementVNode("span", {
3346 id: menuEntry.id + "-label",
3347 class: "cdx-menu__group__label"
3348 }, toDisplayString(menuEntry.label), 9, _hoisted_7$2),
3349 menuEntry.description ? (openBlock(), createElementBlock("span", {
3351 id: menuEntry.id + "-description",
3352 class: "cdx-menu__group__description"
3353 }, toDisplayString(menuEntry.description), 9, _hoisted_8$1)) : createCommentVNode("v-if", true)
3356 (openBlock(true), createElementBlock(
3359 renderList(menuEntry.items, (menuItemInGroup) => {
3360 return openBlock(), createBlock(
3361 _component_cdx_menu_item,
3363 key: menuItemInGroup.value,
3365 ref: (ref2) => _ctx.assignTemplateRef(ref2, _ctx.getMenuItemIndex(menuItemInGroup)),
3366 class: "cdx-menu__group__item"
3367 }, _ctx.getMenuItemBindings(menuItemInGroup), toHandlers(_ctx.getMenuItemHandlers(menuItemInGroup))),
3369 default: withCtx(() => [
3370 renderSlot(_ctx.$slots, "default", mergeProps({ ref_for: true }, _ctx.getSlotBindings(menuItemInGroup)))
3376 /* FULL_PROPS, DYNAMIC_SLOTS */
3380 /* KEYED_FRAGMENT */
3386 )) : (openBlock(), createBlock(
3387 _component_cdx_menu_item,
3391 ref: (ref2) => _ctx.assignTemplateRef(ref2, _ctx.getMenuItemIndex(menuEntry))
3392 }, _ctx.getMenuItemBindings(menuEntry), toHandlers(_ctx.getMenuItemHandlers(menuEntry))),
3394 default: withCtx(() => [
3395 renderSlot(_ctx.$slots, "default", mergeProps({ ref_for: true }, _ctx.getSlotBindings(menuEntry)))
3401 /* FULL_PROPS, DYNAMIC_SLOTS */
3405 /* STABLE_FRAGMENT */
3409 /* KEYED_FRAGMENT */
3411 _ctx.showPending ? (openBlock(), createBlock(_component_cdx_progress_bar, {
3413 class: "cdx-menu__progress-bar",
3415 })) : createCommentVNode("v-if", true)
3416 ], 16, _hoisted_1$j)
3421 [vShow, _ctx.expanded]
3424 const CdxMenu = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$l]]);
3425 const textInputTypeValidator = makeStringTypeValidator(TextInputTypes);
3426 const statusValidator$8 = makeStringTypeValidator(ValidationStatusTypes);
3427 const _sfc_main$k = defineComponent({
3428 name: "CdxTextInput",
3429 components: { CdxIcon },
3431 * We want the input to inherit attributes, not the root element.
3433 inheritAttrs: false,
3443 * Current value of the input.
3445 * Provided by `v-model` binding in the parent component.
3448 type: [String, Number],
3452 * `type` attribute of the input.
3454 * @values 'text', 'search', 'number', 'email', 'password', 'tel', 'url',
3455 * 'week', 'month', 'date', 'datetime-local', 'time'
3460 validator: textInputTypeValidator
3463 * `status` attribute of the input.
3468 validator: statusValidator$8
3471 * Whether the input is disabled.
3478 * An icon at the start of the input element. Similar to a `::before` pseudo-element.
3481 type: [String, Object],
3485 * An icon at the end of the input element. Similar to an `::after` pseudo-element.
3488 type: [String, Object],
3492 * Add a clear button at the end of the input element.
3494 * When the clear button is pressed, the input's value is set to an empty string.
3495 * The clear button is displayed when input text is present.
3504 * When the input value changes
3506 * @property {string | number} modelValue The new model value
3508 "update:modelValue",
3510 * When the user presses a key.
3512 * This event is not emitted when the user presses the Home or End key (T314728),
3513 * but is emitted for Ctrl/Cmd+Home and Ctrl/Cmd+End.
3515 * @property {KeyboardEvent}
3519 * When the input value changes via direct use of the input
3521 * @property {InputEvent} event
3525 * When an input value change is committed by the user (e.g. on blur)
3527 * @property {Event} event
3531 * When the input comes into focus
3533 * @property {FocusEvent} event
3537 * When the input loses focus
3539 * @property {FocusEvent} event
3543 * When the input value is cleared through the use of the clear button
3545 * @property {MouseEvent} event
3549 * When the input value is invalid according to the input's constraint
3550 * attributes (e.g. min, max, pattern). See:
3551 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/invalid_event
3553 * @property {Event} event
3557 setup(props, { emit, attrs }) {
3558 const idAttribute = attrs.id;
3564 toRef(props, "disabled"),
3565 toRef(props, "status"),
3568 const descriptionId = inject(FieldDescriptionIdKey, void 0);
3569 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
3570 const isClearable = computed(
3571 () => props.clearable && !!wrappedModel.value && !computedDisabled.value
3573 const internalClasses = computed(() => ({
3574 "cdx-text-input--has-start-icon": !!props.startIcon,
3575 "cdx-text-input--has-end-icon": !!props.endIcon,
3576 "cdx-text-input--clearable": isClearable.value,
3577 ["cdx-text-input--status-".concat(computedStatus.value)]: true
3583 } = useSplitAttributes(attrs, internalClasses);
3584 const otherAttrsMinusId = computed(() => {
3585 const _a = otherAttrs.value, { id } = _a, everythingElse = __objRest(_a, ["id"]);
3586 return everythingElse;
3588 const inputClasses = computed(() => ({
3589 "cdx-text-input__input--has-value": !!wrappedModel.value
3591 const onClear = (event) => {
3592 wrappedModel.value = "";
3593 emit("clear", event);
3595 const onKeydown = (event) => {
3596 if ((event.key === "Home" || event.key === "End") && !event.ctrlKey && !event.metaKey) {
3599 emit("keydown", event);
3601 const onInput = (event) => {
3602 emit("input", event);
3604 const onChange = (event) => {
3605 emit("change", event);
3607 const onFocus = (event) => {
3608 emit("focus", event);
3610 const onBlur = (event) => {
3611 emit("blur", event);
3613 const shouldPreventDefault = ref(true);
3614 const onInvalid = (event, doPreventDefault) => {
3615 if (doPreventDefault) {
3616 event.preventDefault();
3618 emit("invalid", event);
3619 shouldPreventDefault.value = true;
3638 shouldPreventDefault,
3643 // These must be in the methods block, not in the setup function, otherwise their documentation
3644 // won't be picked up by vue-docgen
3647 * Focus the component's input element.
3652 const input = this.$refs.input;
3656 * Blur the component's input element.
3661 const input = this.$refs.input;
3665 * Check the validity of the input element according to its constraint attributes. Emits an
3666 * 'invalid' event if the input is invalid. See:
3667 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/checkValidity
3670 * @return {boolean} Whether the input is valid
3673 const input = this.$refs.input;
3674 return input.checkValidity();
3677 * Check the validity of the input element and report it as a pop up on the UI. See:
3678 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/reportValidity
3681 * @return {boolean} Whether the input is valid
3684 this.shouldPreventDefault = false;
3685 const input = this.$refs.input;
3686 return input.reportValidity();
3689 * Set custom validity and message for the input element. See:
3690 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity
3693 * @param {string} message The custom validation message to set
3695 setCustomValidity(message) {
3696 const input = this.$refs.input;
3697 input.setCustomValidity(message);
3701 const _hoisted_1$i = ["id", "type", "aria-describedby", "disabled"];
3702 function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
3703 const _component_cdx_icon = resolveComponent("cdx-icon");
3704 return openBlock(), createElementBlock(
3707 class: normalizeClass(["cdx-text-input", _ctx.rootClasses]),
3708 style: normalizeStyle(_ctx.rootStyle)
3711 withDirectives(createElementVNode("input", mergeProps({
3712 id: _ctx.computedInputId,
3714 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
3715 class: ["cdx-text-input__input", _ctx.inputClasses]
3716 }, _ctx.otherAttrsMinusId, {
3717 type: _ctx.inputType,
3718 "aria-describedby": _ctx.descriptionId,
3719 disabled: _ctx.computedDisabled,
3721 onInput: _cache[1] || (_cache[1] = (...args) => _ctx.onInput && _ctx.onInput(...args)),
3722 onChange: _cache[2] || (_cache[2] = (...args) => _ctx.onChange && _ctx.onChange(...args)),
3723 onFocus: _cache[3] || (_cache[3] = (...args) => _ctx.onFocus && _ctx.onFocus(...args)),
3724 onBlur: _cache[4] || (_cache[4] = (...args) => _ctx.onBlur && _ctx.onBlur(...args)),
3725 onKeydown: _cache[5] || (_cache[5] = (...args) => _ctx.onKeydown && _ctx.onKeydown(...args)),
3726 onInvalid: _cache[6] || (_cache[6] = (e) => _ctx.onInvalid(e, _ctx.shouldPreventDefault))
3727 }), null, 16, _hoisted_1$i), [
3728 [vModelDynamic, _ctx.wrappedModel]
3730 _ctx.startIcon ? (openBlock(), createBlock(_component_cdx_icon, {
3732 icon: _ctx.startIcon,
3733 class: "cdx-text-input__icon-vue cdx-text-input__start-icon"
3734 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
3735 _ctx.endIcon ? (openBlock(), createBlock(_component_cdx_icon, {
3738 class: "cdx-text-input__icon-vue cdx-text-input__end-icon"
3739 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
3740 _ctx.isClearable ? (openBlock(), createBlock(_component_cdx_icon, {
3742 icon: _ctx.cdxIconClear,
3743 class: "cdx-text-input__icon-vue cdx-text-input__clear-icon",
3744 onMousedown: _cache[7] || (_cache[7] = withModifiers(() => {
3746 onClick: _ctx.onClear
3747 }, null, 8, ["icon", "onClick"])) : createCommentVNode("v-if", true)
3753 const CdxTextInput = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$k]]);
3754 const sides = ["top", "right", "bottom", "left"];
3755 const min = Math.min;
3756 const max = Math.max;
3757 const round = Math.round;
3758 const floor = Math.floor;
3759 const createCoords = (v) => ({
3763 const oppositeSideMap = {
3769 const oppositeAlignmentMap = {
3773 function clamp(start, value, end) {
3774 return max(start, min(value, end));
3776 function evaluate(value, param) {
3777 return typeof value === "function" ? value(param) : value;
3779 function getSide(placement) {
3780 return placement.split("-")[0];
3782 function getAlignment(placement) {
3783 return placement.split("-")[1];
3785 function getOppositeAxis(axis) {
3786 return axis === "x" ? "y" : "x";
3788 function getAxisLength(axis) {
3789 return axis === "y" ? "height" : "width";
3791 function getSideAxis(placement) {
3792 return ["top", "bottom"].includes(getSide(placement)) ? "y" : "x";
3794 function getAlignmentAxis(placement) {
3795 return getOppositeAxis(getSideAxis(placement));
3797 function getAlignmentSides(placement, rects, rtl) {
3798 if (rtl === void 0) {
3801 const alignment = getAlignment(placement);
3802 const alignmentAxis = getAlignmentAxis(placement);
3803 const length = getAxisLength(alignmentAxis);
3804 let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
3805 if (rects.reference[length] > rects.floating[length]) {
3806 mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
3808 return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
3810 function getExpandedPlacements(placement) {
3811 const oppositePlacement = getOppositePlacement(placement);
3812 return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
3814 function getOppositeAlignmentPlacement(placement) {
3815 return placement.replace(/start|end/g, (alignment) => oppositeAlignmentMap[alignment]);
3817 function getSideList(side, isStart, rtl) {
3818 const lr = ["left", "right"];
3819 const rl = ["right", "left"];
3820 const tb = ["top", "bottom"];
3821 const bt = ["bottom", "top"];
3826 return isStart ? rl : lr;
3827 return isStart ? lr : rl;
3830 return isStart ? tb : bt;
3835 function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
3836 const alignment = getAlignment(placement);
3837 let list = getSideList(getSide(placement), direction === "start", rtl);
3839 list = list.map((side) => side + "-" + alignment);
3840 if (flipAlignment) {
3841 list = list.concat(list.map(getOppositeAlignmentPlacement));
3846 function getOppositePlacement(placement) {
3847 return placement.replace(/left|right|bottom|top/g, (side) => oppositeSideMap[side]);
3849 function expandPaddingObject(padding) {
3850 return __spreadValues({
3857 function getPaddingObject(padding) {
3858 return typeof padding !== "number" ? expandPaddingObject(padding) : {
3865 function rectToClientRect(rect) {
3883 function computeCoordsFromPlacement(_ref, placement, rtl) {
3888 const sideAxis = getSideAxis(placement);
3889 const alignmentAxis = getAlignmentAxis(placement);
3890 const alignLength = getAxisLength(alignmentAxis);
3891 const side = getSide(placement);
3892 const isVertical = sideAxis === "y";
3893 const commonX = reference.x + reference.width / 2 - floating.width / 2;
3894 const commonY = reference.y + reference.height / 2 - floating.height / 2;
3895 const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
3901 y: reference.y - floating.height
3907 y: reference.y + reference.height
3912 x: reference.x + reference.width,
3918 x: reference.x - floating.width,
3928 switch (getAlignment(placement)) {
3930 coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
3933 coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
3938 const computePosition$1 = (reference, floating, config) => __async(void 0, null, function* () {
3940 placement = "bottom",
3941 strategy = "absolute",
3945 const validMiddleware = middleware.filter(Boolean);
3946 const rtl = yield platform2.isRTL == null ? void 0 : platform2.isRTL(floating);
3947 let rects = yield platform2.getElementRects({
3955 } = computeCoordsFromPlacement(rects, placement, rtl);
3956 let statefulPlacement = placement;
3957 let middlewareData = {};
3959 for (let i = 0; i < validMiddleware.length; i++) {
3963 } = validMiddleware[i];
3972 initialPlacement: placement,
3973 placement: statefulPlacement,
3977 platform: platform2,
3983 x = nextX != null ? nextX : x;
3984 y = nextY != null ? nextY : y;
3985 middlewareData = __spreadProps(__spreadValues({}, middlewareData), {
3986 [name]: __spreadValues(__spreadValues({}, middlewareData[name]), data)
3988 if (reset && resetCount <= 50) {
3990 if (typeof reset === "object") {
3991 if (reset.placement) {
3992 statefulPlacement = reset.placement;
3995 rects = reset.rects === true ? yield platform2.getElementRects({
4004 } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
4012 placement: statefulPlacement,
4017 function detectOverflow(state, options) {
4018 return __async(this, null, function* () {
4019 var _await$platform$isEle;
4020 if (options === void 0) {
4026 platform: platform2,
4032 boundary = "clippingAncestors",
4033 rootBoundary = "viewport",
4034 elementContext = "floating",
4035 altBoundary = false,
4037 } = evaluate(options, state);
4038 const paddingObject = getPaddingObject(padding);
4039 const altContext = elementContext === "floating" ? "reference" : "floating";
4040 const element = elements[altBoundary ? altContext : elementContext];
4041 const clippingClientRect = rectToClientRect(yield platform2.getClippingRect({
4042 element: ((_await$platform$isEle = yield platform2.isElement == null ? void 0 : platform2.isElement(element)) != null ? _await$platform$isEle : true) ? element : element.contextElement || (yield platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
4047 const rect = elementContext === "floating" ? {
4050 width: rects.floating.width,
4051 height: rects.floating.height
4052 } : rects.reference;
4053 const offsetParent = yield platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating);
4054 const offsetScale = (yield platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? (yield platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
4061 const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? yield platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
4068 top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
4069 bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
4070 left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
4071 right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
4075 const flip$1 = function(options) {
4076 if (options === void 0) {
4083 return __async(this, null, function* () {
4084 var _middlewareData$arrow, _middlewareData$flip;
4090 platform: platform2,
4093 const _a2 = evaluate(options, state), {
4094 mainAxis: checkMainAxis = true,
4095 crossAxis: checkCrossAxis = true,
4096 fallbackPlacements: specifiedFallbackPlacements,
4097 fallbackStrategy = "bestFit",
4098 fallbackAxisSideDirection = "none",
4099 flipAlignment = true
4100 } = _a2, detectOverflowOptions = __objRest(_a2, [
4103 "fallbackPlacements",
4105 "fallbackAxisSideDirection",
4108 if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
4111 const side = getSide(placement);
4112 const initialSideAxis = getSideAxis(initialPlacement);
4113 const isBasePlacement = getSide(initialPlacement) === initialPlacement;
4114 const rtl = yield platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating);
4115 const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
4116 const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
4117 if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
4118 fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
4120 const placements = [initialPlacement, ...fallbackPlacements];
4121 const overflow = yield detectOverflow(state, detectOverflowOptions);
4122 const overflows = [];
4123 let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
4124 if (checkMainAxis) {
4125 overflows.push(overflow[side]);
4127 if (checkCrossAxis) {
4128 const sides2 = getAlignmentSides(placement, rects, rtl);
4129 overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
4131 overflowsData = [...overflowsData, {
4135 if (!overflows.every((side2) => side2 <= 0)) {
4136 var _middlewareData$flip2, _overflowsData$filter;
4137 const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
4138 const nextPlacement = placements[nextIndex];
4139 if (nextPlacement) {
4143 overflows: overflowsData
4146 placement: nextPlacement
4150 let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
4151 if (!resetPlacement) {
4152 switch (fallbackStrategy) {
4154 var _overflowsData$filter2;
4155 const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
4156 if (hasFallbackAxisSideDirection) {
4157 const currentSideAxis = getSideAxis(d.placement);
4158 return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
4159 // reading directions favoring greater width.
4160 currentSideAxis === "y";
4163 }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
4165 resetPlacement = placement2;
4169 case "initialPlacement":
4170 resetPlacement = initialPlacement;
4174 if (placement !== resetPlacement) {
4177 placement: resetPlacement
4187 function getSideOffsets(overflow, rect) {
4189 top: overflow.top - rect.height,
4190 right: overflow.right - rect.width,
4191 bottom: overflow.bottom - rect.height,
4192 left: overflow.left - rect.width
4195 function isAnySideFullyClipped(overflow) {
4196 return sides.some((side) => overflow[side] >= 0);
4198 const hide$1 = function(options) {
4199 if (options === void 0) {
4206 return __async(this, null, function* () {
4210 const _a2 = evaluate(options, state), {
4211 strategy = "referenceHidden"
4212 } = _a2, detectOverflowOptions = __objRest(_a2, [
4216 case "referenceHidden": {
4217 const overflow = yield detectOverflow(state, __spreadProps(__spreadValues({}, detectOverflowOptions), {
4218 elementContext: "reference"
4220 const offsets = getSideOffsets(overflow, rects.reference);
4223 referenceHiddenOffsets: offsets,
4224 referenceHidden: isAnySideFullyClipped(offsets)
4229 const overflow = yield detectOverflow(state, __spreadProps(__spreadValues({}, detectOverflowOptions), {
4232 const offsets = getSideOffsets(overflow, rects.floating);
4235 escapedOffsets: offsets,
4236 escaped: isAnySideFullyClipped(offsets)
4248 function convertValueToCoords(state, options) {
4249 return __async(this, null, function* () {
4252 platform: platform2,
4255 const rtl = yield platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating);
4256 const side = getSide(placement);
4257 const alignment = getAlignment(placement);
4258 const isVertical = getSideAxis(placement) === "y";
4259 const mainAxisMulti = ["left", "top"].includes(side) ? -1 : 1;
4260 const crossAxisMulti = rtl && isVertical ? -1 : 1;
4261 const rawValue = evaluate(options, state);
4266 } = typeof rawValue === "number" ? {
4271 mainAxis: rawValue.mainAxis || 0,
4272 crossAxis: rawValue.crossAxis || 0,
4273 alignmentAxis: rawValue.alignmentAxis
4275 if (alignment && typeof alignmentAxis === "number") {
4276 crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
4278 return isVertical ? {
4279 x: crossAxis * crossAxisMulti,
4280 y: mainAxis * mainAxisMulti
4282 x: mainAxis * mainAxisMulti,
4283 y: crossAxis * crossAxisMulti
4287 const offset$1 = function(options) {
4288 if (options === void 0) {
4295 return __async(this, null, function* () {
4296 var _middlewareData$offse, _middlewareData$arrow;
4303 const diffCoords = yield convertValueToCoords(state, options);
4304 if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
4308 x: x + diffCoords.x,
4309 y: y + diffCoords.y,
4310 data: __spreadProps(__spreadValues({}, diffCoords), {
4318 const shift$1 = function(options) {
4319 if (options === void 0) {
4326 return __async(this, null, function* () {
4332 const _a2 = evaluate(options, state), {
4333 mainAxis: checkMainAxis = true,
4334 crossAxis: checkCrossAxis = false,
4347 } = _a2, detectOverflowOptions = __objRest(_a2, [
4356 const overflow = yield detectOverflow(state, detectOverflowOptions);
4357 const crossAxis = getSideAxis(getSide(placement));
4358 const mainAxis = getOppositeAxis(crossAxis);
4359 let mainAxisCoord = coords[mainAxis];
4360 let crossAxisCoord = coords[crossAxis];
4361 if (checkMainAxis) {
4362 const minSide = mainAxis === "y" ? "top" : "left";
4363 const maxSide = mainAxis === "y" ? "bottom" : "right";
4364 const min2 = mainAxisCoord + overflow[minSide];
4365 const max2 = mainAxisCoord - overflow[maxSide];
4366 mainAxisCoord = clamp(min2, mainAxisCoord, max2);
4368 if (checkCrossAxis) {
4369 const minSide = crossAxis === "y" ? "top" : "left";
4370 const maxSide = crossAxis === "y" ? "bottom" : "right";
4371 const min2 = crossAxisCoord + overflow[minSide];
4372 const max2 = crossAxisCoord - overflow[maxSide];
4373 crossAxisCoord = clamp(min2, crossAxisCoord, max2);
4375 const limitedCoords = limiter.fn(__spreadProps(__spreadValues({}, state), {
4376 [mainAxis]: mainAxisCoord,
4377 [crossAxis]: crossAxisCoord
4379 return __spreadProps(__spreadValues({}, limitedCoords), {
4381 x: limitedCoords.x - x,
4382 y: limitedCoords.y - y,
4384 [mainAxis]: checkMainAxis,
4385 [crossAxis]: checkCrossAxis
4393 const size$1 = function(options) {
4394 if (options === void 0) {
4401 return __async(this, null, function* () {
4402 var _state$middlewareData, _state$middlewareData2;
4406 platform: platform2,
4409 const _a2 = evaluate(options, state), {
4412 } = _a2, detectOverflowOptions = __objRest(_a2, [
4415 const overflow = yield detectOverflow(state, detectOverflowOptions);
4416 const side = getSide(placement);
4417 const alignment = getAlignment(placement);
4418 const isYAxis = getSideAxis(placement) === "y";
4425 if (side === "top" || side === "bottom") {
4427 widthSide = alignment === ((yield platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating)) ? "start" : "end") ? "left" : "right";
4430 heightSide = alignment === "end" ? "top" : "bottom";
4432 const maximumClippingHeight = height - overflow.top - overflow.bottom;
4433 const maximumClippingWidth = width - overflow.left - overflow.right;
4434 const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);
4435 const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);
4436 const noShift = !state.middlewareData.shift;
4437 let availableHeight = overflowAvailableHeight;
4438 let availableWidth = overflowAvailableWidth;
4439 if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {
4440 availableWidth = maximumClippingWidth;
4442 if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {
4443 availableHeight = maximumClippingHeight;
4445 if (noShift && !alignment) {
4446 const xMin = max(overflow.left, 0);
4447 const xMax = max(overflow.right, 0);
4448 const yMin = max(overflow.top, 0);
4449 const yMax = max(overflow.bottom, 0);
4451 availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));
4453 availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));
4456 yield apply(__spreadProps(__spreadValues({}, state), {
4460 const nextDimensions = yield platform2.getDimensions(elements.floating);
4461 if (width !== nextDimensions.width || height !== nextDimensions.height) {
4473 function hasWindow() {
4474 return typeof window !== "undefined";
4476 function getNodeName(node) {
4478 return (node.nodeName || "").toLowerCase();
4482 function getWindow(node) {
4483 var _node$ownerDocument;
4484 return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
4486 function getDocumentElement(node) {
4488 return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
4490 function isNode(value) {
4494 return value instanceof Node || value instanceof getWindow(value).Node;
4496 function isElement(value) {
4500 return value instanceof Element || value instanceof getWindow(value).Element;
4502 function isHTMLElement(value) {
4506 return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
4508 function isShadowRoot(value) {
4509 if (!hasWindow() || typeof ShadowRoot === "undefined") {
4512 return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
4514 function isOverflowElement(element) {
4520 } = getComputedStyle(element);
4521 return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !["inline", "contents"].includes(display);
4523 function isTableElement(element) {
4524 return ["table", "td", "th"].includes(getNodeName(element));
4526 function isTopLayer(element) {
4527 return [":popover-open", ":modal"].some((selector) => {
4529 return element.matches(selector);
4535 function isContainingBlock(elementOrCss) {
4536 const webkit = isWebKit();
4537 const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;
4538 return css.transform !== "none" || css.perspective !== "none" || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || ["transform", "perspective", "filter"].some((value) => (css.willChange || "").includes(value)) || ["paint", "layout", "strict", "content"].some((value) => (css.contain || "").includes(value));
4540 function getContainingBlock(element) {
4541 let currentNode = getParentNode(element);
4542 while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
4543 if (isContainingBlock(currentNode)) {
4545 } else if (isTopLayer(currentNode)) {
4548 currentNode = getParentNode(currentNode);
4552 function isWebKit() {
4553 if (typeof CSS === "undefined" || !CSS.supports)
4555 return CSS.supports("-webkit-backdrop-filter", "none");
4557 function isLastTraversableNode(node) {
4558 return ["html", "body", "#document"].includes(getNodeName(node));
4560 function getComputedStyle(element) {
4561 return getWindow(element).getComputedStyle(element);
4563 function getNodeScroll(element) {
4564 if (isElement(element)) {
4566 scrollLeft: element.scrollLeft,
4567 scrollTop: element.scrollTop
4571 scrollLeft: element.scrollX,
4572 scrollTop: element.scrollY
4575 function getParentNode(node) {
4576 if (getNodeName(node) === "html") {
4580 // Step into the shadow DOM of the parent of a slotted node.
4581 node.assignedSlot || // DOM Element detected.
4582 node.parentNode || // ShadowRoot detected.
4583 isShadowRoot(node) && node.host || // Fallback.
4584 getDocumentElement(node)
4586 return isShadowRoot(result) ? result.host : result;
4588 function getNearestOverflowAncestor(node) {
4589 const parentNode = getParentNode(node);
4590 if (isLastTraversableNode(parentNode)) {
4591 return node.ownerDocument ? node.ownerDocument.body : node.body;
4593 if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
4596 return getNearestOverflowAncestor(parentNode);
4598 function getOverflowAncestors(node, list, traverseIframes) {
4599 var _node$ownerDocument2;
4600 if (list === void 0) {
4603 if (traverseIframes === void 0) {
4604 traverseIframes = true;
4606 const scrollableAncestor = getNearestOverflowAncestor(node);
4607 const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
4608 const win = getWindow(scrollableAncestor);
4610 const frameElement = getFrameElement(win);
4611 return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
4613 return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
4615 function getFrameElement(win) {
4616 return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
4618 function getCssDimensions(element) {
4619 const css = getComputedStyle(element);
4620 let width = parseFloat(css.width) || 0;
4621 let height = parseFloat(css.height) || 0;
4622 const hasOffset = isHTMLElement(element);
4623 const offsetWidth = hasOffset ? element.offsetWidth : width;
4624 const offsetHeight = hasOffset ? element.offsetHeight : height;
4625 const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
4626 if (shouldFallback) {
4627 width = offsetWidth;
4628 height = offsetHeight;
4636 function unwrapElement$2(element) {
4637 return !isElement(element) ? element.contextElement : element;
4639 function getScale(element) {
4640 const domElement = unwrapElement$2(element);
4641 if (!isHTMLElement(domElement)) {
4642 return createCoords(1);
4644 const rect = domElement.getBoundingClientRect();
4649 } = getCssDimensions(domElement);
4650 let x = ($ ? round(rect.width) : rect.width) / width;
4651 let y = ($ ? round(rect.height) : rect.height) / height;
4652 if (!x || !Number.isFinite(x)) {
4655 if (!y || !Number.isFinite(y)) {
4663 const noOffsets = /* @__PURE__ */ createCoords(0);
4664 function getVisualOffsets(element) {
4665 const win = getWindow(element);
4666 if (!isWebKit() || !win.visualViewport) {
4670 x: win.visualViewport.offsetLeft,
4671 y: win.visualViewport.offsetTop
4674 function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
4675 if (isFixed === void 0) {
4678 if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
4683 function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
4684 if (includeScale === void 0) {
4685 includeScale = false;
4687 if (isFixedStrategy === void 0) {
4688 isFixedStrategy = false;
4690 const clientRect = element.getBoundingClientRect();
4691 const domElement = unwrapElement$2(element);
4692 let scale = createCoords(1);
4695 if (isElement(offsetParent)) {
4696 scale = getScale(offsetParent);
4699 scale = getScale(element);
4702 const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
4703 let x = (clientRect.left + visualOffsets.x) / scale.x;
4704 let y = (clientRect.top + visualOffsets.y) / scale.y;
4705 let width = clientRect.width / scale.x;
4706 let height = clientRect.height / scale.y;
4708 const win = getWindow(domElement);
4709 const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
4710 let currentWin = win;
4711 let currentIFrame = getFrameElement(currentWin);
4712 while (currentIFrame && offsetParent && offsetWin !== currentWin) {
4713 const iframeScale = getScale(currentIFrame);
4714 const iframeRect = currentIFrame.getBoundingClientRect();
4715 const css = getComputedStyle(currentIFrame);
4716 const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
4717 const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
4720 width *= iframeScale.x;
4721 height *= iframeScale.y;
4724 currentWin = getWindow(currentIFrame);
4725 currentIFrame = getFrameElement(currentWin);
4728 return rectToClientRect({
4735 function getWindowScrollBarX(element, rect) {
4736 const leftScroll = getNodeScroll(element).scrollLeft;
4738 return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
4740 return rect.left + leftScroll;
4742 function getHTMLOffset(documentElement, scroll, ignoreScrollbarX) {
4743 if (ignoreScrollbarX === void 0) {
4744 ignoreScrollbarX = false;
4746 const htmlRect = documentElement.getBoundingClientRect();
4747 const x = htmlRect.left + scroll.scrollLeft - (ignoreScrollbarX ? 0 : (
4748 // RTL <body> scrollbar.
4749 getWindowScrollBarX(documentElement, htmlRect)
4751 const y = htmlRect.top + scroll.scrollTop;
4757 function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
4764 const isFixed = strategy === "fixed";
4765 const documentElement = getDocumentElement(offsetParent);
4766 const topLayer = elements ? isTopLayer(elements.floating) : false;
4767 if (offsetParent === documentElement || topLayer && isFixed) {
4774 let scale = createCoords(1);
4775 const offsets = createCoords(0);
4776 const isOffsetParentAnElement = isHTMLElement(offsetParent);
4777 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
4778 if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
4779 scroll = getNodeScroll(offsetParent);
4781 if (isHTMLElement(offsetParent)) {
4782 const offsetRect = getBoundingClientRect(offsetParent);
4783 scale = getScale(offsetParent);
4784 offsets.x = offsetRect.x + offsetParent.clientLeft;
4785 offsets.y = offsetRect.y + offsetParent.clientTop;
4788 const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll, true) : createCoords(0);
4790 width: rect.width * scale.x,
4791 height: rect.height * scale.y,
4792 x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
4793 y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
4796 function getClientRects(element) {
4797 return Array.from(element.getClientRects());
4799 function getDocumentRect(element) {
4800 const html = getDocumentElement(element);
4801 const scroll = getNodeScroll(element);
4802 const body = element.ownerDocument.body;
4803 const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
4804 const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
4805 let x = -scroll.scrollLeft + getWindowScrollBarX(element);
4806 const y = -scroll.scrollTop;
4807 if (getComputedStyle(body).direction === "rtl") {
4808 x += max(html.clientWidth, body.clientWidth) - width;
4817 function getViewportRect(element, strategy) {
4818 const win = getWindow(element);
4819 const html = getDocumentElement(element);
4820 const visualViewport = win.visualViewport;
4821 let width = html.clientWidth;
4822 let height = html.clientHeight;
4825 if (visualViewport) {
4826 width = visualViewport.width;
4827 height = visualViewport.height;
4828 const visualViewportBased = isWebKit();
4829 if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
4830 x = visualViewport.offsetLeft;
4831 y = visualViewport.offsetTop;
4841 function getInnerBoundingClientRect(element, strategy) {
4842 const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
4843 const top = clientRect.top + element.clientTop;
4844 const left = clientRect.left + element.clientLeft;
4845 const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
4846 const width = element.clientWidth * scale.x;
4847 const height = element.clientHeight * scale.y;
4848 const x = left * scale.x;
4849 const y = top * scale.y;
4857 function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
4859 if (clippingAncestor === "viewport") {
4860 rect = getViewportRect(element, strategy);
4861 } else if (clippingAncestor === "document") {
4862 rect = getDocumentRect(getDocumentElement(element));
4863 } else if (isElement(clippingAncestor)) {
4864 rect = getInnerBoundingClientRect(clippingAncestor, strategy);
4866 const visualOffsets = getVisualOffsets(element);
4868 x: clippingAncestor.x - visualOffsets.x,
4869 y: clippingAncestor.y - visualOffsets.y,
4870 width: clippingAncestor.width,
4871 height: clippingAncestor.height
4874 return rectToClientRect(rect);
4876 function hasFixedPositionAncestor(element, stopNode) {
4877 const parentNode = getParentNode(element);
4878 if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
4881 return getComputedStyle(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
4883 function getClippingElementAncestors(element, cache) {
4884 const cachedResult = cache.get(element);
4886 return cachedResult;
4888 let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
4889 let currentContainingBlockComputedStyle = null;
4890 const elementIsFixed = getComputedStyle(element).position === "fixed";
4891 let currentNode = elementIsFixed ? getParentNode(element) : element;
4892 while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
4893 const computedStyle = getComputedStyle(currentNode);
4894 const currentNodeIsContaining = isContainingBlock(currentNode);
4895 if (!currentNodeIsContaining && computedStyle.position === "fixed") {
4896 currentContainingBlockComputedStyle = null;
4898 const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && ["absolute", "fixed"].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
4899 if (shouldDropCurrentNode) {
4900 result = result.filter((ancestor) => ancestor !== currentNode);
4902 currentContainingBlockComputedStyle = computedStyle;
4904 currentNode = getParentNode(currentNode);
4906 cache.set(element, result);
4909 function getClippingRect(_ref) {
4916 const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
4917 const clippingAncestors = [...elementClippingAncestors, rootBoundary];
4918 const firstClippingAncestor = clippingAncestors[0];
4919 const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
4920 const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
4921 accRect.top = max(rect.top, accRect.top);
4922 accRect.right = min(rect.right, accRect.right);
4923 accRect.bottom = min(rect.bottom, accRect.bottom);
4924 accRect.left = max(rect.left, accRect.left);
4926 }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
4928 width: clippingRect.right - clippingRect.left,
4929 height: clippingRect.bottom - clippingRect.top,
4930 x: clippingRect.left,
4934 function getDimensions(element) {
4938 } = getCssDimensions(element);
4944 function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
4945 const isOffsetParentAnElement = isHTMLElement(offsetParent);
4946 const documentElement = getDocumentElement(offsetParent);
4947 const isFixed = strategy === "fixed";
4948 const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
4953 const offsets = createCoords(0);
4954 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
4955 if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
4956 scroll = getNodeScroll(offsetParent);
4958 if (isOffsetParentAnElement) {
4959 const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
4960 offsets.x = offsetRect.x + offsetParent.clientLeft;
4961 offsets.y = offsetRect.y + offsetParent.clientTop;
4962 } else if (documentElement) {
4963 offsets.x = getWindowScrollBarX(documentElement);
4966 const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
4967 const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
4968 const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
4976 function isStaticPositioned(element) {
4977 return getComputedStyle(element).position === "static";
4979 function getTrueOffsetParent(element, polyfill) {
4980 if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") {
4984 return polyfill(element);
4986 let rawOffsetParent = element.offsetParent;
4987 if (getDocumentElement(element) === rawOffsetParent) {
4988 rawOffsetParent = rawOffsetParent.ownerDocument.body;
4990 return rawOffsetParent;
4992 function getOffsetParent(element, polyfill) {
4993 const win = getWindow(element);
4994 if (isTopLayer(element)) {
4997 if (!isHTMLElement(element)) {
4998 let svgOffsetParent = getParentNode(element);
4999 while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
5000 if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
5001 return svgOffsetParent;
5003 svgOffsetParent = getParentNode(svgOffsetParent);
5007 let offsetParent = getTrueOffsetParent(element, polyfill);
5008 while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
5009 offsetParent = getTrueOffsetParent(offsetParent, polyfill);
5011 if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
5014 return offsetParent || getContainingBlock(element) || win;
5016 const getElementRects = function(data) {
5017 return __async(this, null, function* () {
5018 const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
5019 const getDimensionsFn = this.getDimensions;
5020 const floatingDimensions = yield getDimensionsFn(data.floating);
5022 reference: getRectRelativeToOffsetParent(data.reference, yield getOffsetParentFn(data.floating), data.strategy),
5026 width: floatingDimensions.width,
5027 height: floatingDimensions.height
5032 function isRTL(element) {
5033 return getComputedStyle(element).direction === "rtl";
5036 convertOffsetParentRelativeRectToViewportRelativeRect,
5047 function observeMove(element, onMove) {
5050 const root = getDocumentElement(element);
5051 function cleanup() {
5053 clearTimeout(timeoutId);
5054 (_io = io) == null || _io.disconnect();
5057 function refresh(skip, threshold) {
5058 if (skip === void 0) {
5061 if (threshold === void 0) {
5070 } = element.getBoundingClientRect();
5074 if (!width || !height) {
5077 const insetTop = floor(top);
5078 const insetRight = floor(root.clientWidth - (left + width));
5079 const insetBottom = floor(root.clientHeight - (top + height));
5080 const insetLeft = floor(left);
5081 const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px";
5084 threshold: max(0, min(1, threshold)) || 1
5086 let isFirstUpdate = true;
5087 function handleObserve(entries) {
5088 const ratio = entries[0].intersectionRatio;
5089 if (ratio !== threshold) {
5090 if (!isFirstUpdate) {
5094 timeoutId = setTimeout(() => {
5095 refresh(false, 1e-7);
5098 refresh(false, ratio);
5101 isFirstUpdate = false;
5104 io = new IntersectionObserver(handleObserve, __spreadProps(__spreadValues({}, options), {
5106 root: root.ownerDocument
5109 io = new IntersectionObserver(handleObserve, options);
5111 io.observe(element);
5116 function autoUpdate(reference, floating, update, options) {
5117 if (options === void 0) {
5121 ancestorScroll = true,
5122 ancestorResize = true,
5123 elementResize = typeof ResizeObserver === "function",
5124 layoutShift = typeof IntersectionObserver === "function",
5125 animationFrame = false
5127 const referenceEl = unwrapElement$2(reference);
5128 const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating)] : [];
5129 ancestors.forEach((ancestor) => {
5130 ancestorScroll && ancestor.addEventListener("scroll", update, {
5133 ancestorResize && ancestor.addEventListener("resize", update);
5135 const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;
5136 let reobserveFrame = -1;
5137 let resizeObserver = null;
5138 if (elementResize) {
5139 resizeObserver = new ResizeObserver((_ref) => {
5140 let [firstEntry] = _ref;
5141 if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
5142 resizeObserver.unobserve(floating);
5143 cancelAnimationFrame(reobserveFrame);
5144 reobserveFrame = requestAnimationFrame(() => {
5145 var _resizeObserver;
5146 (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);
5151 if (referenceEl && !animationFrame) {
5152 resizeObserver.observe(referenceEl);
5154 resizeObserver.observe(floating);
5157 let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
5158 if (animationFrame) {
5161 function frameLoop() {
5162 const nextRefRect = getBoundingClientRect(reference);
5163 if (prevRefRect && (nextRefRect.x !== prevRefRect.x || nextRefRect.y !== prevRefRect.y || nextRefRect.width !== prevRefRect.width || nextRefRect.height !== prevRefRect.height)) {
5166 prevRefRect = nextRefRect;
5167 frameId = requestAnimationFrame(frameLoop);
5171 var _resizeObserver2;
5172 ancestors.forEach((ancestor) => {
5173 ancestorScroll && ancestor.removeEventListener("scroll", update);
5174 ancestorResize && ancestor.removeEventListener("resize", update);
5176 cleanupIo == null || cleanupIo();
5177 (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();
5178 resizeObserver = null;
5179 if (animationFrame) {
5180 cancelAnimationFrame(frameId);
5184 const offset = offset$1;
5185 const shift = shift$1;
5186 const flip = flip$1;
5187 const size = size$1;
5188 const hide = hide$1;
5189 const computePosition = (reference, floating, options) => {
5190 const cache = /* @__PURE__ */ new Map();
5191 const mergedOptions = __spreadValues({
5194 const platformWithCache = __spreadProps(__spreadValues({}, mergedOptions.platform), {
5197 return computePosition$1(reference, floating, __spreadProps(__spreadValues({}, mergedOptions), {
5198 platform: platformWithCache
5201 function isComponentPublicInstance(target) {
5202 return target != null && typeof target === "object" && "$el" in target;
5204 function unwrapElement$1(target) {
5205 if (isComponentPublicInstance(target)) {
5206 const element = target.$el;
5207 return isNode(element) && getNodeName(element) === "#comment" ? null : element;
5211 function getDPR(element) {
5212 if (typeof window === "undefined") {
5215 const win = element.ownerDocument.defaultView || window;
5216 return win.devicePixelRatio || 1;
5218 function roundByDPR(element, value) {
5219 const dpr = getDPR(element);
5220 return Math.round(value * dpr) / dpr;
5222 function useFloating(reference, floating, options) {
5223 if (options === void 0) {
5226 const whileElementsMountedOption = options.whileElementsMounted;
5227 const openOption = computed(() => {
5229 return (_unref = unref(options.open)) != null ? _unref : true;
5231 const middlewareOption = computed(() => unref(options.middleware));
5232 const placementOption = computed(() => {
5234 return (_unref2 = unref(options.placement)) != null ? _unref2 : "bottom";
5236 const strategyOption = computed(() => {
5238 return (_unref3 = unref(options.strategy)) != null ? _unref3 : "absolute";
5240 const transformOption = computed(() => {
5242 return (_unref4 = unref(options.transform)) != null ? _unref4 : true;
5244 const referenceElement = computed(() => unwrapElement$1(reference.value));
5245 const floatingElement = computed(() => unwrapElement$1(floating.value));
5248 const strategy = ref(strategyOption.value);
5249 const placement = ref(placementOption.value);
5250 const middlewareData = shallowRef({});
5251 const isPositioned = ref(false);
5252 const floatingStyles = computed(() => {
5253 const initialStyles = {
5254 position: strategy.value,
5258 if (!floatingElement.value) {
5259 return initialStyles;
5261 const xVal = roundByDPR(floatingElement.value, x.value);
5262 const yVal = roundByDPR(floatingElement.value, y.value);
5263 if (transformOption.value) {
5264 return __spreadValues(__spreadProps(__spreadValues({}, initialStyles), {
5265 transform: "translate(" + xVal + "px, " + yVal + "px)"
5266 }), getDPR(floatingElement.value) >= 1.5 && {
5267 willChange: "transform"
5271 position: strategy.value,
5276 let whileElementsMountedCleanup;
5278 if (referenceElement.value == null || floatingElement.value == null) {
5281 computePosition(referenceElement.value, floatingElement.value, {
5282 middleware: middlewareOption.value,
5283 placement: placementOption.value,
5284 strategy: strategyOption.value
5285 }).then((position) => {
5286 x.value = position.x;
5287 y.value = position.y;
5288 strategy.value = position.strategy;
5289 placement.value = position.placement;
5290 middlewareData.value = position.middlewareData;
5291 isPositioned.value = true;
5294 function cleanup() {
5295 if (typeof whileElementsMountedCleanup === "function") {
5296 whileElementsMountedCleanup();
5297 whileElementsMountedCleanup = void 0;
5302 if (whileElementsMountedOption === void 0) {
5306 if (referenceElement.value != null && floatingElement.value != null) {
5307 whileElementsMountedCleanup = whileElementsMountedOption(referenceElement.value, floatingElement.value, update);
5312 if (!openOption.value) {
5313 isPositioned.value = false;
5316 watch([middlewareOption, placementOption, strategyOption], update, {
5319 watch([referenceElement, floatingElement], attach, {
5322 watch(openOption, reset, {
5325 if (getCurrentScope()) {
5326 onScopeDispose(cleanup);
5329 x: shallowReadonly(x),
5330 y: shallowReadonly(y),
5331 strategy: shallowReadonly(strategy),
5332 placement: shallowReadonly(placement),
5333 middlewareData: shallowReadonly(middlewareData),
5334 isPositioned: shallowReadonly(isPositioned),
5339 function unwrapElement(element) {
5340 return element && "$el" in element ? element.$el : element;
5342 const clipPadding = 16;
5343 const minClipHeight = 128;
5344 function useFloatingMenu(referenceElement, menu, opt) {
5346 const menuIsExpanded = () => {
5348 return (_a2 = menu.value) == null ? void 0 : _a2.isExpanded();
5350 const middleware = [
5351 offset(opt == null ? void 0 : opt.offset),
5353 // Don't size the menu to take up exactly all of the available height, because that
5354 // makes it look like it's cut off. Instead, leave 16px of free space between the bottom
5355 // of the menu and the bottom edge of the viewport / scrollable container.
5356 padding: clipPadding,
5357 apply({ rects, elements, availableHeight, availableWidth }) {
5358 Object.assign(elements.floating.style, {
5359 // Optionally use all available width
5360 // Else, set the width of the menu to match the width of the triggering element.
5361 // This is needed in Dialogs, when the menu's position is set relative to
5362 // the dialog, not the triggering element.
5363 width: "".concat((opt == null ? void 0 : opt.useAvailableWidth) ? availableWidth : rects.reference.width, "px"),
5364 // Set the max-height to the available height, to prevent the menu from
5365 // extending past the edge of the viewport or scrollable container. But don't
5366 // allow the menu to be shrunk to less than 128px; this is necessary to make
5367 // the flip() call below work.
5368 maxHeight: "".concat(Math.max(minClipHeight, availableHeight), "px")
5372 // If there is not enough space to put the menu below the triggering element, put it above
5373 // it instead. Because of the maxHeight logic above, this happens when there is less than
5374 // 128px available below the triggering element.
5376 // Apply the same padding here as in size(), otherwise the gap between the bottom of
5377 // the menu and the bottom edge of the viewport is allowed to shrink to zero before the
5379 padding: clipPadding
5381 // Hide the menu when it has escaped the reference element's clipping context (e.g. the menu
5382 // is opened down and you scroll up until the reference element just starts to leave the
5387 // Hide the menu when the reference element is fully hidden (e.g. the menu is opened down
5388 // and you scroll down until the whole reference element is gone).
5391 const { floatingStyles, placement, middlewareData, update } = useFloating(
5396 placement: (_a = opt == null ? void 0 : opt.placement) != null ? _a : "bottom"
5399 const menuVisibility = computed(() => {
5401 const isHidden = !menuIsExpanded() || !!((_a2 = middlewareData.value.hide) == null ? void 0 : _a2.escaped) || ((_b = middlewareData.value.hide) == null ? void 0 : _b.referenceHidden);
5402 return isHidden ? "hidden" : "visible";
5405 [floatingStyles, menuVisibility, placement],
5406 ([newStyles, newVisibility, newPlacement]) => {
5407 var _a2, _b, _c, _d, _e;
5408 Object.assign((_b = (_a2 = menu.value) == null ? void 0 : _a2.$el.style) != null ? _b : {}, {
5409 visibility: newVisibility,
5410 position: newStyles.position,
5411 top: "".concat(newStyles.top, "px"),
5412 // `left: 0` is set in the Menu component, which gets transformed to `right: 0` for
5413 // RTL. For this component, we must unset `right: 0`, because the transform value
5414 // is relative to the left side of the screen regardless of reading direction.
5416 // Set `left` value to ensure the menu is translated relative to the left side of
5417 // the screen, which is what FloatingUI expects when it calculates the translate-x
5418 // value for both LTR and RTL.
5419 left: "".concat(newStyles.left, "px"),
5420 // If menuWidth is specified, transform shifts negative, for now ignore that
5421 transform: (_c = newStyles.transform) != null ? _c : "none",
5422 // Zero out border-radius on the corners of the menu where it touches the reference
5423 // element. Which corners these are depends on whether the menu is flipped
5424 borderTopLeftRadius: newPlacement === "bottom" && newVisibility === "visible" ? "0" : "",
5425 borderTopRightRadius: newPlacement === "bottom" && newVisibility === "visible" ? "0" : "",
5426 borderBottomLeftRadius: newPlacement === "top" && newVisibility === "visible" ? "0" : "",
5427 borderBottomRightRadius: newPlacement === "top" && newVisibility === "visible" ? "0" : ""
5429 Object.assign((_e = (_d = unwrapElement(referenceElement.value)) == null ? void 0 : _d.style) != null ? _e : {}, {
5430 // Zero out border-radius on the corners of the reference element where it touches
5431 // the menu. Which corners these are depends on whether the menu is flipped
5432 borderTopLeftRadius: newPlacement === "top" && newVisibility === "visible" ? "0" : "",
5433 borderTopRightRadius: newPlacement === "top" && newVisibility === "visible" ? "0" : "",
5434 borderBottomLeftRadius: newPlacement === "bottom" && newVisibility === "visible" ? "0" : "",
5435 borderBottomRightRadius: newPlacement === "bottom" && newVisibility === "visible" ? "0" : ""
5439 let cleanupAutoUpdate = null;
5440 watch(menuIsExpanded, (newExpanded) => {
5443 cleanupAutoUpdate = autoUpdate(
5444 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
5445 referenceElement.value && "$el" in referenceElement.value ? referenceElement.value.$el : referenceElement,
5446 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
5447 (_a2 = menu.value) == null ? void 0 : _a2.$el,
5451 if (cleanupAutoUpdate) {
5452 cleanupAutoUpdate();
5453 cleanupAutoUpdate = null;
5458 const statusValidator$7 = makeStringTypeValidator(ValidationStatusTypes);
5459 const _sfc_main$j = defineComponent({
5460 name: "CdxCombobox",
5468 * Attributes applied to this component by a parent will be applied
5469 * to the TextInput child component rather than the root element.
5471 inheritAttrs: false,
5474 * Menu items and/or menu group definitions.
5476 * Menu groups and individual menu items will be output in the order they appear here.
5483 * Value of the current selection.
5485 * Must be bound with `v-model:selected`.
5488 type: [String, Number],
5492 * Whether the dropdown is disabled.
5499 * Configuration for various menu features. All properties default to false.
5501 * See the MenuConfig type.
5510 * `status` property of the TextInput component
5515 validator: statusValidator$7
5520 * When the selected value changes.
5522 * @property {string | number} selected The new selected value
5526 * When the user scrolls towards the bottom of the menu.
5528 * If it is possible to add or load more menu items, then now would be a good moment
5529 * so that the user can experience infinite scrolling.
5533 * When the input value changes via direct use of the input
5535 * @property {InputEvent} event
5539 * When an input value change is committed by the user (e.g. on blur)
5541 * @property {Event} event
5545 * When the input comes into focus
5547 * @property {FocusEvent} event
5551 * When the input loses focus
5553 * @property {FocusEvent} event
5557 setup(props, { emit, attrs, slots }) {
5558 const input = ref();
5559 const inputWrapper = ref();
5561 const menuId = useGeneratedId("combobox");
5562 const selectedProp = toRef(props, "selected");
5563 const modelWrapper = useModelWrapper(selectedProp, emit, "update:selected");
5564 const expanded = ref(false);
5565 const expanderClicked = ref(false);
5566 const highlightedId = computed(() => {
5568 return (_b = (_a = menu.value) == null ? void 0 : _a.getHighlightedMenuItem()) == null ? void 0 : _b.id;
5574 toRef(props, "disabled"),
5575 toRef(props, "status")
5577 const internalClasses = computed(() => ({
5578 "cdx-combobox--expanded": expanded.value,
5579 "cdx-combobox--disabled": computedDisabled.value
5585 } = useSplitAttributes(attrs, internalClasses);
5586 function onInputFocus(event) {
5587 if (expanderClicked.value && expanded.value) {
5588 expanded.value = false;
5589 } else if (props.menuItems.length > 0 || slots["no-results"]) {
5590 expanded.value = true;
5592 emit("focus", event);
5594 function onInputBlur(event) {
5595 expanded.value = expanderClicked.value && expanded.value;
5596 emit("blur", event);
5598 function onButtonMousedown() {
5599 if (computedDisabled.value) {
5602 expanderClicked.value = true;
5604 function onButtonClick() {
5606 if (computedDisabled.value) {
5609 (_a = input.value) == null ? void 0 : _a.focus();
5611 function onKeydown(e) {
5612 if (!menu.value || computedDisabled.value || props.menuItems.length === 0 || e.key === " ") {
5615 menu.value.delegateKeyNavigation(e);
5617 useFloatingMenu(input, menu);
5618 watch(expanded, () => {
5619 expanderClicked.value = false;
5643 const _hoisted_1$h = {
5644 ref: "inputWrapper",
5645 class: "cdx-combobox__input-wrapper"
5647 function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
5648 const _component_cdx_text_input = resolveComponent("cdx-text-input");
5649 const _component_cdx_icon = resolveComponent("cdx-icon");
5650 const _component_cdx_button = resolveComponent("cdx-button");
5651 const _component_cdx_menu = resolveComponent("cdx-menu");
5652 return openBlock(), createElementBlock(
5655 class: normalizeClass(["cdx-combobox", _ctx.rootClasses]),
5656 style: normalizeStyle(_ctx.rootStyle)
5663 createVNode(_component_cdx_text_input, mergeProps({
5665 modelValue: _ctx.modelWrapper,
5666 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.modelWrapper = $event)
5667 }, _ctx.otherAttrs, {
5668 class: "cdx-combobox__input",
5669 "aria-activedescendant": _ctx.highlightedId,
5670 "aria-expanded": _ctx.expanded,
5671 "aria-controls": _ctx.menuId,
5672 disabled: _ctx.computedDisabled,
5673 status: _ctx.computedStatus,
5674 autocomplete: "off",
5676 onKeydown: _ctx.onKeydown,
5677 onInput: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("input", $event)),
5678 onChange: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("change", $event)),
5679 onFocus: _ctx.onInputFocus,
5680 onBlur: _ctx.onInputBlur
5681 }), null, 16, ["modelValue", "aria-activedescendant", "aria-expanded", "aria-controls", "disabled", "status", "onKeydown", "onFocus", "onBlur"]),
5682 createVNode(_component_cdx_button, {
5683 class: "cdx-combobox__expand-button",
5684 "aria-hidden": "true",
5685 disabled: _ctx.computedDisabled,
5688 onMousedown: _ctx.onButtonMousedown,
5689 onClick: _ctx.onButtonClick
5691 default: withCtx(() => [
5692 createVNode(_component_cdx_icon, {
5693 class: "cdx-combobox__expand-icon",
5694 icon: _ctx.cdxIconExpand
5695 }, null, 8, ["icon"])
5699 }, 8, ["disabled", "onMousedown", "onClick"])
5704 createVNode(_component_cdx_menu, mergeProps({
5707 selected: _ctx.modelWrapper,
5708 "onUpdate:selected": _cache[3] || (_cache[3] = ($event) => _ctx.modelWrapper = $event),
5709 expanded: _ctx.expanded,
5710 "onUpdate:expanded": _cache[4] || (_cache[4] = ($event) => _ctx.expanded = $event),
5711 "menu-items": _ctx.menuItems
5712 }, _ctx.menuConfig, {
5713 onLoadMore: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("load-more"))
5715 default: withCtx(({ menuItem }) => [
5716 renderSlot(_ctx.$slots, "menu-item", { menuItem })
5718 "no-results": withCtx(() => [
5719 renderSlot(_ctx.$slots, "no-results")
5723 }, 16, ["id", "selected", "expanded", "menu-items"])
5729 const Combobox = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$j]]);
5730 function useResizeObserver(templateRef) {
5731 const currentDimensions = ref(
5732 { width: void 0, height: void 0 }
5734 if (typeof window !== "object" || !("ResizeObserver" in window) || !("ResizeObserverEntry" in window)) {
5735 return currentDimensions;
5737 const observer = new window.ResizeObserver(
5739 const entry = entries[0];
5741 currentDimensions.value = {
5742 width: entry.borderBoxSize[0].inlineSize,
5743 height: entry.borderBoxSize[0].blockSize
5748 let mounted = false;
5751 if (templateRef.value) {
5752 observer.observe(templateRef.value);
5757 observer.disconnect();
5759 watch(templateRef, (newElement) => {
5763 observer.disconnect();
5764 currentDimensions.value = {
5769 observer.observe(newElement);
5772 return currentDimensions;
5774 const _sfc_main$i = defineComponent({
5780 inheritAttrs: false,
5783 * Whether the dialog is visible. Should be provided via a v-model:open
5784 * binding in the parent scope.
5791 * Title for the dialog header. Used for ARIA purposes even if no
5792 * visible header element is displayed.
5799 * Optional subtitle for the dialog.
5807 * Whether the dialog header should hide the title & subtitle
5814 * Add an icon-only close button to the dialog header.
5820 // DEPRECATED: Set default to 'Close' (T368444)
5822 * Visually-hidden label text for the icon-only close button in the header.
5824 * Omit this prop to use the default value, "Close".
5831 * Primary user action. This will display a primary button with the specified action
5832 * (progressive or destructive).
5839 * Default user action. This will display a normal button.
5846 * Whether action buttons should be vertically stacked and 100% width.
5853 * Selector or DOM element identifying the container the dialog should
5854 * be rendered in. The dialog will be `<teleport>`ed to this element.
5855 * An ID selector is recommended, e.g. `#foo-bar`, but providing an
5856 * actual element is also supported.
5858 * If this prop is not set, and the parent or one of its ancestors
5859 * provides a teleport target using `provide( 'CdxTeleportTarget',
5860 * '#foo-bar' )`, the provided target will be used. If there is no
5861 * provided target, the dialog will be teleported to the end of the
5869 * Whether to disable the use of teleport and render the Dialog in its
5870 * original location in the document. If this is true, the `target` prop
5880 * When the open/close state changes, e.g. when the close button is clicked.
5882 * @property {boolean} newValue The new open/close state (true for open, false for closed)
5886 * When the primary action button is clicked.
5890 * When the default action button is clicked.
5894 setup(props, { emit }) {
5895 const labelId = useGeneratedId("dialog-label");
5896 const backdrop = ref();
5897 const dialogElement = ref();
5898 const dialogBody = ref();
5899 const focusHolder = ref();
5900 const focusTrapStart = ref();
5901 const focusTrapEnd = ref();
5902 let previouslyFocused = null;
5903 const useCloseButtonOrLabel = computed(
5904 () => props.useCloseButton || props.closeButtonLabel.length > 0
5906 const translatedCloseButtonLabel = useI18nWithOverride(
5907 toRef(props, "closeButtonLabel"),
5908 "cdx-dialog-close-button-label",
5911 const showHeader = computed(() => !props.hideTitle || useCloseButtonOrLabel.value);
5912 const showFooterActions = computed(() => !!props.primaryAction || !!props.defaultAction);
5913 const bodyDimensions = useResizeObserver(dialogBody);
5914 const currentBodyHeight = computed(() => {
5916 return (_a = bodyDimensions.value.height) != null ? _a : 0;
5918 const showDividers = ref(false);
5919 const rootClasses = computed(() => ({
5920 "cdx-dialog--vertical-actions": props.stackedActions,
5921 "cdx-dialog--horizontal-actions": !props.stackedActions,
5922 "cdx-dialog--dividers": showDividers.value
5924 const providedTarget = inject("CdxTeleportTarget", void 0);
5925 const computedTarget = computed(() => {
5927 return (_b = (_a = props.target) != null ? _a : providedTarget) != null ? _b : "body";
5929 const scrollWidth = ref(0);
5931 emit("update:open", false);
5933 function focusFirst() {
5934 focusFirstFocusableElement(dialogElement.value);
5936 function focusLast() {
5937 focusFirstFocusableElement(dialogElement.value, true);
5939 function focusFirstFocusableElement(container, backwards = false) {
5940 let candidates = Array.from(
5941 container.querySelectorAll('\n input, select, textarea, button, object, a, area,\n [contenteditable], [tabindex]:not([tabindex^="-"])\n ')
5944 candidates = candidates.reverse();
5946 for (const candidate of candidates) {
5948 if (document.activeElement === candidate) {
5954 let ariaHiddenElements = [];
5955 let inertElements = [];
5956 function setAriaHiddenAndInert() {
5957 let element = backdrop.value;
5958 while (element.parentElement && element.nodeName !== "BODY") {
5959 for (const sibling of Array.from(element.parentElement.children)) {
5960 if (sibling === element || sibling.nodeName === "SCRIPT") {
5963 if (!sibling.hasAttribute("aria-hidden")) {
5964 sibling.setAttribute("aria-hidden", "true");
5965 ariaHiddenElements.push(sibling);
5967 if (!sibling.hasAttribute("inert")) {
5968 sibling.setAttribute("inert", "");
5969 inertElements.push(sibling);
5972 element = element.parentElement;
5975 function unsetAriaHiddenAndInert() {
5976 for (const element of ariaHiddenElements) {
5977 element.removeAttribute("aria-hidden");
5979 for (const element of inertElements) {
5980 element.removeAttribute("inert");
5982 ariaHiddenElements = [];
5985 function onDialogOpen() {
5986 return __async(this, null, function* () {
5989 scrollWidth.value = window.innerWidth - document.documentElement.clientWidth;
5990 document.documentElement.style.setProperty("margin-right", "".concat(scrollWidth.value, "px"));
5991 document.body.classList.add("cdx-dialog-open");
5992 setAriaHiddenAndInert();
5993 previouslyFocused = document.activeElement;
5994 if (!focusFirstFocusableElement(dialogBody.value)) {
5995 (_a = focusHolder.value) == null ? void 0 : _a.focus();
5999 function onDialogClose() {
6000 document.body.classList.remove("cdx-dialog-open");
6001 document.documentElement.style.removeProperty("margin-right");
6002 unsetAriaHiddenAndInert();
6003 if (previouslyFocused instanceof HTMLElement && document.contains(previouslyFocused)) {
6004 previouslyFocused.focus();
6005 previouslyFocused = null;
6018 watch(toRef(props, "open"), (opened) => {
6025 watch(currentBodyHeight, () => {
6026 if (dialogBody.value) {
6027 showDividers.value = dialogBody.value.clientHeight < dialogBody.value.scrollHeight;
6045 useCloseButtonOrLabel,
6046 translatedCloseButtonLabel,
6051 const _hoisted_1$g = ["aria-label", "aria-labelledby"];
6052 const _hoisted_2$9 = {
6054 class: "cdx-dialog__header__title-group"
6056 const _hoisted_3$6 = ["id"];
6057 const _hoisted_4$4 = {
6059 class: "cdx-dialog__header__subtitle"
6061 const _hoisted_5$4 = {
6063 class: "cdx-dialog-focus-trap",
6066 const _hoisted_6$4 = {
6068 class: "cdx-dialog__footer__text"
6070 const _hoisted_7$1 = {
6072 class: "cdx-dialog__footer__actions"
6074 function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
6075 const _component_cdx_icon = resolveComponent("cdx-icon");
6076 const _component_cdx_button = resolveComponent("cdx-button");
6077 return openBlock(), createBlock(Teleport, {
6078 to: _ctx.computedTarget,
6079 disabled: _ctx.renderInPlace
6081 createVNode(Transition, {
6082 name: "cdx-dialog-fade",
6085 default: withCtx(() => [
6086 _ctx.open ? (openBlock(), createElementBlock(
6091 class: "cdx-dialog-backdrop",
6092 onClick: _cache[5] || (_cache[5] = (...args) => _ctx.close && _ctx.close(...args)),
6093 onKeyup: _cache[6] || (_cache[6] = withKeys((...args) => _ctx.close && _ctx.close(...args), ["escape"]))
6099 ref: "focusTrapStart",
6101 onFocus: _cache[0] || (_cache[0] = (...args) => _ctx.focusLast && _ctx.focusLast(...args))
6105 /* NEED_HYDRATION, NEED_PATCH */
6107 createElementVNode("div", mergeProps({
6108 ref: "dialogElement",
6109 class: ["cdx-dialog", _ctx.rootClasses],
6112 "aria-label": _ctx.$slots.header || _ctx.hideTitle ? _ctx.title : void 0,
6113 "aria-labelledby": !_ctx.$slots.header && !_ctx.hideTitle ? _ctx.labelId : void 0,
6114 "aria-modal": "true",
6115 onClick: _cache[3] || (_cache[3] = withModifiers(() => {
6118 _ctx.showHeader || _ctx.$slots.header ? (openBlock(), createElementBlock(
6122 class: normalizeClass(["cdx-dialog__header", { "cdx-dialog__header--default": !_ctx.$slots.header }])
6125 renderSlot(_ctx.$slots, "header", {}, () => [
6126 !_ctx.hideTitle ? (openBlock(), createElementBlock("div", _hoisted_2$9, [
6127 createElementVNode("h2", {
6129 class: "cdx-dialog__header__title"
6130 }, toDisplayString(_ctx.title), 9, _hoisted_3$6),
6131 _ctx.subtitle ? (openBlock(), createElementBlock(
6134 toDisplayString(_ctx.subtitle),
6137 )) : createCommentVNode("v-if", true)
6138 ])) : createCommentVNode("v-if", true),
6139 _ctx.useCloseButtonOrLabel ? (openBlock(), createBlock(_component_cdx_button, {
6141 class: "cdx-dialog__header__close-button",
6144 "aria-label": _ctx.translatedCloseButtonLabel,
6147 default: withCtx(() => [
6148 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconClose }, null, 8, ["icon"])
6152 }, 8, ["aria-label", "onClick"])) : createCommentVNode("v-if", true)
6157 )) : createCommentVNode("v-if", true),
6169 class: normalizeClass(["cdx-dialog__body", {
6170 "cdx-dialog__body--no-header": !(_ctx.showHeader || _ctx.$slots.header),
6171 "cdx-dialog__body--no-footer": !(_ctx.showFooterActions || _ctx.$slots.footer || _ctx.$slots["footer-text"])
6175 renderSlot(_ctx.$slots, "default")
6180 _ctx.showFooterActions || _ctx.$slots.footer || _ctx.$slots["footer-text"] ? (openBlock(), createElementBlock(
6184 class: normalizeClass(["cdx-dialog__footer", { "cdx-dialog__footer--default": !_ctx.$slots.footer }])
6187 renderSlot(_ctx.$slots, "footer", {}, () => [
6188 _ctx.$slots["footer-text"] ? (openBlock(), createElementBlock("p", _hoisted_6$4, [
6189 renderSlot(_ctx.$slots, "footer-text")
6190 ])) : createCommentVNode("v-if", true),
6191 _ctx.showFooterActions ? (openBlock(), createElementBlock("div", _hoisted_7$1, [
6192 _ctx.primaryAction ? (openBlock(), createBlock(_component_cdx_button, {
6194 class: "cdx-dialog__footer__primary-action",
6196 action: _ctx.primaryAction.actionType,
6197 disabled: _ctx.primaryAction.disabled,
6198 onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("primary"))
6200 default: withCtx(() => [
6202 toDisplayString(_ctx.primaryAction.label),
6209 }, 8, ["action", "disabled"])) : createCommentVNode("v-if", true),
6210 _ctx.defaultAction ? (openBlock(), createBlock(_component_cdx_button, {
6212 class: "cdx-dialog__footer__default-action",
6213 disabled: _ctx.defaultAction.disabled,
6214 onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("default"))
6216 default: withCtx(() => [
6218 toDisplayString(_ctx.defaultAction.label),
6225 }, 8, ["disabled"])) : createCommentVNode("v-if", true)
6226 ])) : createCommentVNode("v-if", true)
6231 )) : createCommentVNode("v-if", true)
6232 ], 16, _hoisted_1$g),
6236 ref: "focusTrapEnd",
6238 onFocus: _cache[4] || (_cache[4] = (...args) => _ctx.focusFirst && _ctx.focusFirst(...args))
6242 /* NEED_HYDRATION, NEED_PATCH */
6246 /* NEED_HYDRATION, NEED_PATCH */
6247 )) : createCommentVNode("v-if", true)
6252 ], 8, ["to", "disabled"]);
6254 const Dialog = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$i]]);
6261 const _sfc_main$h = defineComponent({
6263 components: { CdxButton, CdxIcon },
6266 * Status type of Message.
6268 * @values 'notice', 'warning', 'error', 'success'
6273 validator: statusTypeValidator
6276 * Whether this message follows the inline design (no padding, background color, or border).
6283 * Custom message icon. Only allowed for notice messages.
6286 type: [String, Object],
6290 * Whether the message should fade in. Should be used for messages that are dynamically
6291 * displayed, not present on page load.
6298 * Allow the message to be dismissed by the user. Adds an icon-only dismiss button.
6304 // DEPRECATED: set default to 'Close' (T368444).
6306 * Visually-hidden label text for the dismiss button for user-dismissable messages.
6308 * Omit this prop to use the default value, "Close".
6310 dismissButtonLabel: {
6315 * Enable automatic dismissal of message after a period of time.
6317 * This prop can be set to `true` to use the default display time of 4000 milliseconds. To
6318 * customize the display time, set this prop to a number of milliseconds.
6320 * Error messages cannot be automatically dismissed. If the `type` prop is set to `error`,
6321 * this prop will be ignored.
6323 * TODO: consider adding a stricter validator to set limits on this. If the time is too
6324 * short, the message may not be readable. If the time is too long, the message probably
6325 * shouldn't be auto-dismissed.
6328 type: [Boolean, Number],
6330 validator: (value) => typeof value === "boolean" || typeof value === "number" && value > 0
6335 * Emitted when the message is dismissed by the user via the dismiss button.
6339 * Emitted when the message is automatically dismissed after the display time.
6343 setup(props, { emit }) {
6344 const dismissed = ref(false);
6345 const userDismissable = computed(
6346 () => props.inline === false && // DEPRECATED: require use of new prop allowUserDismiss (T368444).
6347 (props.dismissButtonLabel.length > 0 || props.allowUserDismiss)
6349 const translatedDismissButtonLabel = useI18nWithOverride(
6350 toRef(props, "dismissButtonLabel"),
6351 "cdx-message-dismiss-button-label",
6354 const displayTime = computed(() => {
6355 if (props.autoDismiss === false || props.type === "error") {
6357 } else if (props.autoDismiss === true) {
6360 return props.autoDismiss;
6362 const rootClasses = computed(() => ({
6363 "cdx-message--inline": props.inline,
6364 "cdx-message--block": !props.inline,
6365 "cdx-message--user-dismissable": userDismissable.value,
6366 ["cdx-message--".concat(props.type)]: true
6368 const computedIcon = computed(
6369 () => props.icon && props.type === "notice" ? props.icon : iconMap$2[props.type]
6371 const leaveActiveClass = ref("");
6372 function onDismiss(eventName) {
6373 if (dismissed.value) {
6376 leaveActiveClass.value = eventName === "user-dismissed" ? "cdx-message-leave-active-user" : "cdx-message-leave-active-system";
6377 dismissed.value = true;
6381 if (props.type === "error" && props.autoDismiss !== false) {
6382 warn('CdxMessage: Message with type="error" cannot use auto-dismiss');
6383 } else if (displayTime.value) {
6384 setTimeout(() => onDismiss("auto-dismissed"), displayTime.value);
6390 translatedDismissButtonLabel,
6399 const _hoisted_1$f = ["aria-live", "role"];
6400 const _hoisted_2$8 = { class: "cdx-message__content" };
6401 function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
6402 const _component_cdx_icon = resolveComponent("cdx-icon");
6403 const _component_cdx_button = resolveComponent("cdx-button");
6404 return openBlock(), createBlock(Transition, {
6405 name: "cdx-message",
6406 appear: _ctx.fadeIn,
6407 "leave-active-class": _ctx.leaveActiveClass
6409 default: withCtx(() => [
6410 !_ctx.dismissed ? (openBlock(), createElementBlock("div", {
6412 class: normalizeClass(["cdx-message", _ctx.rootClasses]),
6413 "aria-live": _ctx.type !== "error" ? "polite" : void 0,
6414 role: _ctx.type === "error" ? "alert" : void 0
6416 createVNode(_component_cdx_icon, {
6417 class: "cdx-message__icon--vue",
6418 icon: _ctx.computedIcon
6419 }, null, 8, ["icon"]),
6420 createElementVNode("div", _hoisted_2$8, [
6421 renderSlot(_ctx.$slots, "default")
6423 _ctx.userDismissable ? (openBlock(), createBlock(_component_cdx_button, {
6425 class: "cdx-message__dismiss-button",
6428 "aria-label": _ctx.translatedDismissButtonLabel,
6429 onClick: _cache[0] || (_cache[0] = ($event) => _ctx.onDismiss("user-dismissed"))
6431 default: withCtx(() => [
6432 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconClose }, null, 8, ["icon"])
6436 }, 8, ["aria-label"])) : createCommentVNode("v-if", true)
6437 ], 10, _hoisted_1$f)) : createCommentVNode("v-if", true)
6441 }, 8, ["appear", "leave-active-class"]);
6443 const CdxMessage = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$h]]);
6444 const statusValidator$6 = makeStringTypeValidator(ValidationStatusTypes);
6445 const _sfc_main$g = defineComponent({
6447 components: { CdxLabel, CdxMessage },
6450 * Icon before the label text.
6452 * Do not use this if including a start icon within the input component.
6455 type: [String, Object],
6459 * Whether the field is optional.
6461 * This will add a flag next to the label indicating that the field is optional.
6467 // DEPRECATED: set default to '(optional)' (T368444).
6469 * Text to indicate that the field is optional.
6471 * Omit this prop to use the default value, "(optional)".
6478 * Whether the label should be visually hidden.
6480 * Note that this will also hide the description.
6487 * Whether this field contains a group of inputs.
6489 * When true, this outputs a `<fieldset>` element with a semantic `<legend>`. When false,
6490 * it outputs a `<div>` with a semantic `<label>`.
6497 * Whether the entire field is disabled.
6504 * `status` attribute of the input. This also determines which validation message is shown.
6509 validator: statusValidator$6
6512 * Message text keyed on validation status type.
6521 setup(props, { slots }) {
6522 const { disabled, status, isFieldset } = toRefs(props);
6523 const computedDisabled = useComputedDisabled(disabled);
6524 const rootClasses = computed(() => ({
6525 "cdx-field--disabled": computedDisabled.value,
6526 "cdx-field--is-fieldset": isFieldset.value
6528 const labelId = useGeneratedId("label");
6529 const descriptionId = useGeneratedId("description");
6530 const inputId = useGeneratedId("input");
6531 const computedInputId = computed(() => !isFieldset.value ? inputId : void 0);
6532 provide(FieldInputIdKey, computedInputId);
6533 const computedDescriptionId = computed(
6534 () => !isFieldset.value && slots.description ? descriptionId : void 0
6536 provide(FieldDescriptionIdKey, computedDescriptionId);
6537 provide(DisabledKey, computedDisabled);
6538 provide(FieldStatusKey, status);
6539 const validationMessage = computed(
6540 () => props.status !== "default" && props.status in props.messages ? props.messages[props.status] : ""
6542 const validationMessageType = computed(() => props.status === "default" ? "notice" : props.status);
6550 validationMessageType
6554 const _hoisted_1$e = { class: "cdx-field__control" };
6555 const _hoisted_2$7 = { class: "cdx-field__help-text" };
6556 const _hoisted_3$5 = {
6558 class: "cdx-field__validation-message"
6560 function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
6561 const _component_cdx_label = resolveComponent("cdx-label");
6562 const _component_cdx_message = resolveComponent("cdx-message");
6563 return openBlock(), createBlock(resolveDynamicComponent(_ctx.isFieldset ? "fieldset" : "div"), {
6564 class: normalizeClass(["cdx-field", _ctx.rootClasses]),
6565 "aria-disabled": !_ctx.isFieldset && _ctx.computedDisabled ? true : void 0,
6566 disabled: _ctx.isFieldset && _ctx.computedDisabled ? true : void 0
6568 default: withCtx(() => [
6569 createVNode(_component_cdx_label, {
6571 icon: _ctx.labelIcon,
6572 "visually-hidden": _ctx.hideLabel,
6573 optional: _ctx.optional,
6574 "optional-flag": _ctx.optionalFlag,
6575 "input-id": _ctx.inputId,
6576 "description-id": _ctx.descriptionId,
6577 disabled: _ctx.computedDisabled,
6578 "is-legend": _ctx.isFieldset
6580 default: withCtx(() => [
6581 renderSlot(_ctx.$slots, "label")
6586 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? {
6587 name: "description",
6589 renderSlot(_ctx.$slots, "description")
6593 ]), 1032, ["id", "icon", "visually-hidden", "optional", "optional-flag", "input-id", "description-id", "disabled", "is-legend"]),
6594 createElementVNode("div", _hoisted_1$e, [
6595 renderSlot(_ctx.$slots, "default")
6597 createElementVNode("div", _hoisted_2$7, [
6598 renderSlot(_ctx.$slots, "help-text")
6600 !_ctx.computedDisabled && _ctx.validationMessage || _ctx.$slots[_ctx.validationMessageType] ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
6601 createVNode(_component_cdx_message, {
6602 type: _ctx.validationMessageType,
6605 default: withCtx(() => [
6606 _ctx.status === "warning" && _ctx.$slots.warning ? renderSlot(_ctx.$slots, "warning", { key: 0 }) : _ctx.status === "error" && _ctx.$slots.error ? renderSlot(_ctx.$slots, "error", { key: 1 }) : _ctx.status === "success" && _ctx.$slots.success ? renderSlot(_ctx.$slots, "success", { key: 2 }) : (openBlock(), createElementBlock(
6611 toDisplayString(_ctx.validationMessage),
6617 /* STABLE_FRAGMENT */
6623 ])) : createCommentVNode("v-if", true)
6627 }, 8, ["class", "aria-disabled", "disabled"]);
6629 const Field = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$g]]);
6636 const _sfc_main$f = defineComponent({
6637 name: "CdxInfoChip",
6638 components: { CdxIcon },
6643 * @values 'notice', 'warning', 'error', 'success'
6648 validator: statusTypeValidator
6651 * Custom icon to use for "notice" chips. Chips with other status types
6652 * (warning, etc) do not allow custom icons and will ignore this option.
6655 type: [String, Object],
6660 const rootClasses = computed(() => ({
6661 ["cdx-info-chip--".concat(props.status)]: true
6663 const computedIcon = computed(
6664 () => props.status === "notice" ? props.icon : iconMap$1[props.status]
6672 const _hoisted_1$d = { class: "cdx-info-chip__text" };
6673 function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
6674 const _component_cdx_icon = resolveComponent("cdx-icon");
6675 return openBlock(), createElementBlock(
6678 class: normalizeClass(["cdx-info-chip", _ctx.rootClasses])
6681 _ctx.computedIcon ? (openBlock(), createBlock(_component_cdx_icon, {
6683 class: "cdx-info-chip__icon--vue",
6684 icon: _ctx.computedIcon
6685 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
6686 createElementVNode("span", _hoisted_1$d, [
6687 renderSlot(_ctx.$slots, "default")
6694 const InfoChip = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$f]]);
6695 const statusValidator$5 = makeStringTypeValidator(ValidationStatusTypes);
6696 const _sfc_main$e = defineComponent({
6703 * We want the input to inherit attributes, not the root element.
6705 inheritAttrs: false,
6708 * Value of the current selection.
6710 * Must be bound with `v-model:selected`.
6712 * The property should be initialized to `null` rather than using a falsy value.
6715 type: [String, Number, null],
6719 * Menu items and/or menu group definitions.
6721 * Menu groups and individual menu items will be output in the order they appear here.
6728 * Current value of the input. This prop is optional and should only be used if you need to
6729 * keep track of the input value for some reason (e.g. to set an initial value).
6731 * Optionally provided by `v-model:input-value` binding in the parent component.
6734 type: [String, Number],
6737 // DEPRECATED: Remove (T373532).
6739 * Initial value of the text input. Non-reactive.
6741 * @deprecated Use `inputValue` instead.
6743 initialInputValue: {
6744 type: [String, Number],
6746 validator: (value) => {
6749 '[CdxLookup]: prop "initialInputValue" is deprecated. Use "inputValue" instead.'
6756 * Whether the entire component is disabled.
6763 * Configuration for various menu features. All properties default to false.
6765 * See the MenuConfig type.
6774 * `status` property of the TextInput component
6779 validator: statusValidator$5
6784 * When the selected value changes.
6786 * @property {string | number | null} selected The new selected value
6790 * When the input value changes. Only emitted if the inputValue prop is provided.
6792 * @property {string | number} inputValue The new input value
6794 "update:input-value",
6796 * When the user scrolls towards the bottom of the menu.
6798 * If it is possible to add or load more menu items, then now would be a good moment
6799 * so that the user can experience infinite scrolling.
6803 * When the text input value changes.
6805 * @property {string | number} value The new value
6809 * When an input value change is committed by the user (e.g. on blur)
6811 * @property {Event} event
6815 * When the input comes into focus
6817 * @property {FocusEvent} event
6821 * When the input loses focus
6823 * @property {FocusEvent} event
6827 setup: (props, { emit, attrs, slots }) => {
6828 const rootElement = ref();
6829 const textInput = ref();
6831 const menuId = useGeneratedId("lookup-menu");
6832 const pending = ref(false);
6833 const expanded = ref(false);
6834 const isActive = ref(false);
6835 const initialMenuItems = ref(props.menuItems);
6840 toRef(props, "disabled"),
6841 toRef(props, "status")
6843 const selectedProp = toRef(props, "selected");
6844 const selection = useModelWrapper(selectedProp, emit, "update:selected");
6845 const selectedMenuItem = computed(
6848 return (_a = menu.value) == null ? void 0 : _a.getComputedMenuItems().find((item) => item.value === selection.value);
6851 const highlightedId = computed(() => {
6853 return (_b = (_a = menu.value) == null ? void 0 : _a.getHighlightedMenuItem()) == null ? void 0 : _b.id;
6855 const internalInputValue = ref(props.initialInputValue);
6856 const computedInputValue = useOptionalModelWrapper(
6858 toRef(props, "inputValue"),
6860 "update:input-value"
6862 const internalClasses = computed(() => ({
6863 "cdx-lookup--disabled": computedDisabled.value,
6864 "cdx-lookup--pending": pending.value
6870 } = useSplitAttributes(attrs, internalClasses);
6871 function onUpdateInput(newVal) {
6872 if (selectedMenuItem.value) {
6873 if (selectedMenuItem.value.label !== newVal && selectedMenuItem.value.value !== newVal) {
6874 selection.value = null;
6876 } else if (props.selected !== null && props.selected !== newVal) {
6877 selection.value = null;
6879 if (newVal === "" && initialMenuItems.value.length === 0) {
6880 expanded.value = false;
6881 pending.value = false;
6883 pending.value = true;
6885 emit("input", newVal);
6887 function onInputFocus(event) {
6888 isActive.value = true;
6889 const hasInput = computedInputValue.value !== null && computedInputValue.value !== "";
6890 const hasMenuItems = !!(props.menuItems.length > 0 || slots["no-results"]);
6891 if (hasMenuItems && (hasInput || initialMenuItems.value.length > 0)) {
6892 expanded.value = true;
6894 emit("focus", event);
6896 function onInputBlur(event) {
6897 isActive.value = false;
6898 expanded.value = false;
6899 emit("blur", event);
6901 function onKeydown(e) {
6902 if (!menu.value || computedDisabled.value || props.menuItems.length === 0 && !slots["no-results"] || e.key === " ") {
6905 menu.value.delegateKeyNavigation(e);
6907 useFloatingMenu(textInput, menu);
6908 watch(selection, (newVal) => {
6910 if (newVal !== null) {
6911 const inputValueForSelection = selectedMenuItem.value ? (_a = selectedMenuItem.value.label) != null ? _a : selectedMenuItem.value.value : "";
6912 if (computedInputValue.value !== inputValueForSelection) {
6913 computedInputValue.value = inputValueForSelection;
6914 emit("input", inputValueForSelection);
6918 watch(toRef(props, "menuItems"), (newVal) => {
6920 // Only show the menu if we were in the pending state (meaning this menuItems change
6921 // was in response to user input) and the menu is still focused
6922 isActive.value && pending.value && // Show the menu if there are either menu items or no-results content to show
6923 (newVal.length > 0 || slots["no-results"])
6925 expanded.value = true;
6927 if (newVal.length === 0 && !slots["no-results"]) {
6928 expanded.value = false;
6930 pending.value = false;
6953 function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
6954 const _component_cdx_text_input = resolveComponent("cdx-text-input");
6955 const _component_cdx_menu = resolveComponent("cdx-menu");
6956 return openBlock(), createElementBlock(
6960 class: normalizeClass(["cdx-lookup", _ctx.rootClasses]),
6961 style: normalizeStyle(_ctx.rootStyle)
6964 createVNode(_component_cdx_text_input, mergeProps({
6966 modelValue: _ctx.computedInputValue,
6967 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.computedInputValue = $event)
6968 }, _ctx.otherAttrs, {
6969 class: "cdx-lookup__input",
6971 autocomplete: "off",
6972 "aria-autocomplete": "list",
6973 "aria-controls": _ctx.menuId,
6974 "aria-expanded": _ctx.expanded,
6975 "aria-activedescendant": _ctx.highlightedId,
6976 disabled: _ctx.computedDisabled,
6977 status: _ctx.computedStatus,
6978 "onUpdate:modelValue": _ctx.onUpdateInput,
6979 onChange: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("change", $event)),
6980 onFocus: _ctx.onInputFocus,
6981 onBlur: _ctx.onInputBlur,
6982 onKeydown: _ctx.onKeydown
6983 }), null, 16, ["modelValue", "aria-controls", "aria-expanded", "aria-activedescendant", "disabled", "status", "onUpdate:modelValue", "onFocus", "onBlur", "onKeydown"]),
6984 createVNode(_component_cdx_menu, mergeProps({
6987 selected: _ctx.selection,
6988 "onUpdate:selected": _cache[2] || (_cache[2] = ($event) => _ctx.selection = $event),
6989 expanded: _ctx.expanded,
6990 "onUpdate:expanded": _cache[3] || (_cache[3] = ($event) => _ctx.expanded = $event),
6991 "menu-items": _ctx.menuItems
6992 }, _ctx.menuConfig, {
6993 onLoadMore: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("load-more"))
6995 default: withCtx(({ menuItem }) => [
6996 renderSlot(_ctx.$slots, "menu-item", { menuItem })
6998 "no-results": withCtx(() => [
6999 renderSlot(_ctx.$slots, "no-results")
7003 }, 16, ["id", "selected", "expanded", "menu-items"])
7009 const Lookup = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e]]);
7010 const _sfc_main$d = defineComponent({
7011 name: "CdxToggleButton",
7014 * Whether the button should be set to "on" (true) or "off" (false).
7016 * Provided by `v-model` binding in the parent component.
7023 * Whether the disabled attribute should be added to the button, which prevents
7024 * it from being clicked.
7031 * Whether the toggle button should be "quiet", which renders more minimally.
7040 * Emitted when modelValue changes (i.e. when the state is toggled)
7042 * @property {boolean} modelValue The new model value
7046 setup(props, { emit, slots, attrs }) {
7047 const isIconOnly = useIconOnlyButton(slots.default, attrs, "CdxToggleButton");
7048 const isActive = ref(false);
7049 const rootClasses = computed(() => ({
7050 // Quiet means frameless among other things
7051 "cdx-toggle-button--quiet": props.quiet,
7052 "cdx-toggle-button--framed": !props.quiet,
7053 // Provide --toggled-off too so that we can simplify selectors
7054 "cdx-toggle-button--toggled-on": props.modelValue,
7055 "cdx-toggle-button--toggled-off": !props.modelValue,
7056 "cdx-toggle-button--icon-only": isIconOnly.value,
7057 "cdx-toggle-button--is-active": isActive.value
7059 const onClick = () => {
7060 emit("update:modelValue", !props.modelValue);
7062 const setActive = (active) => {
7063 isActive.value = active;
7065 function onKeyDown() {
7068 function onKeyUp() {
7080 const _hoisted_1$c = ["aria-pressed", "disabled"];
7081 function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
7082 return openBlock(), createElementBlock("button", {
7083 class: normalizeClass(["cdx-toggle-button", _ctx.rootClasses]),
7084 "aria-pressed": _ctx.modelValue,
7085 disabled: _ctx.disabled,
7087 onClick: _cache[0] || (_cache[0] = (...args) => _ctx.onClick && _ctx.onClick(...args)),
7088 onKeydown: _cache[1] || (_cache[1] = withKeys(withModifiers((...args) => _ctx.onKeyDown && _ctx.onKeyDown(...args), ["prevent"]), ["space", "enter"])),
7089 onKeyup: _cache[2] || (_cache[2] = withKeys((...args) => _ctx.onKeyUp && _ctx.onKeyUp(...args), ["space", "enter"]))
7091 renderSlot(_ctx.$slots, "default")
7092 ], 42, _hoisted_1$c);
7094 const CdxToggleButton = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$d]]);
7095 const _sfc_main$c = defineComponent({
7096 name: "CdxMenuButton",
7101 inheritAttrs: false,
7104 * Value of the current selection.
7106 * Must be bound with `v-model:selected`.
7109 type: [String, Number, null],
7113 * Menu items and/or menu group definitions.
7115 * Menu groups and individual menu items will be output in the order they appear here.
7122 * Configuration for various menu features. All properties default to false.
7124 * See the MenuConfig type.
7133 * Whether the dropdown is disabled.
7140 * Interactive footer item.
7142 * This is a special menu item which is pinned to the bottom of the menu. When scrolling is
7143 * enabled within the menu, the footer item will always be visible at the bottom of the
7144 * menu. When scrolling is not enabled, the footer item will simply appear as the last menu
7147 * The footer item is selectable, like other menu items.
7156 * When the selected value changes.
7158 * @property {string | number} selected The new selected value
7162 setup(props, { emit, attrs }) {
7164 const toggle = ref();
7165 const selectedProp = toRef(props, "selected");
7166 const modelWrapper = useModelWrapper(selectedProp, emit, "update:selected");
7167 const expanded = ref(false);
7168 const toggleId = useGeneratedId("menuToggle");
7169 const menuId = useGeneratedId("menu");
7170 const { computedDisabled } = useFieldData(toRef(props, "disabled"));
7171 const { rootClasses, rootStyle, otherAttrs } = useSplitAttributes(attrs);
7172 function onKeydown(e) {
7173 if (!menu.value || computedDisabled.value || props.menuItems.length === 0 || e.key === " ") {
7176 menu.value.delegateKeyNavigation(e);
7178 useFloatingMenu(toggle, menu, {
7179 useAvailableWidth: true,
7180 placement: "bottom-start",
7198 const _hoisted_1$b = { class: "cdx-menu-button__menu-wrapper" };
7199 function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
7200 const _component_cdx_toggle_button = resolveComponent("cdx-toggle-button");
7201 const _component_cdx_menu = resolveComponent("cdx-menu");
7202 return openBlock(), createElementBlock(
7205 class: normalizeClass(["cdx-menu-button", _ctx.rootClasses]),
7206 style: normalizeStyle(_ctx.rootStyle)
7209 createVNode(_component_cdx_toggle_button, mergeProps({
7212 }, _ctx.otherAttrs, {
7213 modelValue: _ctx.expanded,
7214 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.expanded = $event),
7215 disabled: _ctx.computedDisabled,
7217 "aria-haspopup": "menu",
7218 "aria-controls": _ctx.menuId,
7219 "aria-expanded": _ctx.expanded,
7220 onBlur: _cache[1] || (_cache[1] = ($event) => _ctx.expanded = false),
7221 onKeydown: _ctx.onKeydown
7223 default: withCtx(() => [
7224 renderSlot(_ctx.$slots, "default")
7228 }, 16, ["id", "modelValue", "disabled", "aria-controls", "aria-expanded", "onKeydown"]),
7229 createElementVNode("div", _hoisted_1$b, [
7230 createVNode(_component_cdx_menu, mergeProps({
7233 selected: _ctx.modelWrapper,
7234 "onUpdate:selected": _cache[2] || (_cache[2] = ($event) => _ctx.modelWrapper = $event),
7235 expanded: _ctx.expanded,
7236 "onUpdate:expanded": _cache[3] || (_cache[3] = ($event) => _ctx.expanded = $event),
7237 "menu-items": _ctx.menuItems
7238 }, _ctx.menuConfig, {
7240 "aria-labelledby": _ctx.toggleId,
7243 default: withCtx(({ menuItem }) => [
7244 renderSlot(_ctx.$slots, "menu-item", { menuItem })
7248 }, 16, ["id", "selected", "expanded", "menu-items", "aria-labelledby", "footer"])
7255 const MenuButton = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$c]]);
7256 const statusValidator$4 = makeStringTypeValidator(ValidationStatusTypes);
7257 const _sfc_main$b = defineComponent({
7258 name: "CdxMultiselectLookup",
7265 * Current chips present in the input.
7267 * Must be bound with `v-model:input-chips`. Initialize to an empty array if there are no
7268 * initial selections. If there are, initialize to an array of input chips matching those
7276 * Value(s) of the current selection(s).
7278 * Must be bound with `v-model:selected`. Initialize to an empty array if there are no
7279 * initial selections.
7286 * Menu items and/or menu group definitions. Initialize to an empty array if there are no
7287 * initial menu items.
7289 * Menu groups and individual menu items will be output in the order they appear here.
7296 * Current value of the text input. This prop is optional and should only be used if you
7297 * need to keep track of the text input value for some reason (e.g. for validation).
7299 * Optionally provided by `v-model:input-value` binding in the parent component.
7302 type: [String, Number],
7306 * Whether the text input should appear below the set of input chips.
7308 * By default, the input chips are inline with the input.
7315 * Whether the entire component is disabled.
7322 * Whether the MultiselectLookup is readonly.
7329 * `status` attribute of the input.
7334 validator: statusValidator$4
7337 * Configuration for various menu features. All properties default to false.
7339 * See the MenuConfig type.
7350 * When the input chips change.
7352 * @property {ChipInputItem[]} inputChips The new set of inputChips
7354 "update:input-chips",
7356 * When the selected value changes.
7358 * @property {MenuItemValue[]} selected The new set of selected values
7362 * When the input value changes. Only emitted if the inputValue prop is provided.
7364 * This event is emitted both when the user changes the input and when the input is changed
7365 * or cleared automatically (e.g. on selection).
7367 * @property {string | number} inputValue The new input value
7369 "update:input-value",
7371 * When the user scrolls towards the bottom of the menu.
7373 * If it is possible to add or load more menu items, then now would be a good moment
7374 * so that the user can experience infinite scrolling.
7378 * When the user changes the value of the input. Not emitted when the input is changed
7379 * automatically (e.g. on selection).
7381 * @property {string | number} value The new value
7385 * When an input value change is committed by the user (e.g. on blur)
7387 * @property {Event} event
7391 * When the input comes into focus
7393 * @property {FocusEvent} event
7397 * When the input loses focus
7399 * @property {FocusEvent} event
7403 setup: (props, { emit, attrs, slots }) => {
7404 const chipInput = ref();
7406 const menuId = useGeneratedId("multiselect-lookup-menu");
7407 const highlightedId = computed(() => {
7409 return (_b = (_a = menu.value) == null ? void 0 : _a.getHighlightedMenuItem()) == null ? void 0 : _b.id;
7411 const pending = ref(false);
7412 const expanded = ref(false);
7413 const isActive = ref(false);
7414 provide(AllowArbitraryKey, ref(false));
7419 toRef(props, "disabled"),
7420 toRef(props, "status")
7422 const internalClasses = computed(() => ({
7423 "cdx-multiselect-lookup--disabled": computedDisabled.value,
7424 "cdx-multiselect-lookup--pending": pending.value
7430 } = useSplitAttributes(attrs, internalClasses);
7431 useFloatingMenu(chipInput, menu);
7432 const selectedWrapper = useModelWrapper(toRef(props, "selected"), emit, "update:selected");
7433 const inputChipsWrapper = useModelWrapper(toRef(props, "inputChips"), emit, "update:input-chips");
7434 const internalInputValue = ref("");
7435 const computedInputValue = useOptionalModelWrapper(
7437 toRef(props, "inputValue"),
7439 "update:input-value"
7441 const showNoResults = computed(() => computedInputValue.value.toString().length > 0 && slots["no-results"]);
7442 function onUpdateInputValue(newVal) {
7443 return __async(this, null, function* () {
7445 pending.value = newVal !== null && newVal !== "";
7446 emit("input", newVal);
7449 function onInputFocus(event) {
7450 isActive.value = true;
7451 if (props.menuItems.length > 0 || showNoResults.value) {
7452 expanded.value = true;
7454 emit("focus", event);
7456 function onInputBlur(event) {
7457 isActive.value = false;
7458 expanded.value = false;
7459 emit("blur", event);
7461 function onKeydown(e) {
7462 if (!menu.value || computedDisabled.value || props.menuItems.length === 0 && !showNoResults.value || e.key === " ") {
7465 menu.value.delegateKeyNavigation(e);
7467 watch(toRef(props, "selected"), (newVal) => {
7468 const newSelections = newVal.filter(
7469 (selection) => inputChipsWrapper.value.find((chip) => selection === chip.value) === void 0
7471 if (newSelections.length > 0) {
7472 newSelections.forEach((newSelection) => {
7474 const newMenuItem = (_a = menu.value) == null ? void 0 : _a.getComputedMenuItems().find(
7475 (menuItem) => menuItem.value === newSelection
7478 const _b = newMenuItem, { id } = _b, newMenuItemWithoutId = __objRest(_b, ["id"]);
7479 inputChipsWrapper.value.push(newMenuItemWithoutId);
7482 computedInputValue.value = "";
7485 inputChipsWrapper.value = inputChipsWrapper.value.filter(
7486 (chip) => newVal.find((selection) => chip.value === selection) !== void 0
7489 watch(toRef(props, "inputChips"), (newVal) => {
7490 if (newVal.length < selectedWrapper.value.length) {
7491 selectedWrapper.value = newVal.map((chip) => chip.value);
7494 watch(toRef(props, "menuItems"), (newVal) => {
7495 if (newVal.length === 0 && !showNoResults.value) {
7496 expanded.value = false;
7497 } else if (isActive.value && pending.value) {
7498 expanded.value = true;
7500 pending.value = false;
7523 function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
7524 const _component_cdx_chip_input = resolveComponent("cdx-chip-input");
7525 const _component_cdx_menu = resolveComponent("cdx-menu");
7526 return openBlock(), createElementBlock(
7529 class: normalizeClass(["cdx-multiselect-lookup", _ctx.rootClasses]),
7530 style: normalizeStyle(_ctx.rootStyle)
7533 createVNode(_component_cdx_chip_input, mergeProps({
7535 "input-chips": _ctx.inputChipsWrapper,
7536 "onUpdate:inputChips": _cache[0] || (_cache[0] = ($event) => _ctx.inputChipsWrapper = $event),
7537 "input-value": _ctx.computedInputValue,
7538 "onUpdate:inputValue": _cache[1] || (_cache[1] = ($event) => _ctx.computedInputValue = $event)
7539 }, _ctx.otherAttrs, {
7540 class: "cdx-multiselect-lookup__chip-input",
7542 autocomplete: "off",
7543 "aria-autocomplete": "list",
7544 "aria-controls": _ctx.menuId,
7545 "aria-expanded": _ctx.expanded,
7546 "aria-activedescendant": _ctx.highlightedId,
7547 "separate-input": _ctx.separateInput,
7548 readonly: _ctx.readonly,
7549 disabled: _ctx.computedDisabled,
7550 status: _ctx.computedStatus,
7551 "onUpdate:inputValue": _ctx.onUpdateInputValue,
7552 onFocus: _ctx.onInputFocus,
7553 onBlur: _ctx.onInputBlur,
7554 onKeydown: _ctx.onKeydown
7555 }), null, 16, ["input-chips", "input-value", "aria-controls", "aria-expanded", "aria-activedescendant", "separate-input", "readonly", "disabled", "status", "onUpdate:inputValue", "onFocus", "onBlur", "onKeydown"]),
7556 createVNode(_component_cdx_menu, mergeProps({
7559 selected: _ctx.selectedWrapper,
7560 "onUpdate:selected": _cache[2] || (_cache[2] = ($event) => _ctx.selectedWrapper = $event),
7561 expanded: _ctx.expanded,
7562 "onUpdate:expanded": _cache[3] || (_cache[3] = ($event) => _ctx.expanded = $event),
7563 "menu-items": _ctx.menuItems
7564 }, _ctx.menuConfig, {
7565 onLoadMore: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("load-more"))
7567 default: withCtx(({ menuItem }) => [
7568 renderSlot(_ctx.$slots, "menu-item", { menuItem })
7570 "no-results": withCtx(() => [
7571 renderSlot(_ctx.$slots, "no-results")
7575 }, 16, ["id", "selected", "expanded", "menu-items"])
7581 const MultiselectLookup = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$b]]);
7582 const statusValidator$3 = makeStringTypeValidator(ValidationStatusTypes);
7583 const _sfc_main$a = defineComponent({
7585 components: { CdxLabel },
7588 * Value of the currently selected radio.
7590 * Provided by `v-model` binding in the parent component.
7593 type: [String, Number, Boolean],
7597 * HTML "value" attribute to assign to the input.
7599 * Required for input groups.
7602 type: [String, Number, Boolean],
7606 * HTML "name" attribute to assign to the input.
7613 * Whether the disabled attribute should be added to the input.
7620 * Whether the component should display inline.
7622 * By default, `display: block` is set and a margin exists between
7623 * sibling components, for a stacked layout.
7630 * Validation status of the Radio.
7635 validator: statusValidator$3
7640 * Emitted when modelValue changes.
7642 * @property {string | number | boolean} modelValue The new model value
7646 setup(props, { emit, slots, attrs }) {
7648 useLabelChecker((_a = slots.default) == null ? void 0 : _a.call(slots), attrs, "CdxRadio");
7653 toRef(props, "disabled"),
7654 toRef(props, "status")
7656 const rootClasses = computed(() => ({
7657 "cdx-radio--inline": props.inline,
7658 ["cdx-radio--status-".concat(computedStatus.value)]: true
7660 const customInputClasses = computed(() => ({
7661 "cdx-radio__custom-input--inline": props.inline
7663 const input = ref();
7664 const radioId = useGeneratedId("radio");
7665 const descriptionId = useGeneratedId("description");
7666 const focusInput = () => {
7667 input.value.focus();
7669 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
7682 const _hoisted_1$a = { class: "cdx-radio__wrapper" };
7683 const _hoisted_2$6 = ["id", "aria-describedby", "name", "value", "disabled"];
7684 const _hoisted_3$4 = /* @__PURE__ */ createElementVNode(
7686 { class: "cdx-radio__icon" },
7691 function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
7692 const _component_cdx_label = resolveComponent("cdx-label");
7693 return openBlock(), createElementBlock(
7696 class: normalizeClass(["cdx-radio", _ctx.rootClasses])
7699 createElementVNode("div", _hoisted_1$a, [
7700 withDirectives(createElementVNode("input", {
7703 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
7704 class: "cdx-radio__input",
7706 "aria-describedby": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
7708 value: _ctx.inputValue,
7709 disabled: _ctx.computedDisabled
7710 }, null, 8, _hoisted_2$6), [
7711 [vModelRadio, _ctx.wrappedModel]
7714 _ctx.$slots.default && _ctx.$slots.default().length ? (openBlock(), createBlock(_component_cdx_label, {
7716 class: "cdx-radio__label",
7717 "input-id": _ctx.radioId,
7718 "description-id": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
7719 disabled: _ctx.computedDisabled,
7720 onClick: _ctx.focusInput
7722 default: withCtx(() => [
7723 renderSlot(_ctx.$slots, "default")
7728 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? {
7729 name: "description",
7731 renderSlot(_ctx.$slots, "description")
7735 ]), 1032, ["input-id", "description-id", "disabled", "onClick"])) : createCommentVNode("v-if", true)
7737 _ctx.$slots["custom-input"] ? (openBlock(), createElementBlock(
7741 class: normalizeClass(["cdx-radio__custom-input", _ctx.customInputClasses])
7744 renderSlot(_ctx.$slots, "custom-input")
7748 )) : createCommentVNode("v-if", true)
7754 const Radio = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$a]]);
7755 const statusValidator$2 = makeStringTypeValidator(ValidationStatusTypes);
7756 const _sfc_main$9 = defineComponent({
7757 name: "CdxSearchInput",
7763 * Attributes, besides class, will be passed to the TextInput's input element.
7765 inheritAttrs: false,
7768 * Value of the search input, provided by `v-model` binding in the parent component.
7771 type: [String, Number],
7776 * Whether to display the search button.
7782 // DEPRECATED: set default to 'Search' (T368444).
7784 * Search button text.
7786 * Omit this prop to use the default value, "Search".
7793 * Whether the search input is disabled.
7800 * `status` property of the TextInput component
7805 validator: statusValidator$2
7810 * When the input value changes
7812 * @property {string | number} value The new value
7814 "update:modelValue",
7816 * When the submit button is clicked.
7818 * @property {string | number} value The current input
7822 * When the input value changes via direct use of the input
7824 * @property {InputEvent} event
7828 * When an input value change is committed by the user (e.g. on blur)
7830 * @property {Event} event
7834 * When the input comes into focus
7836 * @property {FocusEvent} event
7840 * When the input loses focus
7842 * @property {FocusEvent} event
7846 setup(props, { emit, attrs }) {
7847 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
7848 const { computedDisabled } = useFieldData(toRef(props, "disabled"));
7849 const internalClasses = computed(() => ({
7850 "cdx-search-input--has-end-button": !!props.buttonLabel || props.useButton
7856 } = useSplitAttributes(attrs, internalClasses);
7857 const translatedSearchButtonLabel = useI18nWithOverride(
7858 toRef(props, "buttonLabel"),
7859 "cdx-search-input-search-button-label",
7860 // Allow custom button label via props or fallback to a default English string.
7863 const useButtonOrLabel = computed(
7864 () => props.useButton || props.buttonLabel.length > 0
7866 const handleSubmit = () => {
7867 emit("submit-click", wrappedModel.value);
7877 translatedSearchButtonLabel,
7883 * Focus the component's input element.
7888 const textInput = this.$refs.textInput;
7893 const _hoisted_1$9 = { class: "cdx-search-input__input-wrapper" };
7894 function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
7895 const _component_cdx_text_input = resolveComponent("cdx-text-input");
7896 const _component_cdx_button = resolveComponent("cdx-button");
7897 return openBlock(), createElementBlock(
7900 class: normalizeClass(["cdx-search-input", _ctx.rootClasses]),
7901 style: normalizeStyle(_ctx.rootStyle)
7904 createElementVNode("div", _hoisted_1$9, [
7905 createVNode(_component_cdx_text_input, mergeProps({
7907 modelValue: _ctx.wrappedModel,
7908 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
7909 class: "cdx-search-input__text-input",
7910 "input-type": "search",
7911 "start-icon": _ctx.searchIcon,
7912 disabled: _ctx.computedDisabled,
7914 }, _ctx.otherAttrs, {
7915 onKeydown: withKeys(_ctx.handleSubmit, ["enter"]),
7916 onInput: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("input", $event)),
7917 onChange: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("change", $event)),
7918 onFocus: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("focus", $event)),
7919 onBlur: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("blur", $event))
7920 }), null, 16, ["modelValue", "start-icon", "disabled", "status", "onKeydown"]),
7921 renderSlot(_ctx.$slots, "default")
7923 _ctx.useButtonOrLabel ? (openBlock(), createBlock(_component_cdx_button, {
7925 class: "cdx-search-input__end-button",
7926 disabled: _ctx.computedDisabled,
7927 onClick: _ctx.handleSubmit
7929 default: withCtx(() => [
7931 toDisplayString(_ctx.translatedSearchButtonLabel),
7938 }, 8, ["disabled", "onClick"])) : createCommentVNode("v-if", true)
7944 const CdxSearchInput = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9]]);
7945 const statusValidator$1 = makeStringTypeValidator(ValidationStatusTypes);
7946 const _sfc_main$8 = defineComponent({
7953 * We want the select handle to inherit attributes, not the root element.
7955 inheritAttrs: false,
7958 * Menu items and/or menu group definitions.
7960 * Menu groups and individual menu items will be output in the order they appear here.
7967 * Value of the current selection.
7969 * Must be bound with `v-model:selected`.
7971 * The property should be initialized to `null` rather than using a falsy value.
7974 type: [String, Number, null],
7978 * Label to display when no selection has been made.
7985 * Whether the dropdown is disabled.
7992 * Configuration for various menu features. All properties default to false.
7994 * See the MenuConfig type.
8003 * An icon at the start of the select element
8004 * displayed when no selection has been made.
8007 type: [String, Object],
8011 * `status` attribute of the input.
8016 validator: statusValidator$1
8021 * When the selection value changes.
8023 * @property {string | number | null} modelValue The new model value
8027 * When the user scrolls towards the bottom of the menu.
8029 * If it is possible to add or load more menu items, then now would be a good moment
8030 * so that the user can experience infinite scrolling.
8034 setup(props, { emit, attrs }) {
8035 const handle = ref();
8037 const descriptionId = inject(FieldDescriptionIdKey, void 0);
8038 const menuId = useGeneratedId("select-menu");
8039 const expanded = ref(false);
8040 const handleId = attrs.id || useGeneratedId("select-handle");
8044 computedInputId: computedHandleId
8046 toRef(props, "disabled"),
8047 toRef(props, "status"),
8050 const modelWrapper = useModelWrapper(toRef(props, "selected"), emit, "update:selected");
8051 const selectedMenuItem = computed(
8054 return (_a = menu.value) == null ? void 0 : _a.getComputedMenuItems().find(
8055 (menuItem) => menuItem.value === props.selected
8059 const currentLabel = computed(() => {
8061 return selectedMenuItem.value ? (_a = selectedMenuItem.value.label) != null ? _a : selectedMenuItem.value.value : props.defaultLabel;
8063 const startIcon = computed(() => {
8065 if (props.defaultIcon && !selectedMenuItem.value) {
8066 return props.defaultIcon;
8067 } else if ((_a = selectedMenuItem.value) == null ? void 0 : _a.icon) {
8068 return selectedMenuItem.value.icon;
8072 const internalClasses = computed(() => ({
8073 "cdx-select-vue--enabled": !computedDisabled.value,
8074 "cdx-select-vue--disabled": computedDisabled.value,
8075 "cdx-select-vue--expanded": expanded.value,
8076 "cdx-select-vue--value-selected": !!selectedMenuItem.value,
8077 "cdx-select-vue--no-selections": !selectedMenuItem.value,
8078 "cdx-select-vue--has-start-icon": !!startIcon.value,
8079 ["cdx-select-vue--status-".concat(computedStatus.value)]: true
8085 } = useSplitAttributes(attrs, internalClasses);
8086 const otherAttrsMinusId = computed(() => {
8087 const _a = otherAttrs.value, { id } = _a, everythingElse = __objRest(_a, ["id"]);
8088 return everythingElse;
8090 const highlightedId = computed(() => {
8092 return (_b = (_a = menu.value) == null ? void 0 : _a.getHighlightedMenuItem()) == null ? void 0 : _b.id;
8095 expanded.value = false;
8097 function onClick() {
8099 if (computedDisabled.value) {
8102 expanded.value = !expanded.value;
8103 (_a = handle.value) == null ? void 0 : _a.focus();
8105 function onKeydown(e) {
8107 if (computedDisabled.value) {
8110 (_a = menu.value) == null ? void 0 : _a.delegateKeyNavigation(e, { characterNavigation: true });
8112 useFloatingMenu(handle, menu);
8136 const _hoisted_1$8 = ["aria-disabled"];
8137 const _hoisted_2$5 = ["id", "aria-controls", "aria-activedescendant", "aria-expanded", "aria-describedby"];
8138 function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8139 const _component_cdx_icon = resolveComponent("cdx-icon");
8140 const _component_cdx_menu = resolveComponent("cdx-menu");
8141 return openBlock(), createElementBlock("div", {
8142 class: normalizeClass(["cdx-select-vue", _ctx.rootClasses]),
8143 style: normalizeStyle(_ctx.rootStyle),
8144 "aria-disabled": _ctx.computedDisabled
8146 createElementVNode("div", mergeProps({
8147 id: _ctx.computedHandleId,
8149 class: "cdx-select-vue__handle"
8150 }, _ctx.otherAttrsMinusId, {
8153 "aria-controls": _ctx.menuId,
8154 "aria-activedescendant": _ctx.highlightedId,
8155 "aria-expanded": _ctx.expanded,
8156 "aria-describedby": _ctx.descriptionId,
8157 onClick: _cache[0] || (_cache[0] = (...args) => _ctx.onClick && _ctx.onClick(...args)),
8158 onBlur: _cache[1] || (_cache[1] = (...args) => _ctx.onBlur && _ctx.onBlur(...args)),
8159 onKeydown: _cache[2] || (_cache[2] = (...args) => _ctx.onKeydown && _ctx.onKeydown(...args))
8161 renderSlot(_ctx.$slots, "label", {
8162 selectedMenuItem: _ctx.selectedMenuItem,
8163 defaultLabel: _ctx.defaultLabel
8166 toDisplayString(_ctx.currentLabel),
8171 _ctx.startIcon ? (openBlock(), createBlock(_component_cdx_icon, {
8173 icon: _ctx.startIcon,
8174 class: "cdx-select-vue__start-icon"
8175 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
8176 createVNode(_component_cdx_icon, {
8177 icon: _ctx.cdxIconExpand,
8178 class: "cdx-select-vue__indicator"
8179 }, null, 8, ["icon"])
8180 ], 16, _hoisted_2$5),
8181 createVNode(_component_cdx_menu, mergeProps({
8184 selected: _ctx.modelWrapper,
8185 "onUpdate:selected": _cache[3] || (_cache[3] = ($event) => _ctx.modelWrapper = $event),
8186 expanded: _ctx.expanded,
8187 "onUpdate:expanded": _cache[4] || (_cache[4] = ($event) => _ctx.expanded = $event),
8188 "menu-items": _ctx.menuItems
8189 }, _ctx.menuConfig, {
8190 onLoadMore: _cache[5] || (_cache[5] = ($event) => _ctx.$emit("load-more"))
8192 default: withCtx(({ menuItem }) => [
8193 renderSlot(_ctx.$slots, "menu-item", { menuItem })
8197 }, 16, ["id", "selected", "expanded", "menu-items"])
8198 ], 14, _hoisted_1$8);
8200 const CdxSelect = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8]]);
8201 const _sfc_main$7 = defineComponent({
8202 name: "CdxTablePager",
8203 components: { CdxButton, CdxIcon, CdxSelect },
8205 paginationSizeOptions: {
8228 * When the items per page option changes
8230 * @property {number} itemsPerPage the number of items to display
8232 "update:itemsPerPage",
8234 * Emitted when the user requests the first page of data
8238 * Emitted when the user requests the last page of data
8242 * Emitted when the user requests the next page of data
8246 * Emitted when the user requests the previous page of data
8250 setup(props, { emit }) {
8251 const wrappedItemsPerPage = useModelWrapper(
8252 toRef(props, "itemsPerPage"),
8254 "update:itemsPerPage"
8256 const defaultItemsPerPageLabel = useI18n(
8257 "cdx-table-pager-items-per-page-default",
8260 const currentItemsPerPageLabel = useI18n(
8261 "cdx-table-pager-items-per-page-current",
8262 (current) => "".concat(current, " rows"),
8263 [wrappedItemsPerPage]
8265 const btnLabelFirst = useI18n(
8266 "cdx-table-pager-button-first-page",
8269 const btnLabelNext = useI18n(
8270 "cdx-table-pager-button-next-page",
8273 const btnLabelPrev = useI18n(
8274 "cdx-table-pager-button-prev-page",
8277 const btnLabelLast = useI18n(
8278 "cdx-table-pager-button-last-page",
8282 defaultItemsPerPageLabel,
8283 currentItemsPerPageLabel,
8288 wrappedItemsPerPage,
8289 cdxIconPrevious: e7,
8291 cdxIconMoveFirst: N6,
8296 const _hoisted_1$7 = { class: "cdx-table-pager" };
8297 const _hoisted_2$4 = { class: "cdx-table-pager__start" };
8298 const _hoisted_3$3 = { key: 0 };
8299 const _hoisted_4$3 = { key: 1 };
8300 const _hoisted_5$3 = { class: "cdx-table-pager__center" };
8301 const _hoisted_6$3 = { class: "cdx-table-pager__end" };
8302 function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
8303 const _component_cdx_select = resolveComponent("cdx-select");
8304 const _component_cdx_icon = resolveComponent("cdx-icon");
8305 const _component_cdx_button = resolveComponent("cdx-button");
8306 return openBlock(), createElementBlock("div", _hoisted_1$7, [
8307 createElementVNode("div", _hoisted_2$4, [
8308 createVNode(_component_cdx_select, {
8309 selected: _ctx.wrappedItemsPerPage,
8310 "onUpdate:selected": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedItemsPerPage = $event),
8311 "default-label": _ctx.defaultItemsPerPageLabel,
8312 "menu-items": _ctx.paginationSizeOptions
8314 label: withCtx(({ selectedMenuItem, defaultLabel }) => [
8315 selectedMenuItem ? (openBlock(), createElementBlock("span", _hoisted_3$3, [
8319 toDisplayString(_ctx.currentItemsPerPageLabel),
8323 ])) : (openBlock(), createElementBlock(
8326 toDisplayString(defaultLabel),
8333 }, 8, ["selected", "default-label", "menu-items"])
8335 createElementVNode("div", _hoisted_5$3, [
8336 renderSlot(_ctx.$slots, "default")
8338 createElementVNode("div", _hoisted_6$3, [
8339 createVNode(_component_cdx_button, {
8340 disabled: _ctx.prevDisabled,
8341 class: "cdx-table-pager__button-first",
8343 "aria-label": _ctx.btnLabelFirst,
8344 onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("first"))
8346 default: withCtx(() => [
8347 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconMoveFirst }, null, 8, ["icon"])
8351 }, 8, ["disabled", "aria-label"]),
8352 createVNode(_component_cdx_button, {
8353 disabled: _ctx.prevDisabled,
8354 class: "cdx-table-pager__button-prev",
8356 "aria-label": _ctx.btnLabelPrev,
8357 onClick: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("prev"))
8359 default: withCtx(() => [
8360 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconPrevious }, null, 8, ["icon"])
8364 }, 8, ["disabled", "aria-label"]),
8365 createVNode(_component_cdx_button, {
8366 disabled: _ctx.nextDisabled,
8367 class: "cdx-table-pager__button-next",
8369 "aria-label": _ctx.btnLabelNext,
8370 onClick: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("next"))
8372 default: withCtx(() => [
8373 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconNext }, null, 8, ["icon"])
8377 }, 8, ["disabled", "aria-label"]),
8378 createVNode(_component_cdx_button, {
8379 disabled: _ctx.nextDisabled || _ctx.lastDisabled,
8380 class: "cdx-table-pager__button-last",
8382 "aria-label": _ctx.btnLabelLast,
8383 onClick: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("last"))
8385 default: withCtx(() => [
8386 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconMoveLast }, null, 8, ["icon"])
8390 }, 8, ["disabled", "aria-label"])
8394 const CdxTablePager = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7]]);
8395 const tableTextAlignmentsValidator = makeStringTypeValidator(TableTextAlignments);
8396 const paginationPositionValidator = makeStringTypeValidator(TablePaginationPositions);
8402 const sortDirectionMap = {
8407 const _sfc_main$6 = defineComponent({
8419 * Required to support users of assistive technology, but can be visually hidden.
8426 * Whether to visually hide the caption.
8433 * Column definitions.
8440 validator: (value) => {
8441 const ids = value.map((column) => column.id);
8442 const hasUniqueIds = new Set(ids).size === ids.length;
8443 if (!hasUniqueIds) {
8445 '[CdxTable]: Each column in the "columns" prop must have a unique "id".'
8455 * An array of objects, with each object representing the data for a table row. Item keys
8456 * should align with column IDs, as defined in the `columns` prop.
8463 validator: (value, props) => {
8464 if (!Array.isArray(props.columns) || props.columns.length === 0 || value.length === 0) {
8467 const hasSort = props.columns.some((column) => "allowSort" in column);
8468 const rowsHaveIds = value.every((row) => TableRowIdentifier in row);
8469 if (hasSort && props.useRowSelection && !rowsHaveIds) {
8471 '[CdxTable]: With sorting and row selection, each row in the "data" prop must have a "TableRowIdentifier".'
8479 * Whether to use `<th>` for the first cell in each row.
8486 * Whether vertical borders separating columns should be rendered.
8488 showVerticalBorders: {
8493 * Whether to enable row selection.
8500 * An array of selected row indices. Must be bound with `v-model:selected-rows`.
8502 * If sorting is also enabled, this will be an array of TableRowIdentifiers.
8511 * Definition of sort order. Column(s) can be sorted ascending, descending, or not sorted.
8512 * To display data unsorted initially, set to an empty object initially.
8513 * Must be bound with v-model:sort
8522 * Whether the table is waiting for data to be fetched.
8529 * Whether to enable pagination.
8536 * Whether the table is paginating through remote data. Setting this to
8537 * "true" will cause the table to emit events indicating that more data
8538 * should be loaded when the user navigates between pages.
8545 * The total number of rows/results available on the server that the
8546 * user can access via pagination. Providing this value will make for
8547 * a better user experience when navigating through pages of remote
8548 * data, but it is not required.
8555 * Where the pagination controls should appear relative to the table body.
8557 paginationPosition: {
8560 validator: paginationPositionValidator
8563 * Pre-defined options for how may rows should be displayed per page.
8564 * The value of these menu items must be a number.
8566 * @default [ { value: 10 }, { value: 20 }, { value: 50 } ]
8568 paginationSizeOptions: {
8575 validator: (value) => {
8576 const hasNumberValue = (item) => typeof item.value === "number";
8577 if (value.every(hasNumberValue)) {
8580 console.warn('[CdxTable]: "value" property of all menu items in PaginationOptions must be a number.');
8586 * The default number of rows to show per page. For basic pagination,
8587 * this will default to the value of the first of the pagination options
8588 * if not provided. For server-side pagination, this will default to
8589 * the initial number of rows if no default is provided.
8591 * @default paginationSizeOptions[ 0 ].value
8593 paginationSizeDefault: {
8595 default: (rawProps) => {
8596 if (rawProps.paginate && rawProps.serverPagination) {
8597 return rawProps.data.length;
8599 return rawProps.paginationSizeOptions[0].value;
8606 * When the selected row(s) changes.
8608 * @property {string[]} selectedRows The new selected rows.
8610 "update:selectedRows",
8612 * When the sort order changes emit an event to update the sort order.
8614 * @property {Object} sort The new sort order.
8618 * When the user requests another page of data from the server.
8620 * @property {number} offset Index of the first visible row on the new page.
8621 * @property {number} rows Number of rows to display.
8625 * When the user requests the last page of data from the server.
8627 * @property {number} rows Number of rows to display.
8631 setup(props, { emit }) {
8632 const offset2 = ref(0);
8633 const pageSize = ref(props.paginationSizeDefault);
8634 const dataForDisplay = computed(() => {
8635 if (props.serverPagination && props.paginate) {
8637 } else if (props.paginate) {
8638 return props.data.slice(offset2.value, pageSize.value + offset2.value);
8643 const totalCount = computed(() => {
8645 if (props.serverPagination) {
8646 return (_a = props.totalRows) != null ? _a : NaN;
8648 return props.data.length;
8651 const indeterminate = computed(() => isNaN(totalCount.value));
8652 const currentCount = computed(() => dataForDisplay.value.length);
8653 const firstOrdinal = computed(() => offset2.value + 1);
8654 const lastOrdinal = computed(() => offset2.value + currentCount.value);
8655 const lastDisabled = computed(() => indeterminate.value);
8656 const prevDisabled = computed(() => offset2.value <= 0);
8657 const nextDisabled = computed(() => {
8658 if (indeterminate.value) {
8659 return currentCount.value < pageSize.value;
8661 return offset2.value + pageSize.value >= totalCount.value;
8664 const paginationStatusMessageDeterminateShort = useI18n(
8665 "cdx-table-pagination-status-message-determinate-short",
8666 (x, y, z) => "".concat(x, "–").concat(y, " of ").concat(z),
8667 [firstOrdinal, lastOrdinal, totalCount]
8669 const paginationStatusMessageDeterminateLong = useI18n(
8670 "cdx-table-pagination-status-message-determinate-long",
8671 (x, y, z) => "Showing results ".concat(x, "–").concat(y, " of ").concat(z),
8672 [firstOrdinal, lastOrdinal, totalCount]
8674 const paginationStatusMessageIndeterminateShort = useI18n(
8675 "cdx-table-pagination-status-message-indeterminate-short",
8676 (x, y) => "".concat(x, "–").concat(y, " of many"),
8677 [firstOrdinal, lastOrdinal]
8679 const paginationStatusMessageIndeterminateLong = useI18n(
8680 "cdx-table-pagination-status-message-indeterminate-long",
8681 (x, y) => "Showing results ".concat(x, "–").concat(y, " of many"),
8682 [firstOrdinal, lastOrdinal]
8684 const paginationStatusMessageIndeterminateFinal = useI18n(
8685 "cdx-table-pagination-status-message-indeterminate-final",
8686 (x) => "Showing the last ".concat(x, " results"),
8689 const paginationStatusMessagePending = useI18n(
8690 "cdx-table-pagination-status-message-pending",
8691 "Loading results..."
8693 const paginationStatusMessageShort = computed(() => {
8694 if (props.pending) {
8695 return paginationStatusMessagePending.value;
8696 } else if (indeterminate.value && nextDisabled.value) {
8697 return paginationStatusMessageIndeterminateFinal.value;
8698 } else if (indeterminate.value) {
8699 return paginationStatusMessageIndeterminateShort.value;
8701 return paginationStatusMessageDeterminateShort.value;
8704 const paginationStatusMessageLong = computed(() => {
8705 if (props.pending) {
8706 return paginationStatusMessagePending.value;
8707 } else if (indeterminate.value && nextDisabled.value) {
8708 return paginationStatusMessageIndeterminateFinal.value;
8709 } else if (indeterminate.value) {
8710 return paginationStatusMessageIndeterminateLong.value;
8712 return paginationStatusMessageDeterminateLong.value;
8716 offset2.value += pageSize.value;
8717 if (props.serverPagination) {
8718 emit("load-more", offset2.value, pageSize.value);
8722 if (offset2.value - pageSize.value < 1) {
8725 offset2.value -= pageSize.value;
8726 if (props.serverPagination) {
8727 emit("load-more", offset2.value, pageSize.value);
8731 function onFirst() {
8733 if (props.serverPagination) {
8734 emit("load-more", offset2.value, pageSize.value);
8738 if (totalCount.value % pageSize.value === 0) {
8739 offset2.value = totalCount.value - pageSize.value;
8740 emit("load-more", offset2.value, pageSize.value);
8742 offset2.value = Math.floor(totalCount.value / pageSize.value) * pageSize.value;
8743 emit("load-more", offset2.value, pageSize.value);
8746 watch(pageSize, (newPageSize) => {
8747 if (props.serverPagination) {
8748 emit("load-more", offset2.value, newPageSize);
8751 const wrappedSelectedRows = useModelWrapper(toRef(props, "selectedRows"), emit, "update:selectedRows");
8752 const selectAll = ref(totalCount.value === wrappedSelectedRows.value.length);
8753 const selectAllIndeterminate = ref(false);
8754 const activeSortColumn = computed(() => Object.keys(props.sort)[0]);
8755 const hasSortableColumns = computed(
8756 () => props.columns.some((column) => column.allowSort)
8758 const tableClasses = computed(() => {
8760 const useFixedLayout = (_a = props.columns) == null ? void 0 : _a.some((column) => "width" in column || "minWidth" in column);
8762 "cdx-table__table--layout-fixed": useFixedLayout,
8763 "cdx-table__table--borders-vertical": props.showVerticalBorders
8766 const translatedSortCaption = useI18n(
8767 "cdx-table-sort-caption",
8768 (caption) => "".concat(caption, " (column headers with buttons are sortable)."),
8769 [toRef(props, "caption")]
8771 const translatedSelectRowLabel = (rowIndex, totalRows) => useI18n(
8772 "cdx-table-select-row-label",
8773 (row, total) => "Select row ".concat(row, " of ").concat(total),
8774 [() => rowIndex, () => totalRows]
8776 const translatedSelectAllLabel = useI18n("cdx-table-select-all-label", "Select all rows");
8777 function getRowKey(row, index) {
8778 return TableRowIdentifier in row ? row[TableRowIdentifier] : index;
8780 function getRowClass(row, rowIndex) {
8781 const rowKey = getRowKey(row, rowIndex);
8783 "cdx-table__row--selected": wrappedSelectedRows.value.indexOf(rowKey) !== -1
8786 function getRowHeaderScope(columnId) {
8787 const firstColumn = props.columns[0].id;
8788 if (props.useRowHeaders && columnId === firstColumn) {
8792 function getCellElement(columnId) {
8793 const firstColumn = props.columns[0].id;
8794 if (props.useRowHeaders && columnId === firstColumn) {
8799 function getCellClass(column, hasSort = false) {
8800 if ("textAlign" in column && !tableTextAlignmentsValidator(column.textAlign)) {
8801 console.warn('[CdxTable]: Invalid value for TableColumn "textAlign" property.');
8805 // Don't assign a class for the default value 'start'. Instead, we'll set
8806 // text-align: left on the td and th elements.
8807 ["cdx-table__table__cell--align-".concat(column.textAlign)]: "textAlign" in column && column.textAlign !== "start",
8808 "cdx-table__table__cell--has-sort": hasSort
8811 function getCellStyle(column) {
8813 if ("width" in column) {
8814 styles.width = column.width;
8816 if ("minWidth" in column) {
8817 styles.minWidth = column.minWidth;
8821 function handleRowSelection(newSelectedRows) {
8822 if (totalCount.value === newSelectedRows.length) {
8823 selectAll.value = true;
8824 selectAllIndeterminate.value = false;
8827 selectAll.value = false;
8828 if (totalCount.value > newSelectedRows.length) {
8829 selectAllIndeterminate.value = true;
8831 if (newSelectedRows.length === 0) {
8832 selectAllIndeterminate.value = false;
8835 function handleSelectAll(newValue) {
8836 selectAllIndeterminate.value = false;
8838 wrappedSelectedRows.value = props.data.map(
8839 (row, rowIndex) => getRowKey(row, rowIndex)
8842 wrappedSelectedRows.value = [];
8845 function handleSort(columnId) {
8847 const currentSortOrder = (_a = props.sort[columnId]) != null ? _a : "none";
8848 let newSortOrder = "asc";
8849 if (currentSortOrder === "asc") {
8850 newSortOrder = "desc";
8852 if (currentSortOrder === "desc") {
8853 newSortOrder = "none";
8855 emit("update:sort", { [columnId]: newSortOrder });
8857 function getSortIcon(columnId) {
8859 const currentSortOrder = (_a = props.sort[columnId]) != null ? _a : "none";
8860 return iconMap[currentSortOrder];
8862 function getSortOrder(columnId, hasSort = false) {
8865 const currentSortOrder = (_a = props.sort[columnId]) != null ? _a : "none";
8866 return currentSortOrder === "none" ? void 0 : sortDirectionMap[currentSortOrder];
8880 paginationStatusMessageShort,
8881 paginationStatusMessageLong,
8882 // Row selection constants.
8883 wrappedSelectedRows,
8885 selectAllIndeterminate,
8886 // Sorting constants.
8889 // Template helpers.
8897 // Row selection methods.
8905 translatedSortCaption,
8906 translatedSelectRowLabel,
8907 translatedSelectAllLabel
8911 const _hoisted_1$6 = {
8915 const _hoisted_2$3 = {
8917 class: "cdx-table__header"
8919 const _hoisted_3$2 = ["aria-hidden"];
8920 const _hoisted_4$2 = { class: "cdx-table__header__content" };
8921 const _hoisted_5$2 = { class: "cdx-table__pagination-status--long" };
8922 const _hoisted_6$2 = { class: "cdx-table__pagination-status--short" };
8923 const _hoisted_7 = { class: "cdx-table__table-wrapper" };
8924 const _hoisted_8 = { key: 0 };
8925 const _hoisted_9 = {
8927 class: "cdx-table__table__select-rows"
8929 const _hoisted_10 = ["aria-sort"];
8930 const _hoisted_11 = ["aria-selected", "onClick"];
8931 const _hoisted_12 = { class: "cdx-table__table__sort-label" };
8932 const _hoisted_13 = { key: 0 };
8933 const _hoisted_14 = { key: 0 };
8934 const _hoisted_15 = { key: 1 };
8935 const _hoisted_16 = { class: "cdx-table__table__empty-state" };
8936 const _hoisted_17 = ["colspan"];
8937 const _hoisted_18 = { class: "cdx-table__pagination-status--long" };
8938 const _hoisted_19 = { class: "cdx-table__pagination-status--short" };
8939 const _hoisted_20 = {
8941 class: "cdx-table__footer"
8943 function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
8944 const _component_cdx_table_pager = resolveComponent("cdx-table-pager");
8945 const _component_cdx_checkbox = resolveComponent("cdx-checkbox");
8946 const _component_cdx_icon = resolveComponent("cdx-icon");
8947 const _component_cdx_progress_bar = resolveComponent("cdx-progress-bar");
8948 return openBlock(), createElementBlock("div", _hoisted_1$6, [
8949 !_ctx.hideCaption || _ctx.$slots.header && _ctx.$slots.header().length > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
8950 createElementVNode("div", {
8951 class: "cdx-table__header__caption",
8952 "aria-hidden": _ctx.$slots.header && _ctx.$slots.header().length > 0 ? void 0 : true
8954 !_ctx.hideCaption ? (openBlock(), createElementBlock(
8959 toDisplayString(_ctx.caption),
8965 /* STABLE_FRAGMENT */
8966 )) : createCommentVNode("v-if", true)
8967 ], 8, _hoisted_3$2),
8968 createElementVNode("div", _hoisted_4$2, [
8969 renderSlot(_ctx.$slots, "header")
8971 ])) : createCommentVNode("v-if", true),
8972 _ctx.paginate && (_ctx.paginationPosition === "top" || _ctx.paginationPosition === "both") ? (openBlock(), createBlock(_component_cdx_table_pager, {
8974 "items-per-page": _ctx.pageSize,
8975 "onUpdate:itemsPerPage": _cache[0] || (_cache[0] = ($event) => _ctx.pageSize = $event),
8976 class: "cdx-table__pagination--top",
8977 "pagination-size-options": _ctx.paginationSizeOptions,
8978 "prev-disabled": _ctx.prevDisabled,
8979 "next-disabled": _ctx.nextDisabled,
8980 "last-disabled": _ctx.lastDisabled,
8981 onNext: _ctx.onNext,
8982 onPrev: _ctx.onPrev,
8983 onFirst: _ctx.onFirst,
8986 default: withCtx(() => [
8990 toDisplayString(_ctx.paginationStatusMessageLong),
8997 toDisplayString(_ctx.paginationStatusMessageShort),
9004 }, 8, ["items-per-page", "pagination-size-options", "prev-disabled", "next-disabled", "last-disabled", "onNext", "onPrev", "onFirst", "onLast"])) : createCommentVNode("v-if", true),
9005 createElementVNode("div", _hoisted_7, [
9009 class: normalizeClass(["cdx-table__table", _ctx.tableClasses])
9012 createElementVNode("caption", null, [
9013 !_ctx.hasSortableColumns ? (openBlock(), createElementBlock(
9018 toDisplayString(_ctx.caption),
9024 /* STABLE_FRAGMENT */
9025 )) : (openBlock(), createElementBlock(
9030 toDisplayString(_ctx.translatedSortCaption),
9036 /* STABLE_FRAGMENT */
9039 renderSlot(_ctx.$slots, "thead", {}, () => [
9040 _ctx.columns.length > 0 ? (openBlock(), createElementBlock("thead", _hoisted_8, [
9041 createElementVNode("tr", null, [
9042 _ctx.useRowSelection ? (openBlock(), createElementBlock("th", _hoisted_9, [
9043 createVNode(_component_cdx_checkbox, {
9044 modelValue: _ctx.selectAll,
9045 "onUpdate:modelValue": [
9046 _cache[1] || (_cache[1] = ($event) => _ctx.selectAll = $event),
9047 _ctx.handleSelectAll
9050 indeterminate: _ctx.selectAllIndeterminate
9052 default: withCtx(() => [
9054 toDisplayString(_ctx.translatedSelectAllLabel),
9061 }, 8, ["modelValue", "indeterminate", "onUpdate:modelValue"])
9062 ])) : createCommentVNode("v-if", true),
9063 (openBlock(true), createElementBlock(
9066 renderList(_ctx.columns, (column) => {
9067 return openBlock(), createElementBlock("th", {
9070 class: normalizeClass(_ctx.getCellClass(column, column.allowSort)),
9071 "aria-sort": _ctx.getSortOrder(column.id, column.allowSort),
9072 style: normalizeStyle(_ctx.getCellStyle(column))
9074 column.allowSort ? (openBlock(), createElementBlock("button", {
9076 "aria-selected": column.id === _ctx.activeSortColumn,
9077 class: "cdx-table__table__sort-button",
9078 onClick: ($event) => _ctx.handleSort(column.id)
9083 toDisplayString(column.label),
9087 createVNode(_component_cdx_icon, {
9088 icon: _ctx.getSortIcon(column.id),
9090 class: "cdx-table__table__sort-icon--vue",
9091 "aria-hidden": "true"
9092 }, null, 8, ["icon"])
9093 ], 8, _hoisted_11)) : (openBlock(), createElementBlock(
9098 toDisplayString(column.label),
9104 /* STABLE_FRAGMENT */
9106 ], 14, _hoisted_10);
9109 /* KEYED_FRAGMENT */
9112 ])) : createCommentVNode("v-if", true)
9114 _ctx.pending ? (openBlock(), createBlock(_component_cdx_progress_bar, {
9117 class: "cdx-table__pending-indicator"
9118 })) : createCommentVNode("v-if", true),
9119 renderSlot(_ctx.$slots, "tbody", {}, () => [
9120 _ctx.dataForDisplay.length > 0 ? (openBlock(), createElementBlock("tbody", _hoisted_13, [
9121 (openBlock(true), createElementBlock(
9124 renderList(_ctx.dataForDisplay, (row, rowIndex) => {
9125 return openBlock(), createElementBlock(
9128 key: _ctx.getRowKey(row, rowIndex),
9129 class: normalizeClass(_ctx.getRowClass(row, rowIndex))
9132 _ctx.useRowSelection ? (openBlock(), createElementBlock("td", _hoisted_14, [
9133 createVNode(_component_cdx_checkbox, {
9134 modelValue: _ctx.wrappedSelectedRows,
9135 "onUpdate:modelValue": [
9136 _cache[2] || (_cache[2] = ($event) => _ctx.wrappedSelectedRows = $event),
9137 _ctx.handleRowSelection
9139 "input-value": _ctx.getRowKey(row, rowIndex),
9142 default: withCtx(() => [
9144 toDisplayString(_ctx.translatedSelectRowLabel(
9146 _ctx.dataForDisplay.length
9154 }, 1032, ["modelValue", "input-value", "onUpdate:modelValue"])
9155 ])) : createCommentVNode("v-if", true),
9156 (openBlock(true), createElementBlock(
9159 renderList(_ctx.columns, (column) => {
9160 return openBlock(), createBlock(resolveDynamicComponent(_ctx.getCellElement(column.id)), {
9162 scope: _ctx.getRowHeaderScope(column.id),
9163 class: normalizeClass(_ctx.getCellClass(column))
9165 default: withCtx(() => [
9166 renderSlot(_ctx.$slots, "item-" + column.id, {
9167 item: row[column.id],
9171 toDisplayString(row[column.id]),
9179 }, 1032, ["scope", "class"]);
9182 /* KEYED_FRAGMENT */
9190 /* KEYED_FRAGMENT */
9192 ])) : _ctx.$slots["empty-state"] && _ctx.$slots["empty-state"]().length > 0 ? (openBlock(), createElementBlock("tbody", _hoisted_15, [
9193 createElementVNode("tr", _hoisted_16, [
9194 createElementVNode("td", {
9195 colspan: _ctx.columns.length,
9196 class: "cdx-table__table__empty-state-content"
9198 renderSlot(_ctx.$slots, "empty-state")
9201 ])) : createCommentVNode("v-if", true)
9203 renderSlot(_ctx.$slots, "tfoot")
9209 _ctx.paginate && (_ctx.paginationPosition === "bottom" || _ctx.paginationPosition === "both") ? (openBlock(), createBlock(_component_cdx_table_pager, {
9211 "items-per-page": _ctx.pageSize,
9212 "onUpdate:itemsPerPage": _cache[3] || (_cache[3] = ($event) => _ctx.pageSize = $event),
9213 class: "cdx-table__pagination--bottom",
9214 "pagination-size-options": _ctx.paginationSizeOptions,
9215 "prev-disabled": _ctx.prevDisabled,
9216 "next-disabled": _ctx.nextDisabled,
9217 "last-disabled": _ctx.lastDisabled,
9218 onNext: _ctx.onNext,
9219 onPrev: _ctx.onPrev,
9220 onFirst: _ctx.onFirst,
9223 default: withCtx(() => [
9227 toDisplayString(_ctx.paginationStatusMessageLong),
9234 toDisplayString(_ctx.paginationStatusMessageShort),
9241 }, 8, ["items-per-page", "pagination-size-options", "prev-disabled", "next-disabled", "last-disabled", "onNext", "onPrev", "onFirst", "onLast"])) : createCommentVNode("v-if", true),
9242 _ctx.$slots.footer && _ctx.$slots.footer().length > 0 ? (openBlock(), createElementBlock("div", _hoisted_20, [
9243 renderSlot(_ctx.$slots, "footer")
9244 ])) : createCommentVNode("v-if", true)
9247 const Table = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6]]);
9248 const _sfc_main$5 = defineComponent({
9251 * The "label" and "disabled" props are referenced by the parent Tabs
9252 * component during the generation of a list of labels.
9256 * String name of the tab, used for programmatic selection. Each Tab
9257 * inside a layout must have a unique name. This prop will also be
9258 * used as the tab label if no "label" prop is provided.
9265 * Label that corresponds to this Tab in the Tabs component's header.
9266 * Lengthy labels will be truncated.
9268 // eslint-disable-next-line vue/no-unused-properties
9274 * Whether or not the tab is disabled. Disabled tabs cannot be accessed
9275 * via label clicks or keyboard navigation.
9277 // eslint-disable-next-line vue/no-unused-properties
9285 const tabsData = inject(TabsKey);
9286 const activeTab = inject(ActiveTabKey);
9287 if (!tabsData || !activeTab) {
9288 throw new Error("Tab component must be used inside a Tabs component");
9290 const tab = (_a = tabsData.value.get(props.name)) != null ? _a : {};
9291 const isActive = computed(() => props.name === activeTab.value);
9298 const _hoisted_1$5 = ["id", "aria-hidden", "aria-labelledby"];
9299 function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
9300 return withDirectives((openBlock(), createElementBlock("section", {
9302 "aria-hidden": !_ctx.isActive ? true : void 0,
9303 "aria-labelledby": "".concat(_ctx.tab.id, "-label"),
9308 renderSlot(_ctx.$slots, "default")
9309 ], 8, _hoisted_1$5)), [
9310 [vShow, _ctx.isActive]
9313 const CdxTab = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
9314 const _sfc_main$4 = defineComponent({
9322 * The `name` of the currently active Tab in the layout.
9324 * This prop is optional; if it is provided, it should be bound
9325 * using a `v-model:active` directive in the parent component.
9326 * Two-way binding the active tab is only necessary if some tab
9327 * other than the first should be active as soon as the component
9328 * renders (such as in cases where the active tab is bound to URL
9329 * params). If this prop is not provided, then the first tab will
9330 * be active by default. Regardless, the active tab can be changed
9331 * normally by user interaction (clicking on tab headings) or by
9332 * using the exposed methods "select", "next", and "prev".
9339 * Whether or not the component should be displayed in a framed
9349 * Emitted whenever the active tab changes, assuming that an `active`
9350 * prop has been provided in the parent.
9352 * @property {string} active The `name` of the current active tab
9357 * Some methods are exposed to allow for programmatic selection of
9358 * the active tab from outside of the component.
9365 setup(props, { slots, emit }) {
9366 const rootElement = ref();
9367 const tabListElement = ref();
9368 const prevScroller = ref();
9369 const nextScroller = ref();
9370 const currentDirection = useComputedDirection(rootElement);
9371 const childTabNodes = computed(() => {
9372 const slotContents = useSlotContents(slots.default);
9373 if (!slotContents.every(
9374 (node) => typeof node === "object" && isComponentVNode(node, CdxTab.name)
9376 throw new Error("Slot content may only contain CdxTab components");
9378 if (slotContents.length === 0) {
9379 throw new Error("Slot content cannot be empty");
9381 return slotContents;
9383 const tabsData = computed(() => childTabNodes.value.reduce((map, item) => {
9385 if (((_a = item.props) == null ? void 0 : _a.name) && typeof item.props.name === "string") {
9386 if (map.get(item.props.name)) {
9387 throw new Error("Tab names must be unique");
9389 map.set(item.props.name, {
9390 name: item.props.name,
9391 id: useGeneratedId(item.props.name),
9392 label: item.props.label || item.props.name,
9393 disabled: item.props.disabled
9397 }, /* @__PURE__ */ new Map()));
9398 const internalRefForActiveTab = ref(Array.from(tabsData.value.keys())[0]);
9399 const activeTab = useOptionalModelWrapper(internalRefForActiveTab, toRef(props, "active"), emit, "update:active");
9400 const tabNames = computed(() => Array.from(tabsData.value.keys()));
9401 const activeTabIndex = computed(() => tabNames.value.indexOf(activeTab.value));
9402 const activeTabId = computed(() => {
9404 return (_a = tabsData.value.get(activeTab.value)) == null ? void 0 : _a.id;
9406 provide(ActiveTabKey, activeTab);
9407 provide(TabsKey, tabsData);
9408 const tabButtonRefs = ref(/* @__PURE__ */ new Map());
9409 const firstTabLabel = ref();
9410 const lastTabLabel = ref();
9411 const firstLabelVisible = useIntersectionObserver(firstTabLabel, { threshold: 0.95 });
9412 const lastLabelVisible = useIntersectionObserver(lastTabLabel, { threshold: 0.95 });
9413 function assignTemplateRefForTabButton(templateRef, index) {
9414 const el = templateRef;
9416 tabButtonRefs.value.set(index, el);
9418 firstTabLabel.value = el;
9419 } else if (index === tabNames.value.length - 1) {
9420 lastTabLabel.value = el;
9424 const rootClasses = computed(() => ({
9425 "cdx-tabs--framed": props.framed,
9426 "cdx-tabs--quiet": !props.framed
9428 function focusActiveTab() {
9430 (_a = tabButtonRefs.value.get(activeTabIndex.value)) == null ? void 0 : _a.focus();
9432 function getScrollDistance(tabLabel) {
9433 if (!tabListElement.value || !prevScroller.value || !nextScroller.value) {
9436 const leftScroller = currentDirection.value === "rtl" ? nextScroller.value : prevScroller.value;
9437 const rightScroller = currentDirection.value === "rtl" ? prevScroller.value : nextScroller.value;
9438 const labelLeft = tabLabel.offsetLeft;
9439 const labelRight = labelLeft + tabLabel.clientWidth;
9440 const visibleLeft = tabListElement.value.scrollLeft + leftScroller.clientWidth;
9441 const visibleRight = tabListElement.value.scrollLeft + tabListElement.value.clientWidth - rightScroller.clientWidth;
9442 if (labelLeft < visibleLeft) {
9443 return labelLeft - visibleLeft;
9445 if (labelRight > visibleRight) {
9446 return labelRight - visibleRight;
9450 function scrollTabs(logicalDirection) {
9451 if (!tabListElement.value || !prevScroller.value || !nextScroller.value) {
9454 const scrollDirection = logicalDirection === "next" && currentDirection.value === "ltr" || logicalDirection === "prev" && currentDirection.value === "rtl" ? 1 : -1;
9455 let scrollDistance = 0;
9456 let tabLabel = logicalDirection === "next" ? tabListElement.value.firstElementChild : tabListElement.value.lastElementChild;
9458 const nextTabLabel = logicalDirection === "next" ? tabLabel.nextElementSibling : tabLabel.previousElementSibling;
9459 scrollDistance = getScrollDistance(tabLabel);
9460 if (Math.sign(scrollDistance) === scrollDirection) {
9461 if (nextTabLabel && Math.abs(scrollDistance) < 0.25 * tabListElement.value.clientWidth) {
9462 scrollDistance = getScrollDistance(nextTabLabel);
9466 tabLabel = nextTabLabel;
9468 tabListElement.value.scrollBy({
9469 left: scrollDistance,
9474 watch(activeTab, () => {
9475 if (activeTabId.value === void 0 || !tabListElement.value || !prevScroller.value || !nextScroller.value) {
9478 const activeTabLabel = document.getElementById("".concat(activeTabId.value, "-label"));
9479 if (!activeTabLabel) {
9482 tabListElement.value.scrollBy({
9483 left: getScrollDistance(activeTabLabel),
9501 assignTemplateRefForTabButton,
9504 cdxIconPrevious: e7,
9509 * Some non-public methods are defined here rather than in setup because
9510 * they support public methods (which *must* be defined using the Options
9511 * API in order to show up in documentation), or are thematically related
9512 * (such as key handlers).
9516 * Programmatically select a tab based on its "name" prop
9518 * @param {string} tabName The name of the tab to select
9519 * @param {boolean} setFocus Whether or not to also set focus to the new tab
9522 select(tabName, setFocus) {
9523 const target = this.tabsData.get(tabName);
9524 if (target && !(target == null ? void 0 : target.disabled)) {
9525 this.activeTab = tabName;
9528 this.focusActiveTab();
9534 * Used to select next or previous tab in the sequence, skipping
9535 * over any tabs that are disabled. The provided increment should
9536 * be either 1 (to move forward) or -1 (to move backwards)
9542 selectNonDisabled(index, increment, setFocus) {
9543 const target = this.tabsData.get(this.tabNames[index + increment]);
9545 if (target.disabled) {
9546 this.selectNonDisabled(index + increment, increment, setFocus);
9548 this.select(target.name, setFocus);
9553 * Set the next tab to active, if one exists
9555 * @param {boolean} setFocus
9559 this.selectNonDisabled(this.activeTabIndex, 1, setFocus);
9562 * Set the previous tab to active, if one exists
9564 * @param {boolean} setFocus
9568 this.selectNonDisabled(this.activeTabIndex, -1, setFocus);
9571 * Handle left arrow key navigation (based on LTR/RTL direction)
9573 onLeftArrowKeypress() {
9574 if (this.currentDirection === "rtl") {
9581 * Handle right arrow key navigation (based on LTR/RTL direction)
9583 onRightArrowKeypress() {
9584 if (this.currentDirection === "rtl") {
9591 * Handle down arrow key navigation by moving focus to the contents
9592 * of the currently active tab
9594 onDownArrowKeypress() {
9596 if (this.activeTabId) {
9597 (_a = document.getElementById(this.activeTabId)) == null ? void 0 : _a.focus();
9602 const _hoisted_1$4 = { class: "cdx-tabs__header" };
9603 const _hoisted_2$2 = {
9604 ref: "prevScroller",
9605 class: "cdx-tabs__prev-scroller"
9607 const _hoisted_3$1 = {
9608 ref: "tabListElement",
9609 class: "cdx-tabs__list",
9612 const _hoisted_4$1 = ["id", "disabled", "aria-controls", "aria-selected", "tabindex", "onClick", "onKeyup"];
9613 const _hoisted_5$1 = {
9614 ref: "nextScroller",
9615 class: "cdx-tabs__next-scroller"
9617 const _hoisted_6$1 = { class: "cdx-tabs__content" };
9618 function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
9619 const _component_cdx_icon = resolveComponent("cdx-icon");
9620 const _component_cdx_button = resolveComponent("cdx-button");
9621 return openBlock(), createElementBlock(
9625 class: normalizeClass(["cdx-tabs", _ctx.rootClasses])
9628 createElementVNode("div", _hoisted_1$4, [
9629 withDirectives(createElementVNode(
9633 createVNode(_component_cdx_button, {
9634 class: "cdx-tabs__scroll-button",
9638 "aria-hidden": true,
9639 onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {
9641 onClick: _cache[1] || (_cache[1] = ($event) => _ctx.scrollTabs("prev"))
9643 default: withCtx(() => [
9644 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconPrevious }, null, 8, ["icon"])
9653 [vShow, !_ctx.firstLabelVisible]
9659 (openBlock(true), createElementBlock(
9662 renderList(_ctx.tabsData.values(), (tab, index) => {
9663 return openBlock(), createElementBlock("button", {
9664 id: "".concat(tab.id, "-label"),
9667 ref: (ref2) => _ctx.assignTemplateRefForTabButton(ref2, index),
9668 disabled: tab.disabled ? true : void 0,
9669 "aria-controls": tab.id,
9670 "aria-selected": tab.name === _ctx.activeTab,
9671 tabindex: tab.name === _ctx.activeTab ? void 0 : -1,
9672 class: "cdx-tabs__list__item",
9674 onClick: withModifiers(($event) => _ctx.select(tab.name), ["prevent"]),
9675 onKeyup: withKeys(($event) => _ctx.select(tab.name), ["enter"]),
9677 _cache[2] || (_cache[2] = withKeys(withModifiers((...args) => _ctx.onRightArrowKeypress && _ctx.onRightArrowKeypress(...args), ["prevent"]), ["right"])),
9678 _cache[3] || (_cache[3] = withKeys(withModifiers((...args) => _ctx.onDownArrowKeypress && _ctx.onDownArrowKeypress(...args), ["prevent"]), ["down"])),
9679 _cache[4] || (_cache[4] = withKeys(withModifiers((...args) => _ctx.onLeftArrowKeypress && _ctx.onLeftArrowKeypress(...args), ["prevent"]), ["left"]))
9685 toDisplayString(tab.label),
9689 ], 40, _hoisted_4$1);
9692 /* KEYED_FRAGMENT */
9698 withDirectives(createElementVNode(
9702 createVNode(_component_cdx_button, {
9703 class: "cdx-tabs__scroll-button",
9707 "aria-hidden": true,
9708 onMousedown: _cache[5] || (_cache[5] = withModifiers(() => {
9710 onClick: _cache[6] || (_cache[6] = ($event) => _ctx.scrollTabs("next"))
9712 default: withCtx(() => [
9713 createVNode(_component_cdx_icon, { icon: _ctx.cdxIconNext }, null, 8, ["icon"])
9722 [vShow, !_ctx.lastLabelVisible]
9725 createElementVNode("div", _hoisted_6$1, [
9726 renderSlot(_ctx.$slots, "default")
9733 const Tabs = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
9734 const statusValidator = makeStringTypeValidator(ValidationStatusTypes);
9735 const _sfc_main$3 = defineComponent({
9736 name: "CdxTextArea",
9737 components: { CdxIcon },
9738 inheritAttrs: false,
9748 * Current value of the textarea.
9750 * Provided by `v-model` binding in the parent component.
9757 * `status` attribute of the textarea.
9762 validator: statusValidator
9765 * Whether the textarea is disabled.
9772 * Describes whether the textarea grows vertically to show all text.
9774 * When autosize is true, the textarea automatically grows in height (vertically).
9775 * The height of the textarea expands while the user types in the textarea.
9776 * The content inside the textarea is visible and there's no scroll.
9778 * @values true, false
9785 * An icon at the start of the textarea element. Similar to a `::before` pseudo-element.
9788 type: [String, Object],
9792 * An icon at the end of the textarea element. Similar to an `::after` pseudo-element.
9795 type: [String, Object],
9801 * When the textarea value changes.
9803 * @property {string} modelValue The new model value
9805 "update:modelValue",
9807 * When the input value changes via direct use of the input
9809 * @property {InputEvent} event
9813 * When an input value change is committed by the user (e.g. on blur)
9815 * @property {Event} event
9819 * When the input comes into focus
9821 * @property {FocusEvent} event
9825 * When the input loses focus
9827 * @property {FocusEvent} event
9831 * When the textarea value is invalid according to the textarea's constraint
9832 * attributes (e.g. minlength, maxlength, or required). See:
9833 * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation#validation-related_attributes
9835 * @property {Event} event
9839 setup(props, { attrs, emit }) {
9840 const textarea = ref();
9841 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
9842 const idAttribute = attrs.id;
9848 toRef(props, "disabled"),
9849 toRef(props, "status"),
9852 const descriptionId = inject(FieldDescriptionIdKey, void 0);
9853 const textareaClasses = computed(() => ({
9854 "cdx-text-area__textarea--has-value": !!wrappedModel.value,
9855 "cdx-text-area__textarea--is-autosize": props.autosize
9857 const internalClasses = computed(() => ({
9858 "cdx-text-area--status-default": computedStatus.value === "default",
9859 "cdx-text-area--status-error": computedStatus.value === "error",
9860 "cdx-text-area--has-start-icon": !!props.startIcon,
9861 "cdx-text-area--has-end-icon": !!props.endIcon
9867 } = useSplitAttributes(attrs, internalClasses);
9868 const otherAttrsMinusId = computed(() => {
9869 const _a = otherAttrs.value, { id } = _a, everythingElse = __objRest(_a, ["id"]);
9870 return everythingElse;
9872 function onInput(event) {
9873 if (textarea.value && props.autosize) {
9874 textarea.value.style.height = "auto";
9875 textarea.value.style.height = "".concat(textarea.value.scrollHeight, "px");
9877 emit("input", event);
9879 const onChange = (event) => {
9880 emit("change", event);
9882 const onFocus = (event) => {
9883 emit("focus", event);
9885 const onBlur = (event) => {
9886 emit("blur", event);
9888 const shouldPreventDefault = ref(true);
9889 const onInvalid = (event, doPreventDefault) => {
9890 if (doPreventDefault) {
9891 event.preventDefault();
9893 emit("invalid", event);
9894 shouldPreventDefault.value = true;
9911 shouldPreventDefault
9915 // These must be in the methods block, not in the setup function, otherwise their documentation
9916 // won't be picked up by vue-docgen
9919 * Focus the component's textarea element.
9924 const textarea = this.$refs.textarea;
9928 * Blur the component's textarea element.
9933 const textarea = this.$refs.textarea;
9937 * Check the validity of the textarea element according to its constraint attributes. Emits
9938 * an 'invalid' event if the textarea is invalid. See:
9939 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement/checkValidity
9942 * @return {boolean} Whether the textarea is valid
9945 const textarea = this.$refs.textarea;
9946 return textarea.checkValidity();
9949 * Check the validity of the textarea element and report it as a pop up on the UI. See:
9950 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement/reportValidity
9953 * @return {boolean} Whether the textarea is valid
9956 this.shouldPreventDefault = false;
9957 const textarea = this.$refs.textarea;
9958 return textarea.reportValidity();
9961 * Set custom validity and message for the textarea element. See:
9962 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement/setCustomValidity
9965 * @param {string} message The custom validation message to set
9967 setCustomValidity(message) {
9968 const textarea = this.$refs.textarea;
9969 textarea.setCustomValidity(message);
9973 const _hoisted_1$3 = ["id", "aria-describedby", "disabled"];
9974 function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
9975 const _component_cdx_icon = resolveComponent("cdx-icon");
9976 return openBlock(), createElementBlock(
9979 class: normalizeClass(["cdx-text-area", _ctx.rootClasses]),
9980 style: normalizeStyle(_ctx.rootStyle)
9983 withDirectives(createElementVNode("textarea", mergeProps({
9984 id: _ctx.computedInputId,
9986 }, _ctx.otherAttrsMinusId, {
9987 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
9988 class: [_ctx.textareaClasses, "cdx-text-area__textarea"],
9989 "aria-describedby": _ctx.descriptionId,
9990 disabled: _ctx.computedDisabled,
9991 onInput: _cache[1] || (_cache[1] = (...args) => _ctx.onInput && _ctx.onInput(...args)),
9992 onChange: _cache[2] || (_cache[2] = (...args) => _ctx.onChange && _ctx.onChange(...args)),
9993 onFocus: _cache[3] || (_cache[3] = (...args) => _ctx.onFocus && _ctx.onFocus(...args)),
9994 onBlur: _cache[4] || (_cache[4] = (...args) => _ctx.onBlur && _ctx.onBlur(...args)),
9995 onInvalid: _cache[5] || (_cache[5] = (e) => _ctx.onInvalid(e, _ctx.shouldPreventDefault))
9996 }), null, 16, _hoisted_1$3), [
9997 [vModelText, _ctx.wrappedModel]
9999 _ctx.startIcon ? (openBlock(), createBlock(_component_cdx_icon, {
10001 icon: _ctx.startIcon,
10002 class: "cdx-text-area__icon-vue cdx-text-area__start-icon"
10003 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
10004 _ctx.endIcon ? (openBlock(), createBlock(_component_cdx_icon, {
10006 icon: _ctx.endIcon,
10007 class: "cdx-text-area__icon-vue cdx-text-area__end-icon"
10008 }, null, 8, ["icon"])) : createCommentVNode("v-if", true)
10014 const TextArea = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
10015 const _sfc_main$2 = defineComponent({
10016 name: "CdxToggleButtonGroup",
10023 * Buttons to display. See the ButtonGroupItem type.
10028 validator: (value) => Array.isArray(value) && value.length >= 1
10031 * Selected value, or array of selected values.
10033 * If this is a string or number, the button whose value equals that string or number is
10034 * selected, and only a single selection is allowed. If this is an array, the buttons whose
10035 * values equal any of the values in the array are selected, and multiple selections are
10036 * allowed. To select none of the buttons initially, set this to `null`
10037 * (for single-selection groups) or to `[]` (for multi-selection groups).
10039 * Must be bound with `v-model`.
10042 type: [String, Number, null, Array],
10046 * Whether the entire group is disabled.
10048 * If this is set to true, all buttons in the group are disabled. Buttons can also be
10049 * disabled individually by setting their `disabled` property to true.
10058 * Emitted when modelValue changes.
10060 * @property {string | number | ( string | number )[]} modelValue The new model value
10062 "update:modelValue"
10064 setup(props, { emit }) {
10071 } = useButtonGroupKeyboardNav(toRef(props, "buttons"));
10072 function isSelected(button) {
10073 if (Array.isArray(props.modelValue)) {
10074 return props.modelValue.indexOf(button.value) !== -1;
10075 } else if (props.modelValue !== null) {
10076 return props.modelValue === button.value;
10080 function onUpdate(button, nowSelected) {
10081 if (Array.isArray(props.modelValue)) {
10082 const wasSelected = props.modelValue.indexOf(button.value) !== -1;
10083 if (nowSelected && !wasSelected) {
10084 emit("update:modelValue", props.modelValue.concat(button.value));
10085 } else if (!nowSelected && wasSelected) {
10086 emit("update:modelValue", props.modelValue.filter((v) => v !== button.value));
10089 if (nowSelected && props.modelValue !== button.value) {
10090 emit("update:modelValue", button.value);
10106 const _hoisted_1$2 = {
10107 ref: "rootElement",
10108 class: "cdx-toggle-button-group"
10110 function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
10111 const _component_cdx_icon = resolveComponent("cdx-icon");
10112 const _component_cdx_toggle_button = resolveComponent("cdx-toggle-button");
10113 return openBlock(), createElementBlock(
10117 (openBlock(true), createElementBlock(
10120 renderList(_ctx.buttons, (button, index) => {
10121 return openBlock(), createBlock(_component_cdx_toggle_button, {
10124 ref: (ref2) => _ctx.assignTemplateRef(ref2, index),
10125 "model-value": _ctx.isSelected(button),
10126 disabled: button.disabled || _ctx.disabled,
10127 "aria-label": button.ariaLabel,
10128 "onUpdate:modelValue": ($event) => _ctx.onUpdate(button, $event),
10129 onFocus: ($event) => _ctx.onFocus(index),
10130 onBlur: _ctx.onBlur,
10131 onKeydown: _ctx.onKeydown
10133 default: withCtx(() => [
10134 renderSlot(_ctx.$slots, "default", {
10136 selected: _ctx.isSelected(button)
10138 button.icon ? (openBlock(), createBlock(_component_cdx_icon, {
10141 }, null, 8, ["icon"])) : createCommentVNode("v-if", true),
10143 " " + toDisplayString(_ctx.getButtonLabel(button)),
10151 }, 1032, ["model-value", "disabled", "aria-label", "onUpdate:modelValue", "onFocus", "onBlur", "onKeydown"]);
10154 /* KEYED_FRAGMENT */
10161 const ToggleButtonGroup = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
10162 const _sfc_main$1 = defineComponent({
10163 name: "CdxToggleSwitch",
10164 components: { CdxLabel },
10166 * The input element will inherit attributes, not the root element.
10168 inheritAttrs: false,
10171 * Current value of the toggle switch or toggle switch group.
10173 * Provided by `v-model` binding in the parent component.
10176 type: [Boolean, Array],
10180 * HTML "value" attribute to assign to the input element.
10182 * Required for groups of ToggleSwitches. Can be omitted for single true/false switches.
10185 type: [String, Number, Boolean],
10189 * Whether to align the switch to the end of the container.
10191 * Useful for ToggleSwitch groups, where each switch should be aligned regardless of
10199 * Whether the label should be visually hidden.
10201 * Note that this will also hide the description.
10208 * Whether the disabled attribute should be added to the input.
10217 * Emitted when modelValue changes.
10219 * @property {boolean} modelValue The new model value
10221 "update:modelValue"
10223 setup(props, { emit, slots, attrs }) {
10225 useLabelChecker((_a = slots.default) == null ? void 0 : _a.call(slots), attrs, "CdxToggleSwitch");
10226 const input = ref();
10227 const inputId = useGeneratedId("toggle-switch");
10228 const descriptionId = useGeneratedId("description");
10229 const internalClasses = computed(() => ({
10230 "cdx-toggle-switch--align-switch": props.alignSwitch
10236 } = useSplitAttributes(attrs, internalClasses);
10237 const { computedDisabled } = useFieldData(toRef(props, "disabled"));
10238 const wrappedModel = useModelWrapper(toRef(props, "modelValue"), emit);
10239 const clickInput = () => {
10240 input.value.click();
10255 const _hoisted_1$1 = ["id", "aria-describedby", "value", "disabled"];
10256 const _hoisted_2$1 = /* @__PURE__ */ createElementVNode(
10258 { class: "cdx-toggle-switch__switch" },
10260 /* @__PURE__ */ createElementVNode("span", { class: "cdx-toggle-switch__switch__grip" })
10265 function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
10266 const _component_cdx_label = resolveComponent("cdx-label");
10267 return openBlock(), createElementBlock(
10270 class: normalizeClass(["cdx-toggle-switch", _ctx.rootClasses]),
10271 style: normalizeStyle(_ctx.rootStyle)
10274 withDirectives(createElementVNode("input", mergeProps({
10277 "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.wrappedModel = $event),
10278 class: "cdx-toggle-switch__input",
10281 "aria-describedby": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
10282 value: _ctx.inputValue,
10283 disabled: _ctx.computedDisabled
10284 }, _ctx.otherAttrs, {
10285 onKeydown: _cache[1] || (_cache[1] = withKeys(withModifiers((...args) => _ctx.clickInput && _ctx.clickInput(...args), ["prevent"]), ["enter"]))
10286 }), null, 16, _hoisted_1$1), [
10287 [vModelCheckbox, _ctx.wrappedModel]
10290 _ctx.$slots.default && _ctx.$slots.default().length ? (openBlock(), createBlock(_component_cdx_label, {
10292 class: "cdx-toggle-switch__label",
10293 "input-id": _ctx.inputId,
10294 "description-id": _ctx.$slots.description && _ctx.$slots.description().length > 0 ? _ctx.descriptionId : void 0,
10295 "visually-hidden": _ctx.hideLabel,
10296 disabled: _ctx.computedDisabled
10298 default: withCtx(() => [
10299 renderSlot(_ctx.$slots, "default")
10304 _ctx.$slots.description && _ctx.$slots.description().length > 0 ? {
10305 name: "description",
10306 fn: withCtx(() => [
10307 renderSlot(_ctx.$slots, "description")
10311 ]), 1032, ["input-id", "description-id", "visually-hidden", "disabled"])) : createCommentVNode("v-if", true)
10317 const ToggleSwitch = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
10319 constructor(referenceElement, options) {
10320 __publicField(this, "referenceElement");
10321 __publicField(this, "tooltipElement");
10322 __publicField(this, "textContent");
10323 __publicField(this, "placement");
10324 __publicField(this, "autoUpdateCleanup");
10325 __publicField(this, "referenceElementHandlers");
10326 __publicField(this, "tooltipElementHandlers");
10327 __publicField(this, "escapeHandler");
10328 __publicField(this, "timeoutId");
10330 const doc = referenceElement.ownerDocument;
10331 const tooltipId = useGeneratedId("tooltip");
10332 this.referenceElement = referenceElement;
10333 this.textContent = options.textContent;
10334 this.placement = (_a = options.placement) != null ? _a : "bottom";
10335 this.timeoutId = null;
10336 this.tooltipElement = doc.createElement("div");
10337 this.tooltipElement.classList.add("cdx-tooltip");
10338 this.tooltipElement.role = "tooltip";
10339 this.tooltipElement.id = tooltipId;
10340 this.referenceElement.setAttribute("aria-describedby", tooltipId);
10341 this.tooltipElement.textContent = this.textContent;
10342 (_b = this.referenceElement.parentElement) == null ? void 0 : _b.appendChild(this.tooltipElement);
10343 this.referenceElementHandlers = {};
10344 this.referenceElementHandlers.mouseenter = this.show.bind(this);
10345 this.referenceElementHandlers.mouseleave = this.hideAfterDelay.bind(this);
10346 this.referenceElementHandlers.focus = this.show.bind(this);
10347 this.referenceElementHandlers.blur = this.hide.bind(this);
10348 this.tooltipElementHandlers = {};
10349 this.tooltipElementHandlers.mouseenter = this.show.bind(this);
10350 this.tooltipElementHandlers.mouseleave = this.hideAfterDelay.bind(this);
10351 this.escapeHandler = this.onKeyup.bind(this);
10352 this.addEventListeners();
10353 this.autoUpdateCleanup = autoUpdate(
10354 this.referenceElement,
10355 this.tooltipElement,
10356 () => this.update()
10360 return this.tooltipElement.style.display === "block";
10363 if (this.timeoutId) {
10364 clearTimeout(this.timeoutId);
10366 this.tooltipElement.style.display = "block";
10367 this.tooltipElement.ownerDocument.addEventListener("keyup", this.escapeHandler);
10370 this.tooltipElement.style.display = "none";
10371 this.tooltipElement.ownerDocument.removeEventListener("keyup", this.escapeHandler);
10374 this.timeoutId = setTimeout(this.hide.bind(this), 250);
10377 if (event.key === "Escape" && this.isVisible()) {
10381 addEventListeners() {
10382 Object.keys(this.referenceElementHandlers).forEach((k) => {
10383 this.referenceElement.addEventListener(k, this.referenceElementHandlers[k]);
10385 Object.keys(this.tooltipElementHandlers).forEach((k) => {
10386 this.tooltipElement.addEventListener(k, this.tooltipElementHandlers[k]);
10389 removeEventListeners() {
10390 Object.keys(this.referenceElementHandlers).forEach((k) => {
10391 this.referenceElement.removeEventListener(k, this.referenceElementHandlers[k]);
10393 Object.keys(this.tooltipElementHandlers).forEach((k) => {
10394 this.tooltipElement.removeEventListener(k, this.tooltipElementHandlers[k]);
10398 computePosition(this.referenceElement, this.tooltipElement, {
10399 placement: this.placement,
10406 }).then(({ x, y, middlewareData }) => {
10408 const finalPlacement = (_b = (_a = middlewareData.offset) == null ? void 0 : _a.placement) != null ? _b : this.placement;
10409 const opposites = {
10411 "left-start": "right",
10412 "left-end": "right",
10414 "top-start": "bottom",
10415 "top-end": "bottom",
10417 "bottom-start": "top",
10418 "bottom-end": "top",
10420 "right-start": "left",
10421 "right-end": "left"
10423 Object.assign(this.tooltipElement.style, {
10424 left: "".concat(x, "px"),
10425 top: "".concat(y, "px"),
10426 visibility: ((_c = middlewareData.hide) == null ? void 0 : _c.referenceHidden) ? "hidden" : "visible",
10427 transformOrigin: opposites[finalPlacement]
10432 this.tooltipElement.remove();
10433 this.autoUpdateCleanup();
10434 this.removeEventListeners();
10437 const CdxTooltip = {
10438 mounted(el, { value, arg }) {
10442 if (typeof value === "string" && value.trim() === "") {
10445 el.tooltip = new Tooltip(el, {
10446 textContent: String(value),
10450 beforeUnmount(el) {
10452 el.tooltip.remove();
10456 const _sfc_main = defineComponent({
10457 name: "CdxTypeaheadSearch",
10464 * Attributes, besides class, will be passed to the TextInput's input element.
10466 inheritAttrs: false,
10469 * ID attribute for the form.
10476 * Action attribute for form.
10483 * List of search results. See the SearchResult type.
10491 * Whether to display a submit button.
10497 // DEPRECATED: set default to 'Search' (T368444).
10499 * Custom label for the submit button.
10501 * Omit this prop to use the default value, "Search".
10508 * Initial value for the text input.
10510 * Triggers an initial `input` event on mount.
10512 initialInputValue: {
10517 * Link for the final menu item.
10519 * This will typically be a link to the search page for the current search query.
10526 * Time interval for debouncing input events, in ms.
10528 debounceInterval: {
10530 default: DebounceInterval
10533 * Whether the search query should be highlighted within a search result's title.
10540 * Whether to show search results' thumbnails (or a placeholder icon).
10547 * Contract the width of the input when unfocused and expand the width of
10548 * the input when focused to accommodate the extra width of the thumbnails.
10550 * This prop is ignored if showThumbnail is false.
10557 * Limit the number of menu items to display before scrolling.
10559 * Setting this prop to anything falsy will show all menu items.
10561 * By default, all menu items are shown.
10563 visibleItemLimit: {
10570 * When the text input value changes. Debounced by default.
10572 * @property {string} value The new input value
10576 * When a search result is selected.
10578 * @property {SearchResultClickEvent} event Data for the selected result
10580 "search-result-click",
10582 * When the form is submitted.
10584 * @property {SearchResultClickEvent} event Data for the selected result
10588 * When the user scrolls towards the bottom of the menu.
10590 * If it is possible to add or load more menu items, then now would be a good moment
10591 * so that the user can experience infinite scrolling.
10595 setup(props, { attrs, emit, slots }) {
10596 const form = ref();
10597 const menu = ref();
10598 const menuId = useGeneratedId("typeahead-search-menu");
10599 const translatedSearchResultsLabel = useI18n("cdx-typeahead-search-search-results-label", "Search results");
10600 const expanded = ref(false);
10601 const pending = ref(false);
10602 const showPending = ref(false);
10603 const isActive = ref(false);
10604 const inputValue = ref(props.initialInputValue);
10605 const searchQuery = ref("");
10606 const highlightedId = computed(() => {
10608 return (_b = (_a = menu.value) == null ? void 0 : _a.getHighlightedMenuItem()) == null ? void 0 : _b.id;
10610 const selection = ref(null);
10611 const menuMessageClass = computed(() => ({
10612 "cdx-typeahead-search__menu-message--has-thumbnail": props.showThumbnail
10614 const selectedResult = computed(
10615 () => props.searchResults.find(
10616 (searchResult) => searchResult.value === selection.value
10619 const footer = computed(
10620 () => props.searchFooterUrl ? { value: MenuFooterValue, url: props.searchFooterUrl } : void 0
10622 const internalClasses = computed(() => ({
10623 "cdx-typeahead-search--show-thumbnail": props.showThumbnail,
10624 "cdx-typeahead-search--expanded": expanded.value,
10625 "cdx-typeahead-search--auto-expand-width": props.showThumbnail && props.autoExpandWidth
10631 } = useSplitAttributes(attrs, internalClasses);
10632 function asSearchResult(menuItem) {
10635 const menuConfig = computed(() => ({
10636 visibleItemLimit: props.visibleItemLimit,
10637 showThumbnail: props.showThumbnail,
10638 // In case search queries aren't highlighted, default to a bold label.
10640 hideDescriptionOverflow: true
10643 let pendingDelayId;
10644 function onUpdateInputValue(newVal, immediate = false) {
10645 if (selectedResult.value && selectedResult.value.label !== newVal && selectedResult.value.value !== newVal) {
10646 selection.value = null;
10648 if (pendingDelayId !== void 0) {
10649 clearTimeout(pendingDelayId);
10650 pendingDelayId = void 0;
10652 if (newVal === "") {
10653 expanded.value = false;
10655 pending.value = true;
10656 if (slots["search-results-pending"]) {
10657 pendingDelayId = setTimeout(() => {
10658 if (isActive.value) {
10659 expanded.value = true;
10661 showPending.value = true;
10665 if (debounceId !== void 0) {
10666 clearTimeout(debounceId);
10667 debounceId = void 0;
10669 const handleUpdateInputValue = () => {
10670 emit("input", newVal);
10673 handleUpdateInputValue();
10675 debounceId = setTimeout(() => {
10676 handleUpdateInputValue();
10677 }, props.debounceInterval);
10680 function onUpdateMenuSelection(newVal) {
10682 if (newVal === MenuFooterValue) {
10683 selection.value = null;
10684 inputValue.value = searchQuery.value;
10687 selection.value = newVal;
10688 if (newVal !== null) {
10689 inputValue.value = selectedResult.value ? (_a = selectedResult.value.label) != null ? _a : String(selectedResult.value.value) : "";
10692 function onFocus() {
10693 isActive.value = true;
10694 if (searchQuery.value || showPending.value) {
10695 expanded.value = true;
10698 function onBlur() {
10699 isActive.value = false;
10700 expanded.value = false;
10702 function onSearchResultClick(searchResult) {
10703 const _a = searchResult, { id } = _a, resultWithoutId = __objRest(_a, ["id"]);
10704 if (resultWithoutId.value === MenuFooterValue) {
10705 emit("search-result-click", {
10706 searchResult: null,
10707 index: props.searchResults.length,
10708 numberOfResults: props.searchResults.length
10712 emitSearchResultClick(resultWithoutId);
10714 function emitSearchResultClick(searchResult) {
10715 const searchResultClickEvent = {
10717 index: props.searchResults.findIndex(
10718 (r) => r.value === searchResult.value
10720 numberOfResults: props.searchResults.length
10722 emit("search-result-click", searchResultClickEvent);
10724 function onSearchResultKeyboardNavigation(searchResult) {
10726 if (searchResult.value === MenuFooterValue) {
10727 inputValue.value = searchQuery.value;
10730 inputValue.value = searchResult.value ? (_a = searchResult.label) != null ? _a : String(searchResult.value) : "";
10732 function onSearchFooterClick(footerMenuItem) {
10734 expanded.value = false;
10735 (_a = menu.value) == null ? void 0 : _a.clearActive();
10736 onSearchResultClick(footerMenuItem);
10738 function onSubmit(e) {
10739 if (selectedResult.value) {
10740 emitSearchResultClick(selectedResult.value);
10741 e.stopPropagation();
10742 window.location.assign(selectedResult.value.url);
10743 e.preventDefault();
10745 const submitEvent = {
10746 searchResult: null,
10748 numberOfResults: props.searchResults.length
10750 emit("submit", submitEvent);
10753 function onKeydown(e) {
10754 if (!menu.value || !searchQuery.value || e.key === " ") {
10757 const highlightedResult = menu.value.getHighlightedMenuItem();
10758 const resultHighlightedViaKeyboard = menu.value.getHighlightedViaKeyboard();
10761 if (highlightedResult) {
10762 if (highlightedResult.value === MenuFooterValue && resultHighlightedViaKeyboard) {
10763 window.location.assign(props.searchFooterUrl);
10765 menu.value.delegateKeyNavigation(e, { prevent: false });
10768 expanded.value = false;
10771 expanded.value = false;
10774 menu.value.delegateKeyNavigation(e);
10779 if (props.initialInputValue) {
10780 onUpdateInputValue(props.initialInputValue, true);
10783 watch(toRef(props, "searchResults"), () => {
10784 searchQuery.value = inputValue.value.trim();
10785 if (isActive.value && pending.value && searchQuery.value.length > 0) {
10786 expanded.value = true;
10788 if (pendingDelayId !== void 0) {
10789 clearTimeout(pendingDelayId);
10790 pendingDelayId = void 0;
10792 pending.value = false;
10793 showPending.value = false;
10812 onUpdateInputValue,
10813 onUpdateMenuSelection,
10816 onSearchResultClick,
10817 onSearchResultKeyboardNavigation,
10818 onSearchFooterClick,
10823 translatedSearchResultsLabel
10828 * Focus the component's input element.
10833 const searchInput = this.$refs.searchInput;
10834 searchInput.focus();
10838 const _hoisted_1 = ["id", "action"];
10839 const _hoisted_2 = { class: "cdx-typeahead-search__menu-message__text" };
10840 const _hoisted_3 = { class: "cdx-typeahead-search__menu-message__text" };
10841 const _hoisted_4 = ["href", "onClickCapture"];
10842 const _hoisted_5 = { class: "cdx-menu-item__text cdx-typeahead-search__search-footer__text" };
10843 const _hoisted_6 = { class: "cdx-typeahead-search__search-footer__query" };
10844 function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
10845 const _component_cdx_icon = resolveComponent("cdx-icon");
10846 const _component_cdx_menu = resolveComponent("cdx-menu");
10847 const _component_cdx_search_input = resolveComponent("cdx-search-input");
10848 return openBlock(), createElementBlock(
10851 class: normalizeClass(["cdx-typeahead-search", _ctx.rootClasses]),
10852 style: normalizeStyle(_ctx.rootStyle)
10855 createElementVNode("form", {
10858 class: "cdx-typeahead-search__form",
10859 action: _ctx.formAction,
10860 onSubmit: _cache[4] || (_cache[4] = (...args) => _ctx.onSubmit && _ctx.onSubmit(...args))
10862 createVNode(_component_cdx_search_input, mergeProps({
10863 ref: "searchInput",
10864 modelValue: _ctx.inputValue,
10865 "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => _ctx.inputValue = $event),
10866 "button-label": _ctx.buttonLabel,
10867 "use-button": _ctx.useButton
10868 }, _ctx.otherAttrs, {
10869 class: "cdx-typeahead-search__input",
10872 autocomplete: "off",
10873 "aria-autocomplete": "list",
10874 "aria-controls": _ctx.menuId,
10875 "aria-expanded": _ctx.expanded,
10876 "aria-activedescendant": _ctx.highlightedId,
10877 "onUpdate:modelValue": _ctx.onUpdateInputValue,
10878 onFocus: _ctx.onFocus,
10879 onBlur: _ctx.onBlur,
10880 onKeydown: _ctx.onKeydown
10882 default: withCtx(() => [
10883 createVNode(_component_cdx_menu, mergeProps({
10886 expanded: _ctx.expanded,
10887 "onUpdate:expanded": _cache[0] || (_cache[0] = ($event) => _ctx.expanded = $event),
10888 class: "cdx-typeahead-search__menu",
10889 "show-pending": _ctx.showPending,
10890 selected: _ctx.selection,
10891 "menu-items": _ctx.searchResults,
10892 footer: _ctx.footer,
10893 "search-query": _ctx.highlightQuery ? _ctx.searchQuery : "",
10894 "show-no-results-slot": _ctx.searchQuery.length > 0 && _ctx.searchResults.length === 0 && _ctx.$slots["search-no-results-text"] && _ctx.$slots["search-no-results-text"]().length > 0
10895 }, _ctx.menuConfig, {
10896 "aria-label": _ctx.translatedSearchResultsLabel,
10897 "onUpdate:selected": _ctx.onUpdateMenuSelection,
10898 onMenuItemClick: _cache[1] || (_cache[1] = (menuItem) => _ctx.onSearchResultClick(_ctx.asSearchResult(menuItem))),
10899 onMenuItemKeyboardNavigation: _ctx.onSearchResultKeyboardNavigation,
10900 onLoadMore: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("load-more"))
10902 pending: withCtx(() => [
10903 createElementVNode(
10906 class: normalizeClass(["cdx-menu-item__content cdx-typeahead-search__menu-message", _ctx.menuMessageClass])
10909 createElementVNode("span", _hoisted_2, [
10910 renderSlot(_ctx.$slots, "search-results-pending")
10917 "no-results": withCtx(() => [
10918 createElementVNode(
10921 class: normalizeClass(["cdx-menu-item__content cdx-typeahead-search__menu-message", _ctx.menuMessageClass])
10924 createElementVNode("span", _hoisted_3, [
10925 renderSlot(_ctx.$slots, "search-no-results-text")
10932 default: withCtx(({ menuItem, active }) => [
10933 menuItem.value === _ctx.MenuFooterValue ? (openBlock(), createElementBlock("a", {
10935 class: normalizeClass(["cdx-menu-item__content cdx-typeahead-search__search-footer", {
10936 "cdx-typeahead-search__search-footer__active": active
10938 href: _ctx.asSearchResult(menuItem).url,
10939 onClickCapture: withModifiers(($event) => _ctx.onSearchFooterClick(_ctx.asSearchResult(menuItem)), ["stop"])
10941 createVNode(_component_cdx_icon, {
10942 class: "cdx-menu-item__thumbnail cdx-typeahead-search__search-footer__icon",
10943 icon: _ctx.articleIcon
10944 }, null, 8, ["icon"]),
10945 createElementVNode("span", _hoisted_5, [
10946 renderSlot(_ctx.$slots, "search-footer-text", { searchQuery: _ctx.searchQuery }, () => [
10947 createElementVNode(
10950 toDisplayString(_ctx.searchQuery),
10956 ], 42, _hoisted_4)) : createCommentVNode("v-if", true)
10960 }, 16, ["id", "expanded", "show-pending", "selected", "menu-items", "footer", "search-query", "show-no-results-slot", "aria-label", "onUpdate:selected", "onMenuItemKeyboardNavigation"])
10964 }, 16, ["modelValue", "button-label", "use-button", "aria-controls", "aria-expanded", "aria-activedescendant", "onUpdate:modelValue", "onFocus", "onBlur", "onKeydown"]),
10965 renderSlot(_ctx.$slots, "default")
10972 const TypeaheadSearch = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
10974 Accordion as CdxAccordion,
10976 ButtonGroup as CdxButtonGroup,
10980 Combobox as CdxCombobox,
10981 Dialog as CdxDialog,
10984 InfoChip as CdxInfoChip,
10986 Lookup as CdxLookup,
10988 MenuButton as CdxMenuButton,
10991 MultiselectLookup as CdxMultiselectLookup,
10995 CdxSearchResultTitle,
11000 TextArea as CdxTextArea,
11004 ToggleButtonGroup as CdxToggleButtonGroup,
11005 ToggleSwitch as CdxToggleSwitch,
11007 TypeaheadSearch as CdxTypeaheadSearch,
11008 TableRowIdentifier,
11010 useComputedDirection,
11011 useComputedDisabled,
11012 useComputedLanguage,
11017 useIntersectionObserver,
11021 useSplitAttributes,