@eos-ui/vue 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/components/Avatar/EAvatar.js.map +1 -1
  2. package/dist/components/Avatar/EAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/Button/EButton.js.map +1 -1
  4. package/dist/components/Button/EButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  5. package/dist/components/Combobox/EComboboxBase.js.map +1 -1
  6. package/dist/components/Combobox/EComboboxBase.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/components/DataGrid/EDataGrid.js.map +1 -1
  8. package/dist/components/DataGrid/EDataGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/NavList/ENavList.js.map +1 -1
  10. package/dist/components/NavList/ENavList.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/Notice/ENotice.js.map +1 -1
  12. package/dist/components/Notice/ENotice.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/Progress/EProgress.js.map +1 -1
  14. package/dist/components/Progress/EProgress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  15. package/dist/components/SearchBar/ESearchBar.js.map +1 -1
  16. package/dist/components/SearchBar/ESearchBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/Segmented/ESegmented.js.map +1 -1
  18. package/dist/components/Segmented/ESegmented.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/components/Select/ESelectControl.js.map +1 -1
  20. package/dist/components/Select/ESelectControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/SignaturePad/ESignaturePad.js.map +1 -1
  22. package/dist/components/SignaturePad/ESignaturePad.vue_vue_type_script_setup_true_lang.js.map +1 -1
  23. package/dist/components/Stepper/EStepper.js.map +1 -1
  24. package/dist/components/Stepper/EStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  25. package/dist/components/Switch/ESwitch.js.map +1 -1
  26. package/dist/components/Switch/ESwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/components/Tabs/ETabs.js.map +1 -1
  28. package/dist/components/Tabs/ETabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  29. package/dist/components/Textarea/ETextarea.js.map +1 -1
  30. package/dist/components/Textarea/ETextarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  31. package/dist/style.css +147 -124
  32. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"EAvatar.js","names":["_sfc_main","EAvatar_vue_vue_type_script_setup_true_lang_default","EAvatar_default"],"sources":["../../../src/components/Avatar/EAvatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The person's name. Screen readers read it; the initials are the first letters of its first and last word. */\n name: string;\n /** A photo URL. If it fails to load, the initials appear. */\n src?: string;\n /** 32px, for rows and bars. */\n small?: boolean;\n /** 64px, for a profile or practitioner on an appointment card. The default is 44px. */\n large?: boolean;\n /** `button` renders a `button` with `type=\"button\"`, a pointer cursor and a focus ring, named by `name`, such as the `trigger` of an `EMenu`. */\n as?: \"span\" | \"button\";\n }>(),\n { as: \"span\" },\n);\n\nconst failed = ref(false);\nwatch(\n () => props.src,\n () => (failed.value = false),\n);\n\nconst initials = computed(() => {\n const parts = String(props.name || \"?\")\n .split(/\\s+/)\n .filter(Boolean);\n const first = [...(parts[0] ?? \"?\")][0] ?? \"?\";\n const last = parts.length > 1 ? ([...parts[parts.length - 1]!][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"e-avatar\"\n :class=\"{ 'e-avatar--s': small, 'e-avatar--l': large, 'e-avatar--button': as === 'button' }\"\n :type=\"as === 'button' ? 'button' : undefined\"\n :role=\"as === 'button' ? undefined : 'img'\"\n :aria-label=\"as === 'button' ? undefined : name\"\n >\n <img v-if=\"src && !failed\" class=\"e-avatar-img\" :src=\"src\" alt=\"\" @error=\"failed = true\" />\n <span v-else-if=\"as === 'button'\" aria-hidden=\"true\">{{ initials }}</span>\n <template v-else>{{ initials }}</template>\n <span v-if=\"as === 'button'\" class=\"e-sr\">{{ name }}</span>\n </component>\n</template>\n\n<style>\n@layer e.primitives {\n .e-avatar {\n --e-ring: var(--e-border-strong);\n\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: none;\n box-sizing: border-box;\n width: var(--e-tap, 44px);\n height: var(--e-tap, 44px);\n overflow: hidden;\n border: 0;\n border-radius: var(--e-radius-md);\n background: var(--e-surface-tint);\n color: var(--e-primary);\n font: 600 var(--e-text-sm) / 1 var(--e-font-mono);\n letter-spacing: 0.02em;\n }\n\n /* The ring sits over the picture so an image never covers it. */\n .e-avatar::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n pointer-events: none;\n transition: box-shadow var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-avatar--button {\n position: relative;\n padding: 0;\n cursor: pointer;\n }\n\n .e-avatar--button:hover {\n --e-ring: var(--e-ink);\n }\n\n .e-avatar--button:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-avatar--button {\n transition: none;\n }\n }\n\n .e-avatar--s {\n width: 32px;\n height: 32px;\n font-size: var(--e-text-xs);\n border-radius: var(--e-radius-sm);\n }\n\n .e-avatar--l {\n width: 64px;\n height: 64px;\n font-size: var(--e-text-lg);\n }\n\n .e-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n @media (forced-colors: active) {\n .e-avatar {\n border-color: CanvasText;\n outline-color: CanvasText;\n color: CanvasText;\n }\n\n .e-avatar--button:focus-visible {\n outline-color: Highlight;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"EAvatar.js","names":["_sfc_main","EAvatar_vue_vue_type_script_setup_true_lang_default","EAvatar_default"],"sources":["../../../src/components/Avatar/EAvatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The person's name. Screen readers read it; the initials are the first letters of its first and last word. */\n name: string;\n /** A photo URL. If it fails to load, the initials appear. */\n src?: string;\n /** 32px, for rows and bars. */\n small?: boolean;\n /** 64px, for a profile or practitioner on an appointment card. The default is 44px. */\n large?: boolean;\n /** `button` renders a `button` with `type=\"button\"`, a pointer cursor and a focus ring, named by `name`, such as the `trigger` of an `EMenu`. */\n as?: \"span\" | \"button\";\n }>(),\n { as: \"span\" },\n);\n\nconst failed = ref(false);\nwatch(\n () => props.src,\n () => (failed.value = false),\n);\n\nconst initials = computed(() => {\n const parts = String(props.name || \"?\")\n .split(/\\s+/)\n .filter(Boolean);\n const first = [...(parts[0] ?? \"?\")][0] ?? \"?\";\n const last = parts.length > 1 ? ([...parts[parts.length - 1]!][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"e-avatar\"\n :class=\"{ 'e-avatar--s': small, 'e-avatar--l': large, 'e-avatar--button': as === 'button' }\"\n :type=\"as === 'button' ? 'button' : undefined\"\n :role=\"as === 'button' ? undefined : 'img'\"\n :aria-label=\"as === 'button' ? undefined : name\"\n >\n <img v-if=\"src && !failed\" class=\"e-avatar-img\" :src=\"src\" alt=\"\" @error=\"failed = true\" />\n <span v-else-if=\"as === 'button'\" aria-hidden=\"true\">{{ initials }}</span>\n <template v-else>{{ initials }}</template>\n <span v-if=\"as === 'button'\" class=\"e-sr\">{{ name }}</span>\n </component>\n</template>\n\n<style>\n@layer e.primitives {\n .e-avatar {\n --e-ring: var(--e-border-strong);\n\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: none;\n box-sizing: border-box;\n width: var(--e-tap, 44px);\n height: var(--e-tap, 44px);\n overflow: hidden;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface-tint);\n background-clip: padding-box;\n color: var(--e-primary);\n font: 600 var(--e-text-sm) / 1 var(--e-font-mono);\n letter-spacing: 0.02em;\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-avatar--button {\n position: relative;\n padding: 0;\n cursor: pointer;\n }\n\n .e-avatar--button:hover {\n --e-ring: var(--e-ink);\n }\n\n .e-avatar--button:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-avatar--button {\n transition: none;\n }\n }\n\n .e-avatar--s {\n width: 32px;\n height: 32px;\n font-size: var(--e-text-xs);\n border-radius: var(--e-radius-sm);\n }\n\n .e-avatar--l {\n width: 64px;\n height: 64px;\n font-size: var(--e-text-lg);\n }\n\n .e-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n @media (forced-colors: active) {\n .e-avatar {\n border-color: CanvasText;\n outline-color: CanvasText;\n color: CanvasText;\n }\n\n .e-avatar--button:focus-visible {\n outline-color: Highlight;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"EAvatar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_withCtx","_createElementBlock","_toDisplayString","_Fragment","_createTextVNode","_createCommentVNode","_hoisted_1","_hoisted_2","_hoisted_3","EAvatar_vue_vue_type_script_setup_true_lang_default","props","__props","failed","ref","initials","computed","parts","openBlock","createBlock","resolveDynamicComponent","normalizeClass","withCtx","createElementBlock","_cache","toDisplayString","Fragment","createTextVNode","createCommentVNode"],"sources":["../../../src/components/Avatar/EAvatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The person's name. Screen readers read it; the initials are the first letters of its first and last word. */\n name: string;\n /** A photo URL. If it fails to load, the initials appear. */\n src?: string;\n /** 32px, for rows and bars. */\n small?: boolean;\n /** 64px, for a profile or practitioner on an appointment card. The default is 44px. */\n large?: boolean;\n /** `button` renders a `button` with `type=\"button\"`, a pointer cursor and a focus ring, named by `name`, such as the `trigger` of an `EMenu`. */\n as?: \"span\" | \"button\";\n }>(),\n { as: \"span\" },\n);\n\nconst failed = ref(false);\nwatch(\n () => props.src,\n () => (failed.value = false),\n);\n\nconst initials = computed(() => {\n const parts = String(props.name || \"?\")\n .split(/\\s+/)\n .filter(Boolean);\n const first = [...(parts[0] ?? \"?\")][0] ?? \"?\";\n const last = parts.length > 1 ? ([...parts[parts.length - 1]!][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"e-avatar\"\n :class=\"{ 'e-avatar--s': small, 'e-avatar--l': large, 'e-avatar--button': as === 'button' }\"\n :type=\"as === 'button' ? 'button' : undefined\"\n :role=\"as === 'button' ? undefined : 'img'\"\n :aria-label=\"as === 'button' ? undefined : name\"\n >\n <img v-if=\"src && !failed\" class=\"e-avatar-img\" :src=\"src\" alt=\"\" @error=\"failed = true\" />\n <span v-else-if=\"as === 'button'\" aria-hidden=\"true\">{{ initials }}</span>\n <template v-else>{{ initials }}</template>\n <span v-if=\"as === 'button'\" class=\"e-sr\">{{ name }}</span>\n </component>\n</template>\n\n<style>\n@layer e.primitives {\n .e-avatar {\n --e-ring: var(--e-border-strong);\n\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: none;\n box-sizing: border-box;\n width: var(--e-tap, 44px);\n height: var(--e-tap, 44px);\n overflow: hidden;\n border: 0;\n border-radius: var(--e-radius-md);\n background: var(--e-surface-tint);\n color: var(--e-primary);\n font: 600 var(--e-text-sm) / 1 var(--e-font-mono);\n letter-spacing: 0.02em;\n }\n\n /* The ring sits over the picture so an image never covers it. */\n .e-avatar::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n pointer-events: none;\n transition: box-shadow var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-avatar--button {\n position: relative;\n padding: 0;\n cursor: pointer;\n }\n\n .e-avatar--button:hover {\n --e-ring: var(--e-ink);\n }\n\n .e-avatar--button:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-avatar--button {\n transition: none;\n }\n }\n\n .e-avatar--s {\n width: 32px;\n height: 32px;\n font-size: var(--e-text-xs);\n border-radius: var(--e-radius-sm);\n }\n\n .e-avatar--l {\n width: 64px;\n height: 64px;\n font-size: var(--e-text-lg);\n }\n\n .e-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n @media (forced-colors: active) {\n .e-avatar {\n border-color: CanvasText;\n outline-color: CanvasText;\n color: CanvasText;\n }\n\n .e-avatar--button:focus-visible {\n outline-color: Highlight;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAIA,IAAMc,IAAQC,GAgBRC,IAASC,EAAI,EAAK;EACxB,QACQH,EAAM,WACL,EAAO,QAAQ,EACxB;EAEA,IAAMI,IAAWC,QAAe;GAC9B,IAAMC,IAAQ,OAAON,EAAM,QAAQ,GAAG,CAAA,CACnC,MAAM,KAAK,CAAA,CACX,OAAO,OAAO;GAGjB,SAFc,CAAC,GAAIM,EAAM,MAAM,GAAI,CAAC,CAAC,MAAM,QAC9BA,EAAM,SAAS,IAAK,CAAC,GAAGA,EAAMA,EAAM,SAAS,EAAG,CAAC,CAAC,MAAM,KAAM,IAAA,CACrD,YAAY;EACpC,CAAC;E,kBAICpB,EAAA,GAAAC,EAYYC,EAXLa,EAAA,EAAE,GAAA;GACP,OAAKZ,EAAA,CAAC,YAAU;IAAA,eACSY,EAAA;IAAK,eAAiBA,EAAA;IAAK,oBAAsBA,EAAA,OAAE;GAAA,CAAA,CAAA;GAC3E,MAAMA,EAAA,OAAE,WAAA,WAA2B,KAAA;GACnC,MAAMA,EAAA,OAAE,WAAgB,KAAA,IAAS;GACjC,cAAYA,EAAA,OAAE,WAAgB,KAAA,IAAYA,EAAA;;GAE3C,SAAAX,QAA2F,CAAhFW,EAAA,OAAG,CAAKC,EAAA,SAAnBhB,EAAA,GAAAK,EAA2F,OAAA;;IAAhE,OAAM;IAAgB,KAAKU,EAAA;IAAK,KAAI;IAAI,SAAK,AAAAY,EAAA,QAAA,MAAE,EAAA,QAAM;G,mBAC/DZ,EAAA,OAAE,YAAnBf,EAAA,GAAAK,EAA0E,QAA1EM,GAA0EL,EAAlBY,EAAA,KAAQ,GAAA,CAAA,MAChElB,EAAA,GAAAK,EAA0CE,GAAA,EAAA,KAAA,EAAA,GAAA,CAAtBC,EAAAF,EAAAY,EAAA,KAAQ,GAAA,CAAA,C,SAChBH,EAAA,OAAE,YAAdf,EAAA,GAAAK,EAA2D,QAA3DO,GAA2DN,EAAdS,EAAA,IAAI,GAAA,CAAA,K"}
1
+ {"version":3,"file":"EAvatar.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeClass","_withCtx","_createElementBlock","_toDisplayString","_Fragment","_createTextVNode","_createCommentVNode","_hoisted_1","_hoisted_2","_hoisted_3","EAvatar_vue_vue_type_script_setup_true_lang_default","props","__props","failed","ref","initials","computed","parts","openBlock","createBlock","resolveDynamicComponent","normalizeClass","withCtx","createElementBlock","_cache","toDisplayString","Fragment","createTextVNode","createCommentVNode"],"sources":["../../../src/components/Avatar/EAvatar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** The person's name. Screen readers read it; the initials are the first letters of its first and last word. */\n name: string;\n /** A photo URL. If it fails to load, the initials appear. */\n src?: string;\n /** 32px, for rows and bars. */\n small?: boolean;\n /** 64px, for a profile or practitioner on an appointment card. The default is 44px. */\n large?: boolean;\n /** `button` renders a `button` with `type=\"button\"`, a pointer cursor and a focus ring, named by `name`, such as the `trigger` of an `EMenu`. */\n as?: \"span\" | \"button\";\n }>(),\n { as: \"span\" },\n);\n\nconst failed = ref(false);\nwatch(\n () => props.src,\n () => (failed.value = false),\n);\n\nconst initials = computed(() => {\n const parts = String(props.name || \"?\")\n .split(/\\s+/)\n .filter(Boolean);\n const first = [...(parts[0] ?? \"?\")][0] ?? \"?\";\n const last = parts.length > 1 ? ([...parts[parts.length - 1]!][0] ?? \"\") : \"\";\n return (first + last).toUpperCase();\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n class=\"e-avatar\"\n :class=\"{ 'e-avatar--s': small, 'e-avatar--l': large, 'e-avatar--button': as === 'button' }\"\n :type=\"as === 'button' ? 'button' : undefined\"\n :role=\"as === 'button' ? undefined : 'img'\"\n :aria-label=\"as === 'button' ? undefined : name\"\n >\n <img v-if=\"src && !failed\" class=\"e-avatar-img\" :src=\"src\" alt=\"\" @error=\"failed = true\" />\n <span v-else-if=\"as === 'button'\" aria-hidden=\"true\">{{ initials }}</span>\n <template v-else>{{ initials }}</template>\n <span v-if=\"as === 'button'\" class=\"e-sr\">{{ name }}</span>\n </component>\n</template>\n\n<style>\n@layer e.primitives {\n .e-avatar {\n --e-ring: var(--e-border-strong);\n\n position: relative;\n display: inline-grid;\n place-items: center;\n flex: none;\n box-sizing: border-box;\n width: var(--e-tap, 44px);\n height: var(--e-tap, 44px);\n overflow: hidden;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface-tint);\n background-clip: padding-box;\n color: var(--e-primary);\n font: 600 var(--e-text-sm) / 1 var(--e-font-mono);\n letter-spacing: 0.02em;\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-avatar--button {\n position: relative;\n padding: 0;\n cursor: pointer;\n }\n\n .e-avatar--button:hover {\n --e-ring: var(--e-ink);\n }\n\n .e-avatar--button:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-avatar--button {\n transition: none;\n }\n }\n\n .e-avatar--s {\n width: 32px;\n height: 32px;\n font-size: var(--e-text-xs);\n border-radius: var(--e-radius-sm);\n }\n\n .e-avatar--l {\n width: 64px;\n height: 64px;\n font-size: var(--e-text-lg);\n }\n\n .e-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n }\n\n @media (forced-colors: active) {\n .e-avatar {\n border-color: CanvasText;\n outline-color: CanvasText;\n color: CanvasText;\n }\n\n .e-avatar--button:focus-visible {\n outline-color: Highlight;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;EAIA,IAAMc,IAAQC,GAgBRC,IAASC,EAAI,EAAK;EACxB,QACQH,EAAM,WACL,EAAO,QAAQ,EACxB;EAEA,IAAMI,IAAWC,QAAe;GAC9B,IAAMC,IAAQ,OAAON,EAAM,QAAQ,GAAG,CAAA,CACnC,MAAM,KAAK,CAAA,CACX,OAAO,OAAO;GAGjB,SAFc,CAAC,GAAIM,EAAM,MAAM,GAAI,CAAC,CAAC,MAAM,QAC9BA,EAAM,SAAS,IAAK,CAAC,GAAGA,EAAMA,EAAM,SAAS,EAAG,CAAC,CAAC,MAAM,KAAM,IAAA,CACrD,YAAY;EACpC,CAAC;E,kBAICpB,EAAA,GAAAC,EAYYC,EAXLa,EAAA,EAAE,GAAA;GACP,OAAKZ,EAAA,CAAC,YAAU;IAAA,eACSY,EAAA;IAAK,eAAiBA,EAAA;IAAK,oBAAsBA,EAAA,OAAE;GAAA,CAAA,CAAA;GAC3E,MAAMA,EAAA,OAAE,WAAA,WAA2B,KAAA;GACnC,MAAMA,EAAA,OAAE,WAAgB,KAAA,IAAS;GACjC,cAAYA,EAAA,OAAE,WAAgB,KAAA,IAAYA,EAAA;;GAE3C,SAAAX,QAA2F,CAAhFW,EAAA,OAAG,CAAKC,EAAA,SAAnBhB,EAAA,GAAAK,EAA2F,OAAA;;IAAhE,OAAM;IAAgB,KAAKU,EAAA;IAAK,KAAI;IAAI,SAAK,AAAAY,EAAA,QAAA,MAAE,EAAA,QAAM;G,mBAC/DZ,EAAA,OAAE,YAAnBf,EAAA,GAAAK,EAA0E,QAA1EM,GAA0EL,EAAlBY,EAAA,KAAQ,GAAA,CAAA,MAChElB,EAAA,GAAAK,EAA0CE,GAAA,EAAA,KAAA,EAAA,GAAA,CAAtBC,EAAAF,EAAAY,EAAA,KAAQ,GAAA,CAAA,C,SAChBH,EAAA,OAAE,YAAdf,EAAA,GAAAK,EAA2D,QAA3DO,GAA2DN,EAAdS,EAAA,IAAI,GAAA,CAAA,K"}
@@ -1 +1 @@
1
- {"version":3,"file":"EButton.js","names":["_sfc_main","EButton_vue_vue_type_script_setup_true_lang_default","EButton_default"],"sources":["../../../src/components/Button/EButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** `primary` is the one main action on a screen; `secondary` confirms; `outline` is for the other actions beside it; `danger` cancels or removes; `quiet` is an underlined text action. */\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"danger\" | \"quiet\";\n /** An icon before the label: a name such as `download`, or a component. */\n icon?: IconProp;\n /** Full width. */\n block?: boolean;\n /** Dashed and unfilled; not focusable, ignores clicks. With `href` the link gets `aria-disabled=\"true\"` and `tabindex=\"-1\"` and does not navigate. */\n disabled?: boolean;\n /** Set `submit` on the one that submits a form. */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Renders a link that looks like the button, for a destination rather than an action (a call to action that goes to a page). Space does not follow it. */\n href?: string;\n /** With `href`: opens in a new tab. */\n external?: boolean;\n /** Swaps the icon for a spinner, flattens the face, dashes its edge and animates stripes across it, and ignores clicks while an action runs. The button keeps its width and stays focusable, and is announced as busy. */\n loading?: boolean;\n }>(),\n { variant: \"primary\", type: \"button\" },\n);\n\ndefineSlots<{\n /** The label: a verb that says what happens, like \"Pay $162.40\". */\n default(): unknown;\n}>();\n\nfunction blockWhenDisabled(event: Event) {\n if (!props.disabled && !props.loading) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n</script>\n\n<template>\n <a\n v-if=\"href\"\n :href=\"href\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noreferrer' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click.capture=\"blockWhenDisabled\"\n @auxclick.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </a>\n <button\n v-else\n :type=\"type\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :disabled=\"disabled\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </button>\n</template>\n\n<style>\n@layer e.primitives {\n .e-btn {\n --e-fill: var(--e-primary);\n --e-on-fill: var(--e-on-primary);\n --e-slab: color-mix(in srgb, var(--e-fill), var(--e-shade-slab));\n --e-hover: color-mix(in srgb, var(--e-fill), var(--e-shade-hover));\n --e-press: color-mix(in srgb, var(--e-fill), var(--e-shade-press));\n\n /* One rounded box, one control height tall. The slab is an inset shadow shifted up by the lift: the part of the box left uncovered along its bottom, which follows the corners up the sides, in the colour of the box's own edge. It is cut by the box's one outline, so nothing sits behind the curve. Pressing sinks the face over it. */\n --e-lift: var(--e-depth);\n --e-band: calc(var(--e-lift) + var(--e-stroke-edge));\n --e-ring: var(--e-slab);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--e-space-2);\n height: var(--e-control-height);\n padding: 0 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: var(--e-radius-md);\n background-color: var(--e-fill);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-ring),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\n color: var(--e-on-fill);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n letter-spacing: 0.01em;\n white-space: nowrap;\n text-decoration: none;\n cursor: pointer;\n transition:\n box-shadow var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-btn:hover {\n --e-slab: color-mix(in srgb, var(--e-hover), var(--e-shade-slab));\n\n background-color: var(--e-hover);\n }\n\n .e-btn:active {\n --e-lift: 0px;\n\n background-color: var(--e-press);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n }\n\n .e-btn--secondary {\n --e-fill: var(--e-secondary);\n --e-on-fill: var(--e-on-secondary);\n }\n\n .e-btn--danger {\n --e-fill: var(--e-danger);\n --e-on-fill: var(--e-on-danger);\n }\n\n .e-btn--outline {\n --e-fill: var(--e-surface);\n --e-on-fill: var(--e-ink);\n --e-slab: var(--e-border-strong);\n }\n\n .e-btn--outline:hover {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-hover));\n }\n\n .e-btn--outline:active {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-press));\n }\n\n .e-btn--quiet {\n --e-ring: transparent;\n --e-lift: 0px;\n\n background: transparent;\n color: var(--e-ink);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n padding-inline: var(--e-space-3);\n text-decoration: underline;\n text-underline-offset: 5px;\n text-decoration-thickness: var(--e-stroke-edge);\n text-decoration-color: var(--e-border-strong);\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):hover {\n --e-ring: var(--e-wash-ring);\n\n background: var(--e-wash-hover);\n text-decoration-color: currentcolor;\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):active {\n --e-ring: var(--e-ink);\n\n background: var(--e-wash-press);\n transform: none;\n }\n\n .e-btn .e-icon,\n .e-btn-spinner {\n margin-inline-start: calc(-0.5 * var(--e-space-1));\n }\n\n .e-btn-spinner {\n flex: none;\n width: 1.125em;\n height: 1.125em;\n fill: none;\n stroke: currentcolor;\n stroke-width: 3;\n stroke-linecap: round;\n stroke-dasharray: 36 56;\n animation: e-btn-spin 0.9s linear infinite;\n }\n\n /* Busy reads as unavailable and in progress: a soft tint of the button's colour with a dashed edge like a disabled button, and stripes that move. The face grows over its slab, so the button stays one control height tall. The edge is a pseudo-element, so a page's focus reset cannot remove it. */\n .e-btn--loading {\n --e-lift: 0px;\n --e-tint: var(--e-fill);\n --e-busy: color-mix(in srgb, var(--e-tint) 80%, var(--e-ink));\n }\n\n .e-btn--outline.e-btn--loading {\n --e-tint: var(--e-border-strong);\n }\n\n .e-btn--loading,\n .e-btn--loading:hover,\n .e-btn--loading:active {\n background-color: color-mix(in srgb, var(--e-tint) 14%, var(--e-surface));\n background-image: repeating-linear-gradient(135deg, transparent 0 8px, color-mix(in srgb, var(--e-tint) 20%, transparent) 8px 16px);\n background-size: 22.63px 22.63px;\n box-shadow: none;\n color: var(--e-busy);\n transform: none;\n cursor: not-allowed;\n animation: e-btn-stripes 0.8s linear infinite;\n }\n\n .e-btn--loading::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border: var(--e-stroke-edge) dashed var(--e-busy);\n border-radius: inherit;\n pointer-events: none;\n }\n\n @keyframes e-btn-stripes {\n to {\n background-position-x: 22.63px;\n }\n }\n\n @keyframes e-btn-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .e-btn--block {\n width: 100%;\n }\n\n /* A toggle: any button with aria-pressed=\"true\" reads as selected. */\n .e-btn[aria-pressed=\"true\"],\n .e-btn[aria-pressed=\"true\"]:hover,\n .e-btn[aria-pressed=\"true\"]:active {\n --e-slab: var(--e-primary);\n --e-ring: var(--e-primary);\n\n background-color: var(--e-surface-hover);\n color: var(--e-primary);\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n --e-lift: 0px;\n\n cursor: not-allowed;\n background: transparent;\n color: var(--e-muted);\n outline: var(--e-stroke-edge) dashed var(--e-border-strong);\n outline-offset: calc(-1 * var(--e-stroke-edge));\n box-shadow: none;\n transform: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-btn {\n transition: none;\n }\n\n .e-btn-spinner {\n animation-duration: 3s;\n }\n\n .e-btn--loading {\n animation: none;\n }\n }\n\n @media print {\n .e-btn {\n display: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-btn {\n border: var(--e-stroke-focus) solid ButtonText;\n }\n\n .e-btn[aria-pressed=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n outline-color: GrayText;\n color: GrayText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"EButton.js","names":["_sfc_main","EButton_vue_vue_type_script_setup_true_lang_default","EButton_default"],"sources":["../../../src/components/Button/EButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** `primary` is the one main action on a screen; `secondary` confirms; `outline` is for the other actions beside it; `danger` cancels or removes; `quiet` is an underlined text action. */\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"danger\" | \"quiet\";\n /** An icon before the label: a name such as `download`, or a component. */\n icon?: IconProp;\n /** Full width. */\n block?: boolean;\n /** Dashed and unfilled; not focusable, ignores clicks. With `href` the link gets `aria-disabled=\"true\"` and `tabindex=\"-1\"` and does not navigate. */\n disabled?: boolean;\n /** Set `submit` on the one that submits a form. */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Renders a link that looks like the button, for a destination rather than an action (a call to action that goes to a page). Space does not follow it. */\n href?: string;\n /** With `href`: opens in a new tab. */\n external?: boolean;\n /** Swaps the icon for a spinner, flattens the face, dashes its edge and animates stripes across it, and ignores clicks while an action runs. The button keeps its width and stays focusable, and is announced as busy. */\n loading?: boolean;\n }>(),\n { variant: \"primary\", type: \"button\" },\n);\n\ndefineSlots<{\n /** The label: a verb that says what happens, like \"Pay $162.40\". */\n default(): unknown;\n}>();\n\nfunction blockWhenDisabled(event: Event) {\n if (!props.disabled && !props.loading) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n</script>\n\n<template>\n <a\n v-if=\"href\"\n :href=\"href\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noreferrer' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click.capture=\"blockWhenDisabled\"\n @auxclick.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </a>\n <button\n v-else\n :type=\"type\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :disabled=\"disabled\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </button>\n</template>\n\n<style>\n@layer e.primitives {\n .e-btn {\n --e-fill: var(--e-primary);\n --e-on-fill: var(--e-on-primary);\n --e-slab: color-mix(in srgb, var(--e-fill), var(--e-shade-slab));\n --e-hover: color-mix(in srgb, var(--e-fill), var(--e-shade-hover));\n --e-press: color-mix(in srgb, var(--e-fill), var(--e-shade-press));\n\n /* One border, one control height tall. The slab is the bottom edge made thicker by the lift; the radius tapers it up the corners. Pressing sinks the face over it. */\n --e-lift: var(--e-depth);\n --e-ring: var(--e-slab);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--e-space-2);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: var(--e-radius-md);\n background-color: var(--e-fill);\n\n /* A solid face runs under its border so no page colour shows between them. */\n background-clip: border-box;\n color: var(--e-on-fill);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n letter-spacing: 0.01em;\n white-space: nowrap;\n text-decoration: none;\n cursor: pointer;\n transition:\n border-color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-btn:hover {\n --e-slab: color-mix(in srgb, var(--e-hover), var(--e-shade-slab));\n\n background-color: var(--e-hover);\n }\n\n .e-btn:active {\n --e-lift: 0px;\n\n background-color: var(--e-press);\n }\n\n .e-btn--secondary {\n --e-fill: var(--e-secondary);\n --e-on-fill: var(--e-on-secondary);\n }\n\n .e-btn--danger {\n --e-fill: var(--e-danger);\n --e-on-fill: var(--e-on-danger);\n }\n\n .e-btn--outline {\n --e-fill: var(--e-surface);\n --e-on-fill: var(--e-ink);\n --e-slab: var(--e-border-strong);\n\n background-clip: padding-box;\n }\n\n .e-btn--outline:hover {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-hover));\n }\n\n .e-btn--outline:active {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-press));\n }\n\n .e-btn--quiet {\n --e-ring: transparent;\n --e-lift: 0px;\n\n background: transparent;\n color: var(--e-ink);\n padding-inline: calc(var(--e-space-3) - var(--e-stroke-edge));\n text-decoration: underline;\n text-underline-offset: 5px;\n text-decoration-thickness: var(--e-stroke-edge);\n text-decoration-color: var(--e-border-strong);\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):hover {\n --e-ring: var(--e-wash-ring);\n\n background: var(--e-wash-hover);\n text-decoration-color: currentcolor;\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):active {\n --e-ring: var(--e-ink);\n\n background: var(--e-wash-press);\n transform: none;\n }\n\n .e-btn .e-icon,\n .e-btn-spinner {\n margin-inline-start: calc(-0.5 * var(--e-space-1));\n }\n\n .e-btn-spinner {\n flex: none;\n width: 1.125em;\n height: 1.125em;\n fill: none;\n stroke: currentcolor;\n stroke-width: 3;\n stroke-linecap: round;\n stroke-dasharray: 36 56;\n animation: e-btn-spin 0.9s linear infinite;\n }\n\n /* Busy reads as unavailable and in progress: a soft tint of the button's colour with a dashed edge like a disabled button, and stripes that move. The face grows over its slab, so the button stays one control height tall. The edge is a pseudo-element, so a page's focus reset cannot remove it. */\n .e-btn--loading {\n --e-lift: 0px;\n --e-tint: var(--e-fill);\n --e-busy: color-mix(in srgb, var(--e-tint) 80%, var(--e-ink));\n }\n\n .e-btn--outline.e-btn--loading {\n --e-tint: var(--e-border-strong);\n }\n\n .e-btn--loading,\n .e-btn--loading:hover,\n .e-btn--loading:active {\n background-color: color-mix(in srgb, var(--e-tint) 14%, var(--e-surface));\n background-image: repeating-linear-gradient(135deg, transparent 0 8px, color-mix(in srgb, var(--e-tint) 20%, transparent) 8px 16px);\n background-size: 22.63px 22.63px;\n background-clip: padding-box;\n border-color: transparent;\n color: var(--e-busy);\n transform: none;\n cursor: not-allowed;\n animation: e-btn-stripes 0.8s linear infinite;\n }\n\n .e-btn--loading::before {\n content: \"\";\n position: absolute;\n inset: calc(-1 * var(--e-stroke-edge));\n border: var(--e-stroke-edge) dashed var(--e-busy);\n border-radius: inherit;\n pointer-events: none;\n }\n\n @keyframes e-btn-stripes {\n to {\n background-position-x: 22.63px;\n }\n }\n\n @keyframes e-btn-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .e-btn--block {\n width: 100%;\n }\n\n /* A toggle: any button with aria-pressed=\"true\" reads as selected. */\n .e-btn[aria-pressed=\"true\"],\n .e-btn[aria-pressed=\"true\"]:hover,\n .e-btn[aria-pressed=\"true\"]:active {\n --e-slab: var(--e-primary);\n --e-ring: var(--e-primary);\n\n background-color: var(--e-surface-hover);\n color: var(--e-primary);\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n --e-lift: 0px;\n\n cursor: not-allowed;\n background: transparent;\n color: var(--e-muted);\n outline: var(--e-stroke-edge) dashed var(--e-border-strong);\n outline-offset: calc(-1 * var(--e-stroke-edge));\n border-color: transparent;\n transform: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-btn {\n transition: none;\n }\n\n .e-btn-spinner {\n animation-duration: 3s;\n }\n\n .e-btn--loading {\n animation: none;\n }\n }\n\n @media print {\n .e-btn {\n display: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-btn {\n border: var(--e-stroke-focus) solid ButtonText;\n }\n\n .e-btn[aria-pressed=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n outline-color: GrayText;\n color: GrayText;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"EButton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_createBlock","EIcon","_createCommentVNode","_renderSlot","EIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","EButton_vue_vue_type_script_setup_true_lang_default","props","__props","blockWhenDisabled","event","openBlock","createElementBlock","normalizeClass","_cache","createElementVNode","createBlock","createCommentVNode","renderSlot","_ctx"],"sources":["../../../src/components/Button/EButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** `primary` is the one main action on a screen; `secondary` confirms; `outline` is for the other actions beside it; `danger` cancels or removes; `quiet` is an underlined text action. */\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"danger\" | \"quiet\";\n /** An icon before the label: a name such as `download`, or a component. */\n icon?: IconProp;\n /** Full width. */\n block?: boolean;\n /** Dashed and unfilled; not focusable, ignores clicks. With `href` the link gets `aria-disabled=\"true\"` and `tabindex=\"-1\"` and does not navigate. */\n disabled?: boolean;\n /** Set `submit` on the one that submits a form. */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Renders a link that looks like the button, for a destination rather than an action (a call to action that goes to a page). Space does not follow it. */\n href?: string;\n /** With `href`: opens in a new tab. */\n external?: boolean;\n /** Swaps the icon for a spinner, flattens the face, dashes its edge and animates stripes across it, and ignores clicks while an action runs. The button keeps its width and stays focusable, and is announced as busy. */\n loading?: boolean;\n }>(),\n { variant: \"primary\", type: \"button\" },\n);\n\ndefineSlots<{\n /** The label: a verb that says what happens, like \"Pay $162.40\". */\n default(): unknown;\n}>();\n\nfunction blockWhenDisabled(event: Event) {\n if (!props.disabled && !props.loading) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n</script>\n\n<template>\n <a\n v-if=\"href\"\n :href=\"href\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noreferrer' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click.capture=\"blockWhenDisabled\"\n @auxclick.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </a>\n <button\n v-else\n :type=\"type\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :disabled=\"disabled\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </button>\n</template>\n\n<style>\n@layer e.primitives {\n .e-btn {\n --e-fill: var(--e-primary);\n --e-on-fill: var(--e-on-primary);\n --e-slab: color-mix(in srgb, var(--e-fill), var(--e-shade-slab));\n --e-hover: color-mix(in srgb, var(--e-fill), var(--e-shade-hover));\n --e-press: color-mix(in srgb, var(--e-fill), var(--e-shade-press));\n\n /* One rounded box, one control height tall. The slab is an inset shadow shifted up by the lift: the part of the box left uncovered along its bottom, which follows the corners up the sides, in the colour of the box's own edge. It is cut by the box's one outline, so nothing sits behind the curve. Pressing sinks the face over it. */\n --e-lift: var(--e-depth);\n --e-band: calc(var(--e-lift) + var(--e-stroke-edge));\n --e-ring: var(--e-slab);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--e-space-2);\n height: var(--e-control-height);\n padding: 0 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: var(--e-radius-md);\n background-color: var(--e-fill);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-ring),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\n color: var(--e-on-fill);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n letter-spacing: 0.01em;\n white-space: nowrap;\n text-decoration: none;\n cursor: pointer;\n transition:\n box-shadow var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-btn:hover {\n --e-slab: color-mix(in srgb, var(--e-hover), var(--e-shade-slab));\n\n background-color: var(--e-hover);\n }\n\n .e-btn:active {\n --e-lift: 0px;\n\n background-color: var(--e-press);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n }\n\n .e-btn--secondary {\n --e-fill: var(--e-secondary);\n --e-on-fill: var(--e-on-secondary);\n }\n\n .e-btn--danger {\n --e-fill: var(--e-danger);\n --e-on-fill: var(--e-on-danger);\n }\n\n .e-btn--outline {\n --e-fill: var(--e-surface);\n --e-on-fill: var(--e-ink);\n --e-slab: var(--e-border-strong);\n }\n\n .e-btn--outline:hover {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-hover));\n }\n\n .e-btn--outline:active {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-press));\n }\n\n .e-btn--quiet {\n --e-ring: transparent;\n --e-lift: 0px;\n\n background: transparent;\n color: var(--e-ink);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ring);\n padding-inline: var(--e-space-3);\n text-decoration: underline;\n text-underline-offset: 5px;\n text-decoration-thickness: var(--e-stroke-edge);\n text-decoration-color: var(--e-border-strong);\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):hover {\n --e-ring: var(--e-wash-ring);\n\n background: var(--e-wash-hover);\n text-decoration-color: currentcolor;\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):active {\n --e-ring: var(--e-ink);\n\n background: var(--e-wash-press);\n transform: none;\n }\n\n .e-btn .e-icon,\n .e-btn-spinner {\n margin-inline-start: calc(-0.5 * var(--e-space-1));\n }\n\n .e-btn-spinner {\n flex: none;\n width: 1.125em;\n height: 1.125em;\n fill: none;\n stroke: currentcolor;\n stroke-width: 3;\n stroke-linecap: round;\n stroke-dasharray: 36 56;\n animation: e-btn-spin 0.9s linear infinite;\n }\n\n /* Busy reads as unavailable and in progress: a soft tint of the button's colour with a dashed edge like a disabled button, and stripes that move. The face grows over its slab, so the button stays one control height tall. The edge is a pseudo-element, so a page's focus reset cannot remove it. */\n .e-btn--loading {\n --e-lift: 0px;\n --e-tint: var(--e-fill);\n --e-busy: color-mix(in srgb, var(--e-tint) 80%, var(--e-ink));\n }\n\n .e-btn--outline.e-btn--loading {\n --e-tint: var(--e-border-strong);\n }\n\n .e-btn--loading,\n .e-btn--loading:hover,\n .e-btn--loading:active {\n background-color: color-mix(in srgb, var(--e-tint) 14%, var(--e-surface));\n background-image: repeating-linear-gradient(135deg, transparent 0 8px, color-mix(in srgb, var(--e-tint) 20%, transparent) 8px 16px);\n background-size: 22.63px 22.63px;\n box-shadow: none;\n color: var(--e-busy);\n transform: none;\n cursor: not-allowed;\n animation: e-btn-stripes 0.8s linear infinite;\n }\n\n .e-btn--loading::before {\n content: \"\";\n position: absolute;\n inset: 0;\n border: var(--e-stroke-edge) dashed var(--e-busy);\n border-radius: inherit;\n pointer-events: none;\n }\n\n @keyframes e-btn-stripes {\n to {\n background-position-x: 22.63px;\n }\n }\n\n @keyframes e-btn-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .e-btn--block {\n width: 100%;\n }\n\n /* A toggle: any button with aria-pressed=\"true\" reads as selected. */\n .e-btn[aria-pressed=\"true\"],\n .e-btn[aria-pressed=\"true\"]:hover,\n .e-btn[aria-pressed=\"true\"]:active {\n --e-slab: var(--e-primary);\n --e-ring: var(--e-primary);\n\n background-color: var(--e-surface-hover);\n color: var(--e-primary);\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n --e-lift: 0px;\n\n cursor: not-allowed;\n background: transparent;\n color: var(--e-muted);\n outline: var(--e-stroke-edge) dashed var(--e-border-strong);\n outline-offset: calc(-1 * var(--e-stroke-edge));\n box-shadow: none;\n transform: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-btn {\n transition: none;\n }\n\n .e-btn-spinner {\n animation-duration: 3s;\n }\n\n .e-btn--loading {\n animation: none;\n }\n }\n\n @media print {\n .e-btn {\n display: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-btn {\n border: var(--e-stroke-focus) solid ButtonText;\n }\n\n .e-btn[aria-pressed=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n outline-color: GrayText;\n color: GrayText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKA,IAAMc,IAAQC;EA2Bd,SAASC,EAAkB,GAAc;GACvC,CAAKF,EAAM,YAAaA,EAAM,aAC9BG,EAAM,eAAe,GACrBA,EAAM,yBAAyB;EACjC;E,iBAKUF,EAAA,QADRf,EAAA,GAAAC,EAgBI,KAAA;;GAdD,MAAMc,EAAA;GACP,OAAKb,EAAA,CAAC,SAAO;IACJa,EAAA,YAAO,aAAA,UAA4BA,EAAA;IAAWA,EAAA,SAAK;IAAoBA,EAAA,WAAO;GAAA,CAAA,CAAA;GACtF,QAAQA,EAAA,WAAQ,WAAc,KAAA;GAC9B,KAAKA,EAAA,WAAQ,eAAkB,KAAA;GAC/B,iBAAeA,EAAA,WAAQ,SAAY,KAAA;GACnC,aAAWA,EAAA,UAAO,SAAY,KAAA;GAC9B,UAAUA,EAAA,WAAQ,KAAQ,KAAA;GACX,gBAAAC;GACG,mBAAAA;E,IAERD,EAAA,WAAXf,EAAA,GAAAC,EAAuH,OAAvHS,GAAuH,CAAA,GAAA,AAAAW,EAAA,OAAA,CAAtClB,EAAgC,UAAA;GAAxB,IAAG;GAAK,IAAG;GAAK,GAAE;E,mBACzFY,EAAA,QAAlBf,EAAA,GAAAI,EAAuCC,GAAA;;GAAd,MAAMU,EAAA;E,oCAC/BR,EAAQmB,EAAA,QAAA,SAAA,C,cAEV1B,EAAA,GAAAC,EAYS,UAAA;;GAVN,MAAMc,EAAA;GACP,OAAKb,EAAA,CAAC,SAAO;IACJa,EAAA,YAAO,aAAA,UAA4BA,EAAA;IAAWA,EAAA,SAAK;IAAoBA,EAAA,WAAO;GAAA,CAAA,CAAA;GACtF,UAAUA,EAAA;GACV,aAAWA,EAAA,UAAO,SAAY,KAAA;GACf,gBAAAC;E,IAELD,EAAA,WAAXf,EAAA,GAAAC,EAAuH,OAAvHW,GAAuH,CAAA,GAAA,AAAAS,EAAA,OAAA,CAAtClB,EAAgC,UAAA;GAAxB,IAAG;GAAK,IAAG;GAAK,GAAE;E,mBACzFY,EAAA,QAAlBf,EAAA,GAAAI,EAAuCC,GAAA;;GAAd,MAAMU,EAAA;E,oCAC/BR,EAAQmB,EAAA,QAAA,SAAA,C"}
1
+ {"version":3,"file":"EButton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_createElementVNode","_createBlock","EIcon","_createCommentVNode","_renderSlot","EIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","EButton_vue_vue_type_script_setup_true_lang_default","props","__props","blockWhenDisabled","event","openBlock","createElementBlock","normalizeClass","_cache","createElementVNode","createBlock","createCommentVNode","renderSlot","_ctx"],"sources":["../../../src/components/Button/EButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport type { IconProp } from \"../../icons/types.js\";\nimport \"../../styles/base.css\";\n\nconst props = withDefaults(\n defineProps<{\n /** `primary` is the one main action on a screen; `secondary` confirms; `outline` is for the other actions beside it; `danger` cancels or removes; `quiet` is an underlined text action. */\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"danger\" | \"quiet\";\n /** An icon before the label: a name such as `download`, or a component. */\n icon?: IconProp;\n /** Full width. */\n block?: boolean;\n /** Dashed and unfilled; not focusable, ignores clicks. With `href` the link gets `aria-disabled=\"true\"` and `tabindex=\"-1\"` and does not navigate. */\n disabled?: boolean;\n /** Set `submit` on the one that submits a form. */\n type?: \"button\" | \"submit\" | \"reset\";\n /** Renders a link that looks like the button, for a destination rather than an action (a call to action that goes to a page). Space does not follow it. */\n href?: string;\n /** With `href`: opens in a new tab. */\n external?: boolean;\n /** Swaps the icon for a spinner, flattens the face, dashes its edge and animates stripes across it, and ignores clicks while an action runs. The button keeps its width and stays focusable, and is announced as busy. */\n loading?: boolean;\n }>(),\n { variant: \"primary\", type: \"button\" },\n);\n\ndefineSlots<{\n /** The label: a verb that says what happens, like \"Pay $162.40\". */\n default(): unknown;\n}>();\n\nfunction blockWhenDisabled(event: Event) {\n if (!props.disabled && !props.loading) return;\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n</script>\n\n<template>\n <a\n v-if=\"href\"\n :href=\"href\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noreferrer' : undefined\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n @click.capture=\"blockWhenDisabled\"\n @auxclick.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </a>\n <button\n v-else\n :type=\"type\"\n class=\"e-btn\"\n :class=\"[variant !== 'primary' && `e-btn--${variant}`, block && 'e-btn--block', loading && 'e-btn--loading']\"\n :disabled=\"disabled\"\n :aria-busy=\"loading ? 'true' : undefined\"\n @click.capture=\"blockWhenDisabled\"\n >\n <svg v-if=\"loading\" class=\"e-btn-spinner\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\" /></svg>\n <EIcon v-else-if=\"icon\" :name=\"icon\" />\n <slot />\n </button>\n</template>\n\n<style>\n@layer e.primitives {\n .e-btn {\n --e-fill: var(--e-primary);\n --e-on-fill: var(--e-on-primary);\n --e-slab: color-mix(in srgb, var(--e-fill), var(--e-shade-slab));\n --e-hover: color-mix(in srgb, var(--e-fill), var(--e-shade-hover));\n --e-press: color-mix(in srgb, var(--e-fill), var(--e-shade-press));\n\n /* One border, one control height tall. The slab is the bottom edge made thicker by the lift; the radius tapers it up the corners. Pressing sinks the face over it. */\n --e-lift: var(--e-depth);\n --e-ring: var(--e-slab);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--e-space-2);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: var(--e-radius-md);\n background-color: var(--e-fill);\n\n /* A solid face runs under its border so no page colour shows between them. */\n background-clip: border-box;\n color: var(--e-on-fill);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n letter-spacing: 0.01em;\n white-space: nowrap;\n text-decoration: none;\n cursor: pointer;\n transition:\n border-color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-btn:hover {\n --e-slab: color-mix(in srgb, var(--e-hover), var(--e-shade-slab));\n\n background-color: var(--e-hover);\n }\n\n .e-btn:active {\n --e-lift: 0px;\n\n background-color: var(--e-press);\n }\n\n .e-btn--secondary {\n --e-fill: var(--e-secondary);\n --e-on-fill: var(--e-on-secondary);\n }\n\n .e-btn--danger {\n --e-fill: var(--e-danger);\n --e-on-fill: var(--e-on-danger);\n }\n\n .e-btn--outline {\n --e-fill: var(--e-surface);\n --e-on-fill: var(--e-ink);\n --e-slab: var(--e-border-strong);\n\n background-clip: padding-box;\n }\n\n .e-btn--outline:hover {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-hover));\n }\n\n .e-btn--outline:active {\n --e-ring: var(--e-ink);\n --e-slab: var(--e-ink);\n\n background-color: color-mix(in srgb, var(--e-surface), var(--e-shade-press));\n }\n\n .e-btn--quiet {\n --e-ring: transparent;\n --e-lift: 0px;\n\n background: transparent;\n color: var(--e-ink);\n padding-inline: calc(var(--e-space-3) - var(--e-stroke-edge));\n text-decoration: underline;\n text-underline-offset: 5px;\n text-decoration-thickness: var(--e-stroke-edge);\n text-decoration-color: var(--e-border-strong);\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):hover {\n --e-ring: var(--e-wash-ring);\n\n background: var(--e-wash-hover);\n text-decoration-color: currentcolor;\n }\n\n .e-btn--quiet:not([disabled], [aria-disabled=\"true\"]):active {\n --e-ring: var(--e-ink);\n\n background: var(--e-wash-press);\n transform: none;\n }\n\n .e-btn .e-icon,\n .e-btn-spinner {\n margin-inline-start: calc(-0.5 * var(--e-space-1));\n }\n\n .e-btn-spinner {\n flex: none;\n width: 1.125em;\n height: 1.125em;\n fill: none;\n stroke: currentcolor;\n stroke-width: 3;\n stroke-linecap: round;\n stroke-dasharray: 36 56;\n animation: e-btn-spin 0.9s linear infinite;\n }\n\n /* Busy reads as unavailable and in progress: a soft tint of the button's colour with a dashed edge like a disabled button, and stripes that move. The face grows over its slab, so the button stays one control height tall. The edge is a pseudo-element, so a page's focus reset cannot remove it. */\n .e-btn--loading {\n --e-lift: 0px;\n --e-tint: var(--e-fill);\n --e-busy: color-mix(in srgb, var(--e-tint) 80%, var(--e-ink));\n }\n\n .e-btn--outline.e-btn--loading {\n --e-tint: var(--e-border-strong);\n }\n\n .e-btn--loading,\n .e-btn--loading:hover,\n .e-btn--loading:active {\n background-color: color-mix(in srgb, var(--e-tint) 14%, var(--e-surface));\n background-image: repeating-linear-gradient(135deg, transparent 0 8px, color-mix(in srgb, var(--e-tint) 20%, transparent) 8px 16px);\n background-size: 22.63px 22.63px;\n background-clip: padding-box;\n border-color: transparent;\n color: var(--e-busy);\n transform: none;\n cursor: not-allowed;\n animation: e-btn-stripes 0.8s linear infinite;\n }\n\n .e-btn--loading::before {\n content: \"\";\n position: absolute;\n inset: calc(-1 * var(--e-stroke-edge));\n border: var(--e-stroke-edge) dashed var(--e-busy);\n border-radius: inherit;\n pointer-events: none;\n }\n\n @keyframes e-btn-stripes {\n to {\n background-position-x: 22.63px;\n }\n }\n\n @keyframes e-btn-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .e-btn--block {\n width: 100%;\n }\n\n /* A toggle: any button with aria-pressed=\"true\" reads as selected. */\n .e-btn[aria-pressed=\"true\"],\n .e-btn[aria-pressed=\"true\"]:hover,\n .e-btn[aria-pressed=\"true\"]:active {\n --e-slab: var(--e-primary);\n --e-ring: var(--e-primary);\n\n background-color: var(--e-surface-hover);\n color: var(--e-primary);\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n --e-lift: 0px;\n\n cursor: not-allowed;\n background: transparent;\n color: var(--e-muted);\n outline: var(--e-stroke-edge) dashed var(--e-border-strong);\n outline-offset: calc(-1 * var(--e-stroke-edge));\n border-color: transparent;\n transform: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-btn {\n transition: none;\n }\n\n .e-btn-spinner {\n animation-duration: 3s;\n }\n\n .e-btn--loading {\n animation: none;\n }\n }\n\n @media print {\n .e-btn {\n display: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-btn {\n border: var(--e-stroke-focus) solid ButtonText;\n }\n\n .e-btn[aria-pressed=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n\n .e-btn[disabled],\n .e-btn[aria-disabled=\"true\"] {\n outline-color: GrayText;\n color: GrayText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKA,IAAMc,IAAQC;EA2Bd,SAASC,EAAkB,GAAc;GACvC,CAAKF,EAAM,YAAaA,EAAM,aAC9BG,EAAM,eAAe,GACrBA,EAAM,yBAAyB;EACjC;E,iBAKUF,EAAA,QADRf,EAAA,GAAAC,EAgBI,KAAA;;GAdD,MAAMc,EAAA;GACP,OAAKb,EAAA,CAAC,SAAO;IACJa,EAAA,YAAO,aAAA,UAA4BA,EAAA;IAAWA,EAAA,SAAK;IAAoBA,EAAA,WAAO;GAAA,CAAA,CAAA;GACtF,QAAQA,EAAA,WAAQ,WAAc,KAAA;GAC9B,KAAKA,EAAA,WAAQ,eAAkB,KAAA;GAC/B,iBAAeA,EAAA,WAAQ,SAAY,KAAA;GACnC,aAAWA,EAAA,UAAO,SAAY,KAAA;GAC9B,UAAUA,EAAA,WAAQ,KAAQ,KAAA;GACX,gBAAAC;GACG,mBAAAA;E,IAERD,EAAA,WAAXf,EAAA,GAAAC,EAAuH,OAAvHS,GAAuH,CAAA,GAAA,AAAAW,EAAA,OAAA,CAAtClB,EAAgC,UAAA;GAAxB,IAAG;GAAK,IAAG;GAAK,GAAE;E,mBACzFY,EAAA,QAAlBf,EAAA,GAAAI,EAAuCC,GAAA;;GAAd,MAAMU,EAAA;E,oCAC/BR,EAAQmB,EAAA,QAAA,SAAA,C,cAEV1B,EAAA,GAAAC,EAYS,UAAA;;GAVN,MAAMc,EAAA;GACP,OAAKb,EAAA,CAAC,SAAO;IACJa,EAAA,YAAO,aAAA,UAA4BA,EAAA;IAAWA,EAAA,SAAK;IAAoBA,EAAA,WAAO;GAAA,CAAA,CAAA;GACtF,UAAUA,EAAA;GACV,aAAWA,EAAA,UAAO,SAAY,KAAA;GACf,gBAAAC;E,IAELD,EAAA,WAAXf,EAAA,GAAAC,EAAuH,OAAvHW,GAAuH,CAAA,GAAA,AAAAS,EAAA,OAAA,CAAtClB,EAAgC,UAAA;GAAxB,IAAG;GAAK,IAAG;GAAK,GAAE;E,mBACzFY,EAAA,QAAlBf,EAAA,GAAAI,EAAuCC,GAAA;;GAAd,MAAMU,EAAA;E,oCAC/BR,EAAQmB,EAAA,QAAA,SAAA,C"}
@@ -1 +1 @@
1
- {"version":3,"file":"EComboboxBase.js","names":["_sfc_main","EComboboxBase_vue_vue_type_script_setup_true_lang_default","EComboboxBase_default"],"sources":["../../../src/components/Combobox/EComboboxBase.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, nextTick, onMounted, ref, watch, type FunctionalComponent } from \"vue\";\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxTrigger,\n ComboboxViewport,\n} from \"reka-ui\";\nimport EField from \"../Field/EField.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport ESpinner from \"../Spinner/ESpinner.vue\";\nimport EComboboxOption from \"./EComboboxOption.vue\";\nimport { normalizeOptions, sectionOptions } from \"../Select/options.js\";\nimport type { EComboboxProps } from \"./types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\nimport \"./combo.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = withDefaults(defineProps<EComboboxProps>(), {\n clearable: true,\n});\n\nconst emit = defineEmits<{\n /** The text in the input changed, by typing or by choosing. Use it to fetch options from a server. */\n inputChange: [text: string];\n}>();\n\nconst model = defineModel<string | string[]>();\n\nconst t = useMessages();\nconst portal = usePortalTarget();\nconst attrs = useFieldAttrs();\nconst groupId = useUid();\nconst bareId = useUid(() => props.id);\n\nconst Bare: FunctionalComponent = (_, { slots }) =>\n h(\"div\", attrs.wrapper(), slots.default?.({ id: bareId.value, ariaInvalid: undefined, ariaDescribedby: undefined }));\nconst frame = computed(() =>\n props.bare\n ? {}\n : {\n id: props.id,\n label: props.label,\n hideLabel: props.hideLabel,\n hint: props.hint,\n error: props.error,\n required: props.required,\n optional: props.optional,\n },\n);\nconst listName = computed(() => (props.bare ? (props.ariaLabel ?? props.label) : props.label));\n\nconst multiple = computed(() => props.multiple);\n// Free text is for one value; with `multiple` it is ignored.\nconst free = computed(() => props.freeform && !props.multiple);\nconst all = computed(() => normalizeOptions(props.options));\nconst values = computed<string[]>(() => (multiple.value && Array.isArray(model.value) ? model.value : []));\nconst single = computed(() => (typeof model.value === \"string\" ? model.value : \"\"));\nconst rootValue = computed(() => (multiple.value ? values.value : single.value));\n\nfunction labelOf(v: string): string {\n return all.value.find((o) => o.value === v)?.label ?? (free.value ? v : \"\");\n}\nconst resting = () => (multiple.value ? \"\" : labelOf(single.value));\n\nconst text = ref(resting());\nconst typing = ref(false);\nconst wantOpen = defineModel<boolean>(\"open\", { default: false });\nconst anchor = ref<{ $el: HTMLElement } | null>(null);\nconst query = computed(() => (typing.value ? text.value.trim().toLowerCase() : \"\"));\n\nconst shown = computed(() => {\n const q = query.value;\n if (props.filter) return all.value.filter((o) => props.filter!(o, q));\n return all.value.filter(\n (o) => !q || o.label.toLowerCase().includes(q) || (o.description ?? \"\").toLowerCase().includes(q),\n );\n});\nconst sections = computed(() => sectionOptions(shown.value));\nconst hasList = computed(() => shown.value.length > 0 || !!props.loading || !free.value);\nconst open = computed(() => wantOpen.value && hasList.value && !props.disabled);\nconst announce = computed(() =>\n open.value && !shown.value.length ? (props.loading ? t(\"searching\") : props.emptyText || t(\"noMatches\")) : \"\",\n);\nconst hasValue = computed(() => (multiple.value ? values.value.length > 0 : !!text.value));\n\nwatch(rootValue, () => {\n const rest = resting();\n if (rest !== text.value) {\n text.value = rest;\n typing.value = false;\n }\n});\nwatch(all, () => {\n if (!typing.value && !open.value) text.value = resting();\n});\n\nconst listId = ref<string | undefined>();\nconst content = ref<{ $el: HTMLElement } | null>(null);\nonMounted(() => {\n if (!open.value) return;\n let tries = 0;\n const read = () => {\n listId.value = content.value?.$el?.id || undefined;\n if (!listId.value && tries++ < 10) requestAnimationFrame(read);\n };\n void nextTick(read);\n});\n\nconst inputEl = () => anchor.value?.$el?.querySelector(\"input\") ?? null;\nconst focusInput = () => inputEl()?.focus();\n\nfunction isSelected(value: string): boolean {\n return multiple.value ? values.value.includes(value) : free.value ? single.value === value : single.value === value;\n}\nconst itemValue = (o: { value: string; label: string }) => (free.value ? o.label : o.value);\n\nfunction onPick(v: unknown) {\n typing.value = false;\n if (multiple.value) {\n model.value = Array.isArray(v) ? (v as string[]) : [];\n text.value = \"\";\n emit(\"inputChange\", \"\");\n return;\n }\n const next = typeof v === \"string\" ? v : \"\";\n model.value = next;\n text.value = free.value ? next : labelOf(next);\n emit(\"inputChange\", text.value);\n}\n\nfunction onInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n text.value = v;\n typing.value = true;\n wantOpen.value = true;\n emit(\"inputChange\", v);\n if (free.value) model.value = v;\n}\n\nfunction remove(v: string) {\n model.value = values.value.filter((x) => x !== v);\n}\n\nfunction clear() {\n model.value = multiple.value ? [] : \"\";\n text.value = \"\";\n typing.value = false;\n emit(\"inputChange\", \"\");\n focusInput();\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\" && !open.value && text.value) {\n e.preventDefault();\n clear();\n } else if (e.key === \"Backspace\" && multiple.value && !text.value && values.value.length) {\n remove(values.value[values.value.length - 1]!);\n }\n}\n\nfunction keepCaretKeys(e: KeyboardEvent) {\n if (e.key === \"Home\" || e.key === \"End\") e.stopImmediatePropagation();\n}\n\nfunction onBlur(e: FocusEvent) {\n const next = e.relatedTarget as Element | null;\n if (next && (anchor.value?.$el?.contains(next) || next.closest?.(\".e-popover\"))) return;\n wantOpen.value = false;\n typing.value = false;\n if (!free.value) text.value = resting();\n}\n\nfunction onWrapDown(e: MouseEvent) {\n if (e.target === e.currentTarget && !props.disabled) {\n e.preventDefault();\n focusInput();\n }\n}\n\ntype FieldSlot = { id: string; ariaInvalid: \"true\" | undefined; ariaDescribedby: string | undefined };\nfunction inputBind(field: FieldSlot) {\n return {\n id: field.id,\n required: props.required && !(multiple.value && values.value.length) ? true : undefined,\n placeholder: multiple.value && values.value.length ? \"\" : props.placeholder,\n \"aria-invalid\": field.ariaInvalid,\n \"aria-label\": props.bare ? listName.value : undefined,\n autocomplete: \"off\",\n ...(listId.value ? { \"aria-controls\": listId.value } : {}),\n ...(shown.value.length ? {} : { \"aria-activedescendant\": undefined }),\n ...attrs.input(field.ariaDescribedby),\n };\n}\n\ndefineExpose({\n input: computed(() => inputEl()),\n focus: focusInput,\n});\n</script>\n\n<template>\n <component :is=\"bare ? Bare : EField\" v-bind=\"{ ...attrs.wrapper(), ...frame }\">\n <template #default=\"field\">\n <ComboboxRoot\n class=\"e-combo-root\"\n :model-value=\"rootValue\"\n :multiple=\"multiple\"\n :open=\"open\"\n :disabled=\"disabled\"\n ignore-filter\n @update:model-value=\"onPick\"\n @update:open=\"wantOpen = $event\"\n >\n <ComboboxAnchor\n ref=\"anchor\"\n class=\"e-input-wrap e-combo\"\n :class=\"{ 'e-combo--multi': multiple }\"\n :data-invalid=\"error && !bare ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n @mousedown=\"onWrapDown\"\n @focusout=\"onBlur\"\n >\n <div class=\"e-combo-main\">\n <template v-if=\"multiple\">\n <span v-for=\"v in values\" :key=\"v\" class=\"e-tag\">\n {{ labelOf(v) }}\n <button\n v-if=\"!disabled\"\n type=\"button\"\n class=\"e-tag-x\"\n :aria-label=\"t('removeItem', { label: labelOf(v) })\"\n @click=\"remove(v)\"\n >\n <EIcon name=\"x\" small />\n </button>\n </span>\n </template>\n <ComboboxInput\n class=\"e-input e-combo-input\"\n :model-value=\"text\"\n :display-value=\"(v: unknown) => (typeof v === 'string' ? (free ? v : labelOf(v)) : '')\"\n :disabled=\"disabled\"\n v-bind=\"inputBind(field)\"\n @update:model-value=\"text = $event\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @keydown.capture=\"keepCaretKeys\"\n />\n </div>\n <template v-if=\"name\">\n <input v-for=\"(v, k) in multiple ? values : [single]\" :key=\"k\" type=\"hidden\" :name=\"name\" :value=\"v\" />\n </template>\n <div class=\"e-combo-tail\">\n <button\n v-if=\"hasValue && clearable && !disabled\"\n type=\"button\"\n class=\"e-combo-btn\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <ComboboxTrigger\n v-if=\"!free\"\n class=\"e-combo-btn\"\n :aria-label=\"t('showOptions')\"\n :disabled=\"disabled\"\n @mousedown.prevent\n >\n <EIcon name=\"chevron-down\" bold />\n </ComboboxTrigger>\n </div>\n </ComboboxAnchor>\n <span class=\"e-sr\" role=\"status\">{{ announce }}</span>\n <ComboboxPortal :to=\"portal\">\n <ComboboxContent\n ref=\"content\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"6\"\n :collision-padding=\"8\"\n class=\"e-popover e-listpanel e-root\"\n :aria-label=\"listName\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <ComboboxViewport>\n <template v-if=\"shown.length\">\n <template v-for=\"(section, i) in sections\" :key=\"i\">\n <div v-if=\"section.group\" class=\"e-opt-set\" role=\"group\" :aria-labelledby=\"`${groupId}-g${i}`\">\n <div :id=\"`${groupId}-g${i}`\" class=\"e-opt-group\">{{ section.group }}</div>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </div>\n <template v-else>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </template>\n </template>\n </template>\n <div v-else class=\"e-opt-status\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n <ESpinner v-if=\"loading\" :label=\"t('searching')\" />\n <template v-else>{{ emptyText || t(\"noMatches\") }}</template>\n </div>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </template>\n </component>\n</template>\n\n<style>\n@layer e.controls {\n .e-combo-main {\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n align-items: center;\n align-self: stretch;\n gap: var(--e-space-1);\n min-width: 0;\n }\n\n .e-combo-tail {\n display: flex;\n flex: none;\n align-items: center;\n align-self: center;\n }\n\n .e-combo--multi {\n padding: 3px var(--e-space-1) 3px var(--e-space-2);\n gap: var(--e-space-1);\n }\n\n .e-combo--multi .e-input {\n height: calc(var(--e-control-height) - 9px);\n align-self: center;\n padding-inline: var(--e-space-2);\n }\n\n .e-combo-main .e-tag:not(:has(.e-tag-x)) {\n padding-inline-end: var(--e-space-3);\n }\n\n .e-tag {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-space-8);\n padding: 0 var(--e-space-1) 0 var(--e-space-3);\n border-radius: var(--e-radius-pill);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n color: var(--e-ink);\n font: 500 var(--e-text-sm)/1 var(--e-font-sans);\n }\n\n .e-tag-x::after {\n content: \"\";\n position: absolute;\n inset: calc((var(--e-tap) - var(--e-space-6)) / -2);\n }\n\n .e-tag-x {\n position: relative;\n display: inline-grid;\n place-items: center;\n width: var(--e-space-6);\n height: var(--e-space-6);\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--e-primary);\n cursor: pointer;\n }\n\n .e-tag-x:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n }\n\n .e-tag-x:active {\n background: var(--e-wash-press);\n }\n\n .e-tag-x:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (forced-colors: active) {\n .e-tag {\n outline: var(--e-stroke-card) solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"EComboboxBase.js","names":["_sfc_main","EComboboxBase_vue_vue_type_script_setup_true_lang_default","EComboboxBase_default"],"sources":["../../../src/components/Combobox/EComboboxBase.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, nextTick, onMounted, ref, watch, type FunctionalComponent } from \"vue\";\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxTrigger,\n ComboboxViewport,\n} from \"reka-ui\";\nimport EField from \"../Field/EField.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport ESpinner from \"../Spinner/ESpinner.vue\";\nimport EComboboxOption from \"./EComboboxOption.vue\";\nimport { normalizeOptions, sectionOptions } from \"../Select/options.js\";\nimport type { EComboboxProps } from \"./types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\nimport \"./combo.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = withDefaults(defineProps<EComboboxProps>(), {\n clearable: true,\n});\n\nconst emit = defineEmits<{\n /** The text in the input changed, by typing or by choosing. Use it to fetch options from a server. */\n inputChange: [text: string];\n}>();\n\nconst model = defineModel<string | string[]>();\n\nconst t = useMessages();\nconst portal = usePortalTarget();\nconst attrs = useFieldAttrs();\nconst groupId = useUid();\nconst bareId = useUid(() => props.id);\n\nconst Bare: FunctionalComponent = (_, { slots }) =>\n h(\"div\", attrs.wrapper(), slots.default?.({ id: bareId.value, ariaInvalid: undefined, ariaDescribedby: undefined }));\nconst frame = computed(() =>\n props.bare\n ? {}\n : {\n id: props.id,\n label: props.label,\n hideLabel: props.hideLabel,\n hint: props.hint,\n error: props.error,\n required: props.required,\n optional: props.optional,\n },\n);\nconst listName = computed(() => (props.bare ? (props.ariaLabel ?? props.label) : props.label));\n\nconst multiple = computed(() => props.multiple);\n// Free text is for one value; with `multiple` it is ignored.\nconst free = computed(() => props.freeform && !props.multiple);\nconst all = computed(() => normalizeOptions(props.options));\nconst values = computed<string[]>(() => (multiple.value && Array.isArray(model.value) ? model.value : []));\nconst single = computed(() => (typeof model.value === \"string\" ? model.value : \"\"));\nconst rootValue = computed(() => (multiple.value ? values.value : single.value));\n\nfunction labelOf(v: string): string {\n return all.value.find((o) => o.value === v)?.label ?? (free.value ? v : \"\");\n}\nconst resting = () => (multiple.value ? \"\" : labelOf(single.value));\n\nconst text = ref(resting());\nconst typing = ref(false);\nconst wantOpen = defineModel<boolean>(\"open\", { default: false });\nconst anchor = ref<{ $el: HTMLElement } | null>(null);\nconst query = computed(() => (typing.value ? text.value.trim().toLowerCase() : \"\"));\n\nconst shown = computed(() => {\n const q = query.value;\n if (props.filter) return all.value.filter((o) => props.filter!(o, q));\n return all.value.filter(\n (o) => !q || o.label.toLowerCase().includes(q) || (o.description ?? \"\").toLowerCase().includes(q),\n );\n});\nconst sections = computed(() => sectionOptions(shown.value));\nconst hasList = computed(() => shown.value.length > 0 || !!props.loading || !free.value);\nconst open = computed(() => wantOpen.value && hasList.value && !props.disabled);\nconst announce = computed(() =>\n open.value && !shown.value.length ? (props.loading ? t(\"searching\") : props.emptyText || t(\"noMatches\")) : \"\",\n);\nconst hasValue = computed(() => (multiple.value ? values.value.length > 0 : !!text.value));\n\nwatch(rootValue, () => {\n const rest = resting();\n if (rest !== text.value) {\n text.value = rest;\n typing.value = false;\n }\n});\nwatch(all, () => {\n if (!typing.value && !open.value) text.value = resting();\n});\n\nconst listId = ref<string | undefined>();\nconst content = ref<{ $el: HTMLElement } | null>(null);\nonMounted(() => {\n if (!open.value) return;\n let tries = 0;\n const read = () => {\n listId.value = content.value?.$el?.id || undefined;\n if (!listId.value && tries++ < 10) requestAnimationFrame(read);\n };\n void nextTick(read);\n});\n\nconst inputEl = () => anchor.value?.$el?.querySelector(\"input\") ?? null;\nconst focusInput = () => inputEl()?.focus();\n\nfunction isSelected(value: string): boolean {\n return multiple.value ? values.value.includes(value) : free.value ? single.value === value : single.value === value;\n}\nconst itemValue = (o: { value: string; label: string }) => (free.value ? o.label : o.value);\n\nfunction onPick(v: unknown) {\n typing.value = false;\n if (multiple.value) {\n model.value = Array.isArray(v) ? (v as string[]) : [];\n text.value = \"\";\n emit(\"inputChange\", \"\");\n return;\n }\n const next = typeof v === \"string\" ? v : \"\";\n model.value = next;\n text.value = free.value ? next : labelOf(next);\n emit(\"inputChange\", text.value);\n}\n\nfunction onInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n text.value = v;\n typing.value = true;\n wantOpen.value = true;\n emit(\"inputChange\", v);\n if (free.value) model.value = v;\n}\n\nfunction remove(v: string) {\n model.value = values.value.filter((x) => x !== v);\n}\n\nfunction clear() {\n model.value = multiple.value ? [] : \"\";\n text.value = \"\";\n typing.value = false;\n emit(\"inputChange\", \"\");\n focusInput();\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\" && !open.value && text.value) {\n e.preventDefault();\n clear();\n } else if (e.key === \"Backspace\" && multiple.value && !text.value && values.value.length) {\n remove(values.value[values.value.length - 1]!);\n }\n}\n\nfunction keepCaretKeys(e: KeyboardEvent) {\n if (e.key === \"Home\" || e.key === \"End\") e.stopImmediatePropagation();\n}\n\nfunction onBlur(e: FocusEvent) {\n const next = e.relatedTarget as Element | null;\n if (next && (anchor.value?.$el?.contains(next) || next.closest?.(\".e-popover\"))) return;\n wantOpen.value = false;\n typing.value = false;\n if (!free.value) text.value = resting();\n}\n\nfunction onWrapDown(e: MouseEvent) {\n if (e.target === e.currentTarget && !props.disabled) {\n e.preventDefault();\n focusInput();\n }\n}\n\ntype FieldSlot = { id: string; ariaInvalid: \"true\" | undefined; ariaDescribedby: string | undefined };\nfunction inputBind(field: FieldSlot) {\n return {\n id: field.id,\n required: props.required && !(multiple.value && values.value.length) ? true : undefined,\n placeholder: multiple.value && values.value.length ? \"\" : props.placeholder,\n \"aria-invalid\": field.ariaInvalid,\n \"aria-label\": props.bare ? listName.value : undefined,\n autocomplete: \"off\",\n ...(listId.value ? { \"aria-controls\": listId.value } : {}),\n ...(shown.value.length ? {} : { \"aria-activedescendant\": undefined }),\n ...attrs.input(field.ariaDescribedby),\n };\n}\n\ndefineExpose({\n input: computed(() => inputEl()),\n focus: focusInput,\n});\n</script>\n\n<template>\n <component :is=\"bare ? Bare : EField\" v-bind=\"{ ...attrs.wrapper(), ...frame }\">\n <template #default=\"field\">\n <ComboboxRoot\n class=\"e-combo-root\"\n :model-value=\"rootValue\"\n :multiple=\"multiple\"\n :open=\"open\"\n :disabled=\"disabled\"\n ignore-filter\n @update:model-value=\"onPick\"\n @update:open=\"wantOpen = $event\"\n >\n <ComboboxAnchor\n ref=\"anchor\"\n class=\"e-input-wrap e-combo\"\n :class=\"{ 'e-combo--multi': multiple }\"\n :data-invalid=\"error && !bare ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n @mousedown=\"onWrapDown\"\n @focusout=\"onBlur\"\n >\n <div class=\"e-combo-main\">\n <template v-if=\"multiple\">\n <span v-for=\"v in values\" :key=\"v\" class=\"e-tag\">\n {{ labelOf(v) }}\n <button\n v-if=\"!disabled\"\n type=\"button\"\n class=\"e-tag-x\"\n :aria-label=\"t('removeItem', { label: labelOf(v) })\"\n @click=\"remove(v)\"\n >\n <EIcon name=\"x\" small />\n </button>\n </span>\n </template>\n <ComboboxInput\n class=\"e-input e-combo-input\"\n :model-value=\"text\"\n :display-value=\"(v: unknown) => (typeof v === 'string' ? (free ? v : labelOf(v)) : '')\"\n :disabled=\"disabled\"\n v-bind=\"inputBind(field)\"\n @update:model-value=\"text = $event\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @keydown.capture=\"keepCaretKeys\"\n />\n </div>\n <template v-if=\"name\">\n <input v-for=\"(v, k) in multiple ? values : [single]\" :key=\"k\" type=\"hidden\" :name=\"name\" :value=\"v\" />\n </template>\n <div class=\"e-combo-tail\">\n <button\n v-if=\"hasValue && clearable && !disabled\"\n type=\"button\"\n class=\"e-combo-btn\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <ComboboxTrigger\n v-if=\"!free\"\n class=\"e-combo-btn\"\n :aria-label=\"t('showOptions')\"\n :disabled=\"disabled\"\n @mousedown.prevent\n >\n <EIcon name=\"chevron-down\" bold />\n </ComboboxTrigger>\n </div>\n </ComboboxAnchor>\n <span class=\"e-sr\" role=\"status\">{{ announce }}</span>\n <ComboboxPortal :to=\"portal\">\n <ComboboxContent\n ref=\"content\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"6\"\n :collision-padding=\"8\"\n class=\"e-popover e-listpanel e-root\"\n :aria-label=\"listName\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <ComboboxViewport>\n <template v-if=\"shown.length\">\n <template v-for=\"(section, i) in sections\" :key=\"i\">\n <div v-if=\"section.group\" class=\"e-opt-set\" role=\"group\" :aria-labelledby=\"`${groupId}-g${i}`\">\n <div :id=\"`${groupId}-g${i}`\" class=\"e-opt-group\">{{ section.group }}</div>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </div>\n <template v-else>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </template>\n </template>\n </template>\n <div v-else class=\"e-opt-status\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n <ESpinner v-if=\"loading\" :label=\"t('searching')\" />\n <template v-else>{{ emptyText || t(\"noMatches\") }}</template>\n </div>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </template>\n </component>\n</template>\n\n<style>\n@layer e.controls {\n .e-combo-main {\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n align-items: center;\n align-self: stretch;\n gap: var(--e-space-1);\n min-width: 0;\n }\n\n .e-combo-tail {\n display: flex;\n flex: none;\n align-items: center;\n align-self: center;\n }\n\n .e-combo--multi {\n padding: calc(3px - var(--e-stroke-edge)) calc(var(--e-space-1) - var(--e-stroke-edge)) calc(3px - var(--e-stroke-edge)) calc(var(--e-space-2) - var(--e-stroke-edge));\n gap: var(--e-space-1);\n }\n\n .e-combo--multi .e-input {\n height: calc(var(--e-control-height) - 9px);\n align-self: center;\n padding-inline: var(--e-space-2);\n }\n\n .e-combo-main .e-tag:not(:has(.e-tag-x)) {\n padding-inline-end: var(--e-space-3);\n }\n\n .e-tag {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-space-8);\n padding: 0 var(--e-space-1) 0 var(--e-space-3);\n border-radius: var(--e-radius-pill);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n color: var(--e-ink);\n font: 500 var(--e-text-sm)/1 var(--e-font-sans);\n }\n\n .e-tag-x::after {\n content: \"\";\n position: absolute;\n inset: calc((var(--e-tap) - var(--e-space-6)) / -2);\n }\n\n .e-tag-x {\n position: relative;\n display: inline-grid;\n place-items: center;\n width: var(--e-space-6);\n height: var(--e-space-6);\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--e-primary);\n cursor: pointer;\n }\n\n .e-tag-x:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n }\n\n .e-tag-x:active {\n background: var(--e-wash-press);\n }\n\n .e-tag-x:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (forced-colors: active) {\n .e-tag {\n outline: var(--e-stroke-card) solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"EComboboxBase.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_resolveDynamicComponent","EField","_normalizeProps","_guardReactiveProps","_unref","_withCtx","_createVNode","_normalizeClass","_createElementVNode","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","EIcon","_createCommentVNode","_mergeProps","_withModifiers","EComboboxOption","ESpinner","EIcon_default","EField_default","ESpinner_default","EComboboxOption_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","EComboboxBase_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","__expose","__emit","props","__props","emit","model","useModel","t","useMessages","portal","usePortalTarget","attrs","useFieldAttrs","groupId","useUid","bareId","Bare","h","slots","frame","computed","listName","multiple","free","all","normalizeOptions","values","single","rootValue","labelOf","o","v","resting","text","ref","typing","wantOpen","anchor","query","shown","q","sections","sectionOptions","hasList","open","announce","hasValue","watch","rest","listId","content","tries","read","inputEl","focusInput","isSelected","value","itemValue","onPick","next","onInput","remove","x","clear","onKeydown","keepCaretKeys","onBlur","onWrapDown","inputBind","field","openBlock","createBlock","resolveDynamicComponent","normalizeProps","guardReactiveProps","unref","withCtx","createVNode","ComboboxRoot","_cache","$event","ComboboxAnchor","normalizeClass","createElementVNode","createElementBlock","Fragment","renderList","createTextVNode","toDisplayString","createCommentVNode","ComboboxInput","mergeProps","k","withModifiers","ComboboxTrigger","ComboboxPortal","ComboboxContent","ComboboxViewport","i","section"],"sources":["../../../src/components/Combobox/EComboboxBase.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, nextTick, onMounted, ref, watch, type FunctionalComponent } from \"vue\";\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxTrigger,\n ComboboxViewport,\n} from \"reka-ui\";\nimport EField from \"../Field/EField.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport ESpinner from \"../Spinner/ESpinner.vue\";\nimport EComboboxOption from \"./EComboboxOption.vue\";\nimport { normalizeOptions, sectionOptions } from \"../Select/options.js\";\nimport type { EComboboxProps } from \"./types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\nimport \"./combo.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = withDefaults(defineProps<EComboboxProps>(), {\n clearable: true,\n});\n\nconst emit = defineEmits<{\n /** The text in the input changed, by typing or by choosing. Use it to fetch options from a server. */\n inputChange: [text: string];\n}>();\n\nconst model = defineModel<string | string[]>();\n\nconst t = useMessages();\nconst portal = usePortalTarget();\nconst attrs = useFieldAttrs();\nconst groupId = useUid();\nconst bareId = useUid(() => props.id);\n\nconst Bare: FunctionalComponent = (_, { slots }) =>\n h(\"div\", attrs.wrapper(), slots.default?.({ id: bareId.value, ariaInvalid: undefined, ariaDescribedby: undefined }));\nconst frame = computed(() =>\n props.bare\n ? {}\n : {\n id: props.id,\n label: props.label,\n hideLabel: props.hideLabel,\n hint: props.hint,\n error: props.error,\n required: props.required,\n optional: props.optional,\n },\n);\nconst listName = computed(() => (props.bare ? (props.ariaLabel ?? props.label) : props.label));\n\nconst multiple = computed(() => props.multiple);\n// Free text is for one value; with `multiple` it is ignored.\nconst free = computed(() => props.freeform && !props.multiple);\nconst all = computed(() => normalizeOptions(props.options));\nconst values = computed<string[]>(() => (multiple.value && Array.isArray(model.value) ? model.value : []));\nconst single = computed(() => (typeof model.value === \"string\" ? model.value : \"\"));\nconst rootValue = computed(() => (multiple.value ? values.value : single.value));\n\nfunction labelOf(v: string): string {\n return all.value.find((o) => o.value === v)?.label ?? (free.value ? v : \"\");\n}\nconst resting = () => (multiple.value ? \"\" : labelOf(single.value));\n\nconst text = ref(resting());\nconst typing = ref(false);\nconst wantOpen = defineModel<boolean>(\"open\", { default: false });\nconst anchor = ref<{ $el: HTMLElement } | null>(null);\nconst query = computed(() => (typing.value ? text.value.trim().toLowerCase() : \"\"));\n\nconst shown = computed(() => {\n const q = query.value;\n if (props.filter) return all.value.filter((o) => props.filter!(o, q));\n return all.value.filter(\n (o) => !q || o.label.toLowerCase().includes(q) || (o.description ?? \"\").toLowerCase().includes(q),\n );\n});\nconst sections = computed(() => sectionOptions(shown.value));\nconst hasList = computed(() => shown.value.length > 0 || !!props.loading || !free.value);\nconst open = computed(() => wantOpen.value && hasList.value && !props.disabled);\nconst announce = computed(() =>\n open.value && !shown.value.length ? (props.loading ? t(\"searching\") : props.emptyText || t(\"noMatches\")) : \"\",\n);\nconst hasValue = computed(() => (multiple.value ? values.value.length > 0 : !!text.value));\n\nwatch(rootValue, () => {\n const rest = resting();\n if (rest !== text.value) {\n text.value = rest;\n typing.value = false;\n }\n});\nwatch(all, () => {\n if (!typing.value && !open.value) text.value = resting();\n});\n\nconst listId = ref<string | undefined>();\nconst content = ref<{ $el: HTMLElement } | null>(null);\nonMounted(() => {\n if (!open.value) return;\n let tries = 0;\n const read = () => {\n listId.value = content.value?.$el?.id || undefined;\n if (!listId.value && tries++ < 10) requestAnimationFrame(read);\n };\n void nextTick(read);\n});\n\nconst inputEl = () => anchor.value?.$el?.querySelector(\"input\") ?? null;\nconst focusInput = () => inputEl()?.focus();\n\nfunction isSelected(value: string): boolean {\n return multiple.value ? values.value.includes(value) : free.value ? single.value === value : single.value === value;\n}\nconst itemValue = (o: { value: string; label: string }) => (free.value ? o.label : o.value);\n\nfunction onPick(v: unknown) {\n typing.value = false;\n if (multiple.value) {\n model.value = Array.isArray(v) ? (v as string[]) : [];\n text.value = \"\";\n emit(\"inputChange\", \"\");\n return;\n }\n const next = typeof v === \"string\" ? v : \"\";\n model.value = next;\n text.value = free.value ? next : labelOf(next);\n emit(\"inputChange\", text.value);\n}\n\nfunction onInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n text.value = v;\n typing.value = true;\n wantOpen.value = true;\n emit(\"inputChange\", v);\n if (free.value) model.value = v;\n}\n\nfunction remove(v: string) {\n model.value = values.value.filter((x) => x !== v);\n}\n\nfunction clear() {\n model.value = multiple.value ? [] : \"\";\n text.value = \"\";\n typing.value = false;\n emit(\"inputChange\", \"\");\n focusInput();\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\" && !open.value && text.value) {\n e.preventDefault();\n clear();\n } else if (e.key === \"Backspace\" && multiple.value && !text.value && values.value.length) {\n remove(values.value[values.value.length - 1]!);\n }\n}\n\nfunction keepCaretKeys(e: KeyboardEvent) {\n if (e.key === \"Home\" || e.key === \"End\") e.stopImmediatePropagation();\n}\n\nfunction onBlur(e: FocusEvent) {\n const next = e.relatedTarget as Element | null;\n if (next && (anchor.value?.$el?.contains(next) || next.closest?.(\".e-popover\"))) return;\n wantOpen.value = false;\n typing.value = false;\n if (!free.value) text.value = resting();\n}\n\nfunction onWrapDown(e: MouseEvent) {\n if (e.target === e.currentTarget && !props.disabled) {\n e.preventDefault();\n focusInput();\n }\n}\n\ntype FieldSlot = { id: string; ariaInvalid: \"true\" | undefined; ariaDescribedby: string | undefined };\nfunction inputBind(field: FieldSlot) {\n return {\n id: field.id,\n required: props.required && !(multiple.value && values.value.length) ? true : undefined,\n placeholder: multiple.value && values.value.length ? \"\" : props.placeholder,\n \"aria-invalid\": field.ariaInvalid,\n \"aria-label\": props.bare ? listName.value : undefined,\n autocomplete: \"off\",\n ...(listId.value ? { \"aria-controls\": listId.value } : {}),\n ...(shown.value.length ? {} : { \"aria-activedescendant\": undefined }),\n ...attrs.input(field.ariaDescribedby),\n };\n}\n\ndefineExpose({\n input: computed(() => inputEl()),\n focus: focusInput,\n});\n</script>\n\n<template>\n <component :is=\"bare ? Bare : EField\" v-bind=\"{ ...attrs.wrapper(), ...frame }\">\n <template #default=\"field\">\n <ComboboxRoot\n class=\"e-combo-root\"\n :model-value=\"rootValue\"\n :multiple=\"multiple\"\n :open=\"open\"\n :disabled=\"disabled\"\n ignore-filter\n @update:model-value=\"onPick\"\n @update:open=\"wantOpen = $event\"\n >\n <ComboboxAnchor\n ref=\"anchor\"\n class=\"e-input-wrap e-combo\"\n :class=\"{ 'e-combo--multi': multiple }\"\n :data-invalid=\"error && !bare ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n @mousedown=\"onWrapDown\"\n @focusout=\"onBlur\"\n >\n <div class=\"e-combo-main\">\n <template v-if=\"multiple\">\n <span v-for=\"v in values\" :key=\"v\" class=\"e-tag\">\n {{ labelOf(v) }}\n <button\n v-if=\"!disabled\"\n type=\"button\"\n class=\"e-tag-x\"\n :aria-label=\"t('removeItem', { label: labelOf(v) })\"\n @click=\"remove(v)\"\n >\n <EIcon name=\"x\" small />\n </button>\n </span>\n </template>\n <ComboboxInput\n class=\"e-input e-combo-input\"\n :model-value=\"text\"\n :display-value=\"(v: unknown) => (typeof v === 'string' ? (free ? v : labelOf(v)) : '')\"\n :disabled=\"disabled\"\n v-bind=\"inputBind(field)\"\n @update:model-value=\"text = $event\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @keydown.capture=\"keepCaretKeys\"\n />\n </div>\n <template v-if=\"name\">\n <input v-for=\"(v, k) in multiple ? values : [single]\" :key=\"k\" type=\"hidden\" :name=\"name\" :value=\"v\" />\n </template>\n <div class=\"e-combo-tail\">\n <button\n v-if=\"hasValue && clearable && !disabled\"\n type=\"button\"\n class=\"e-combo-btn\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <ComboboxTrigger\n v-if=\"!free\"\n class=\"e-combo-btn\"\n :aria-label=\"t('showOptions')\"\n :disabled=\"disabled\"\n @mousedown.prevent\n >\n <EIcon name=\"chevron-down\" bold />\n </ComboboxTrigger>\n </div>\n </ComboboxAnchor>\n <span class=\"e-sr\" role=\"status\">{{ announce }}</span>\n <ComboboxPortal :to=\"portal\">\n <ComboboxContent\n ref=\"content\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"6\"\n :collision-padding=\"8\"\n class=\"e-popover e-listpanel e-root\"\n :aria-label=\"listName\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <ComboboxViewport>\n <template v-if=\"shown.length\">\n <template v-for=\"(section, i) in sections\" :key=\"i\">\n <div v-if=\"section.group\" class=\"e-opt-set\" role=\"group\" :aria-labelledby=\"`${groupId}-g${i}`\">\n <div :id=\"`${groupId}-g${i}`\" class=\"e-opt-group\">{{ section.group }}</div>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </div>\n <template v-else>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </template>\n </template>\n </template>\n <div v-else class=\"e-opt-status\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n <ESpinner v-if=\"loading\" :label=\"t('searching')\" />\n <template v-else>{{ emptyText || t(\"noMatches\") }}</template>\n </div>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </template>\n </component>\n</template>\n\n<style>\n@layer e.controls {\n .e-combo-main {\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n align-items: center;\n align-self: stretch;\n gap: var(--e-space-1);\n min-width: 0;\n }\n\n .e-combo-tail {\n display: flex;\n flex: none;\n align-items: center;\n align-self: center;\n }\n\n .e-combo--multi {\n padding: 3px var(--e-space-1) 3px var(--e-space-2);\n gap: var(--e-space-1);\n }\n\n .e-combo--multi .e-input {\n height: calc(var(--e-control-height) - 9px);\n align-self: center;\n padding-inline: var(--e-space-2);\n }\n\n .e-combo-main .e-tag:not(:has(.e-tag-x)) {\n padding-inline-end: var(--e-space-3);\n }\n\n .e-tag {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-space-8);\n padding: 0 var(--e-space-1) 0 var(--e-space-3);\n border-radius: var(--e-radius-pill);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n color: var(--e-ink);\n font: 500 var(--e-text-sm)/1 var(--e-font-sans);\n }\n\n .e-tag-x::after {\n content: \"\";\n position: absolute;\n inset: calc((var(--e-tap) - var(--e-space-6)) / -2);\n }\n\n .e-tag-x {\n position: relative;\n display: inline-grid;\n place-items: center;\n width: var(--e-space-6);\n height: var(--e-space-6);\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--e-primary);\n cursor: pointer;\n }\n\n .e-tag-x:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n }\n\n .e-tag-x:active {\n background: var(--e-wash-press);\n }\n\n .e-tag-x:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (forced-colors: active) {\n .e-tag {\n outline: var(--e-stroke-card) solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"EComboboxBase.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_resolveDynamicComponent","EField","_normalizeProps","_guardReactiveProps","_unref","_withCtx","_createVNode","_normalizeClass","_createElementVNode","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","EIcon","_createCommentVNode","_mergeProps","_withModifiers","EComboboxOption","ESpinner","EIcon_default","EField_default","ESpinner_default","EComboboxOption_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","EComboboxBase_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","\"open\"","\"openModifiers\"","__expose","__emit","props","__props","emit","model","useModel","t","useMessages","portal","usePortalTarget","attrs","useFieldAttrs","groupId","useUid","bareId","Bare","h","slots","frame","computed","listName","multiple","free","all","normalizeOptions","values","single","rootValue","labelOf","o","v","resting","text","ref","typing","wantOpen","anchor","query","shown","q","sections","sectionOptions","hasList","open","announce","hasValue","watch","rest","listId","content","tries","read","inputEl","focusInput","isSelected","value","itemValue","onPick","next","onInput","remove","x","clear","onKeydown","keepCaretKeys","onBlur","onWrapDown","inputBind","field","openBlock","createBlock","resolveDynamicComponent","normalizeProps","guardReactiveProps","unref","withCtx","createVNode","ComboboxRoot","_cache","$event","ComboboxAnchor","normalizeClass","createElementVNode","createElementBlock","Fragment","renderList","createTextVNode","toDisplayString","createCommentVNode","ComboboxInput","mergeProps","k","withModifiers","ComboboxTrigger","ComboboxPortal","ComboboxContent","ComboboxViewport","i","section"],"sources":["../../../src/components/Combobox/EComboboxBase.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, h, nextTick, onMounted, ref, watch, type FunctionalComponent } from \"vue\";\nimport {\n ComboboxAnchor,\n ComboboxContent,\n ComboboxInput,\n ComboboxPortal,\n ComboboxRoot,\n ComboboxTrigger,\n ComboboxViewport,\n} from \"reka-ui\";\nimport EField from \"../Field/EField.vue\";\nimport EIcon from \"../Icon/EIcon.vue\";\nimport ESpinner from \"../Spinner/ESpinner.vue\";\nimport EComboboxOption from \"./EComboboxOption.vue\";\nimport { normalizeOptions, sectionOptions } from \"../Select/options.js\";\nimport type { EComboboxProps } from \"./types.js\";\nimport { useMessages, usePortalTarget } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport { useUid } from \"../../composables/useUid.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\nimport \"../Select/panel.css\";\nimport \"./combo.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = withDefaults(defineProps<EComboboxProps>(), {\n clearable: true,\n});\n\nconst emit = defineEmits<{\n /** The text in the input changed, by typing or by choosing. Use it to fetch options from a server. */\n inputChange: [text: string];\n}>();\n\nconst model = defineModel<string | string[]>();\n\nconst t = useMessages();\nconst portal = usePortalTarget();\nconst attrs = useFieldAttrs();\nconst groupId = useUid();\nconst bareId = useUid(() => props.id);\n\nconst Bare: FunctionalComponent = (_, { slots }) =>\n h(\"div\", attrs.wrapper(), slots.default?.({ id: bareId.value, ariaInvalid: undefined, ariaDescribedby: undefined }));\nconst frame = computed(() =>\n props.bare\n ? {}\n : {\n id: props.id,\n label: props.label,\n hideLabel: props.hideLabel,\n hint: props.hint,\n error: props.error,\n required: props.required,\n optional: props.optional,\n },\n);\nconst listName = computed(() => (props.bare ? (props.ariaLabel ?? props.label) : props.label));\n\nconst multiple = computed(() => props.multiple);\n// Free text is for one value; with `multiple` it is ignored.\nconst free = computed(() => props.freeform && !props.multiple);\nconst all = computed(() => normalizeOptions(props.options));\nconst values = computed<string[]>(() => (multiple.value && Array.isArray(model.value) ? model.value : []));\nconst single = computed(() => (typeof model.value === \"string\" ? model.value : \"\"));\nconst rootValue = computed(() => (multiple.value ? values.value : single.value));\n\nfunction labelOf(v: string): string {\n return all.value.find((o) => o.value === v)?.label ?? (free.value ? v : \"\");\n}\nconst resting = () => (multiple.value ? \"\" : labelOf(single.value));\n\nconst text = ref(resting());\nconst typing = ref(false);\nconst wantOpen = defineModel<boolean>(\"open\", { default: false });\nconst anchor = ref<{ $el: HTMLElement } | null>(null);\nconst query = computed(() => (typing.value ? text.value.trim().toLowerCase() : \"\"));\n\nconst shown = computed(() => {\n const q = query.value;\n if (props.filter) return all.value.filter((o) => props.filter!(o, q));\n return all.value.filter(\n (o) => !q || o.label.toLowerCase().includes(q) || (o.description ?? \"\").toLowerCase().includes(q),\n );\n});\nconst sections = computed(() => sectionOptions(shown.value));\nconst hasList = computed(() => shown.value.length > 0 || !!props.loading || !free.value);\nconst open = computed(() => wantOpen.value && hasList.value && !props.disabled);\nconst announce = computed(() =>\n open.value && !shown.value.length ? (props.loading ? t(\"searching\") : props.emptyText || t(\"noMatches\")) : \"\",\n);\nconst hasValue = computed(() => (multiple.value ? values.value.length > 0 : !!text.value));\n\nwatch(rootValue, () => {\n const rest = resting();\n if (rest !== text.value) {\n text.value = rest;\n typing.value = false;\n }\n});\nwatch(all, () => {\n if (!typing.value && !open.value) text.value = resting();\n});\n\nconst listId = ref<string | undefined>();\nconst content = ref<{ $el: HTMLElement } | null>(null);\nonMounted(() => {\n if (!open.value) return;\n let tries = 0;\n const read = () => {\n listId.value = content.value?.$el?.id || undefined;\n if (!listId.value && tries++ < 10) requestAnimationFrame(read);\n };\n void nextTick(read);\n});\n\nconst inputEl = () => anchor.value?.$el?.querySelector(\"input\") ?? null;\nconst focusInput = () => inputEl()?.focus();\n\nfunction isSelected(value: string): boolean {\n return multiple.value ? values.value.includes(value) : free.value ? single.value === value : single.value === value;\n}\nconst itemValue = (o: { value: string; label: string }) => (free.value ? o.label : o.value);\n\nfunction onPick(v: unknown) {\n typing.value = false;\n if (multiple.value) {\n model.value = Array.isArray(v) ? (v as string[]) : [];\n text.value = \"\";\n emit(\"inputChange\", \"\");\n return;\n }\n const next = typeof v === \"string\" ? v : \"\";\n model.value = next;\n text.value = free.value ? next : labelOf(next);\n emit(\"inputChange\", text.value);\n}\n\nfunction onInput(e: Event) {\n const v = (e.target as HTMLInputElement).value;\n text.value = v;\n typing.value = true;\n wantOpen.value = true;\n emit(\"inputChange\", v);\n if (free.value) model.value = v;\n}\n\nfunction remove(v: string) {\n model.value = values.value.filter((x) => x !== v);\n}\n\nfunction clear() {\n model.value = multiple.value ? [] : \"\";\n text.value = \"\";\n typing.value = false;\n emit(\"inputChange\", \"\");\n focusInput();\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\" && !open.value && text.value) {\n e.preventDefault();\n clear();\n } else if (e.key === \"Backspace\" && multiple.value && !text.value && values.value.length) {\n remove(values.value[values.value.length - 1]!);\n }\n}\n\nfunction keepCaretKeys(e: KeyboardEvent) {\n if (e.key === \"Home\" || e.key === \"End\") e.stopImmediatePropagation();\n}\n\nfunction onBlur(e: FocusEvent) {\n const next = e.relatedTarget as Element | null;\n if (next && (anchor.value?.$el?.contains(next) || next.closest?.(\".e-popover\"))) return;\n wantOpen.value = false;\n typing.value = false;\n if (!free.value) text.value = resting();\n}\n\nfunction onWrapDown(e: MouseEvent) {\n if (e.target === e.currentTarget && !props.disabled) {\n e.preventDefault();\n focusInput();\n }\n}\n\ntype FieldSlot = { id: string; ariaInvalid: \"true\" | undefined; ariaDescribedby: string | undefined };\nfunction inputBind(field: FieldSlot) {\n return {\n id: field.id,\n required: props.required && !(multiple.value && values.value.length) ? true : undefined,\n placeholder: multiple.value && values.value.length ? \"\" : props.placeholder,\n \"aria-invalid\": field.ariaInvalid,\n \"aria-label\": props.bare ? listName.value : undefined,\n autocomplete: \"off\",\n ...(listId.value ? { \"aria-controls\": listId.value } : {}),\n ...(shown.value.length ? {} : { \"aria-activedescendant\": undefined }),\n ...attrs.input(field.ariaDescribedby),\n };\n}\n\ndefineExpose({\n input: computed(() => inputEl()),\n focus: focusInput,\n});\n</script>\n\n<template>\n <component :is=\"bare ? Bare : EField\" v-bind=\"{ ...attrs.wrapper(), ...frame }\">\n <template #default=\"field\">\n <ComboboxRoot\n class=\"e-combo-root\"\n :model-value=\"rootValue\"\n :multiple=\"multiple\"\n :open=\"open\"\n :disabled=\"disabled\"\n ignore-filter\n @update:model-value=\"onPick\"\n @update:open=\"wantOpen = $event\"\n >\n <ComboboxAnchor\n ref=\"anchor\"\n class=\"e-input-wrap e-combo\"\n :class=\"{ 'e-combo--multi': multiple }\"\n :data-invalid=\"error && !bare ? '' : undefined\"\n :data-disabled=\"disabled ? '' : undefined\"\n @mousedown=\"onWrapDown\"\n @focusout=\"onBlur\"\n >\n <div class=\"e-combo-main\">\n <template v-if=\"multiple\">\n <span v-for=\"v in values\" :key=\"v\" class=\"e-tag\">\n {{ labelOf(v) }}\n <button\n v-if=\"!disabled\"\n type=\"button\"\n class=\"e-tag-x\"\n :aria-label=\"t('removeItem', { label: labelOf(v) })\"\n @click=\"remove(v)\"\n >\n <EIcon name=\"x\" small />\n </button>\n </span>\n </template>\n <ComboboxInput\n class=\"e-input e-combo-input\"\n :model-value=\"text\"\n :display-value=\"(v: unknown) => (typeof v === 'string' ? (free ? v : labelOf(v)) : '')\"\n :disabled=\"disabled\"\n v-bind=\"inputBind(field)\"\n @update:model-value=\"text = $event\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @keydown.capture=\"keepCaretKeys\"\n />\n </div>\n <template v-if=\"name\">\n <input v-for=\"(v, k) in multiple ? values : [single]\" :key=\"k\" type=\"hidden\" :name=\"name\" :value=\"v\" />\n </template>\n <div class=\"e-combo-tail\">\n <button\n v-if=\"hasValue && clearable && !disabled\"\n type=\"button\"\n class=\"e-combo-btn\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <ComboboxTrigger\n v-if=\"!free\"\n class=\"e-combo-btn\"\n :aria-label=\"t('showOptions')\"\n :disabled=\"disabled\"\n @mousedown.prevent\n >\n <EIcon name=\"chevron-down\" bold />\n </ComboboxTrigger>\n </div>\n </ComboboxAnchor>\n <span class=\"e-sr\" role=\"status\">{{ announce }}</span>\n <ComboboxPortal :to=\"portal\">\n <ComboboxContent\n ref=\"content\"\n position=\"popper\"\n align=\"start\"\n :side-offset=\"6\"\n :collision-padding=\"8\"\n class=\"e-popover e-listpanel e-root\"\n :aria-label=\"listName\"\n :aria-busy=\"loading ? 'true' : undefined\"\n >\n <ComboboxViewport>\n <template v-if=\"shown.length\">\n <template v-for=\"(section, i) in sections\" :key=\"i\">\n <div v-if=\"section.group\" class=\"e-opt-set\" role=\"group\" :aria-labelledby=\"`${groupId}-g${i}`\">\n <div :id=\"`${groupId}-g${i}`\" class=\"e-opt-group\">{{ section.group }}</div>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </div>\n <template v-else>\n <EComboboxOption\n v-for=\"o in section.options\"\n :key=\"o.value\"\n :option=\"o\"\n :value=\"itemValue(o)\"\n :selected=\"isSelected(itemValue(o))\"\n :query=\"query\"\n />\n </template>\n </template>\n </template>\n <div v-else class=\"e-opt-status\" role=\"option\" aria-disabled=\"true\" aria-selected=\"false\">\n <ESpinner v-if=\"loading\" :label=\"t('searching')\" />\n <template v-else>{{ emptyText || t(\"noMatches\") }}</template>\n </div>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n </template>\n </component>\n</template>\n\n<style>\n@layer e.controls {\n .e-combo-main {\n display: flex;\n flex: 1;\n flex-wrap: wrap;\n align-items: center;\n align-self: stretch;\n gap: var(--e-space-1);\n min-width: 0;\n }\n\n .e-combo-tail {\n display: flex;\n flex: none;\n align-items: center;\n align-self: center;\n }\n\n .e-combo--multi {\n padding: calc(3px - var(--e-stroke-edge)) calc(var(--e-space-1) - var(--e-stroke-edge)) calc(3px - var(--e-stroke-edge)) calc(var(--e-space-2) - var(--e-stroke-edge));\n gap: var(--e-space-1);\n }\n\n .e-combo--multi .e-input {\n height: calc(var(--e-control-height) - 9px);\n align-self: center;\n padding-inline: var(--e-space-2);\n }\n\n .e-combo-main .e-tag:not(:has(.e-tag-x)) {\n padding-inline-end: var(--e-space-3);\n }\n\n .e-tag {\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-space-8);\n padding: 0 var(--e-space-1) 0 var(--e-space-3);\n border-radius: var(--e-radius-pill);\n background: var(--e-surface-tint);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n color: var(--e-ink);\n font: 500 var(--e-text-sm)/1 var(--e-font-sans);\n }\n\n .e-tag-x::after {\n content: \"\";\n position: absolute;\n inset: calc((var(--e-tap) - var(--e-space-6)) / -2);\n }\n\n .e-tag-x {\n position: relative;\n display: inline-grid;\n place-items: center;\n width: var(--e-space-6);\n height: var(--e-space-6);\n padding: 0;\n border: 0;\n border-radius: 50%;\n background: transparent;\n color: var(--e-primary);\n cursor: pointer;\n }\n\n .e-tag-x:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-card) var(--e-primary);\n }\n\n .e-tag-x:active {\n background: var(--e-wash-press);\n }\n\n .e-tag-x:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n @media (forced-colors: active) {\n .e-tag {\n outline: var(--e-stroke-card) solid CanvasText;\n }\n }\n}\n</style>\n"],"mappings":"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"}