@eos-ui/vue 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AppShell/EAppShell.js.map +1 -1
- package/dist/components/AppShell/EAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Button/EButton.js.map +1 -1
- package/dist/components/Button/EButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SearchBar/ESearchBar.js.map +1 -1
- package/dist/components/SearchBar/ESearchBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Tabs/ETabs.js.map +1 -1
- package/dist/components/Tabs/ETabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/style.css +32 -32
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EAppShell.js","names":["_sfc_main","EAppShell_vue_vue_type_script_setup_true_lang_default","EAppShell_default"],"sources":["../../../src/components/AppShell/EAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ESkipLink from \"../SkipLink/ESkipLink.vue\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The `id` of the `main` element, which the skip link targets. Keep it unique. */\n mainId?: string;\n /** The name of the sidebar landmark. @default \"Main\" */\n sidebarLabel?: string;\n }>(),\n { mainId: \"main\" },\n);\n\ndefineSlots<{\n /** An EAppHeader. */\n header?(): unknown;\n /** The side navigation, usually an ENavList. Two columns from 48rem wide; above the content below that. */\n sidebar?(): unknown;\n /** An EAppFooter. */\n footer?(): unknown;\n /** The page: start it with an EPageHeader. */\n default?(): unknown;\n}>();\n\nconst t = useMessages();\n</script>\n\n<template>\n <div class=\"e-shell\" :class=\"$slots.sidebar && 'e-shell--side'\">\n <ESkipLink :href=\"`#${mainId}`\" />\n <slot name=\"header\" />\n <div class=\"e-shell-body\">\n <aside v-if=\"$slots.sidebar\" class=\"e-shell-side\" :aria-label=\"sidebarLabel || t('mainNav')\">\n <slot name=\"sidebar\" />\n </aside>\n <main :id=\"mainId\" class=\"e-shell-main\" tabindex=\"-1\">\n <slot />\n </main>\n </div>\n <slot name=\"footer\" />\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-shell {\n position: relative;\n display: grid;\n grid-template-rows: auto 1fr auto;\n min-height: 100%;\n background: var(--e-background);\n }\n\n .e-shell-body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--e-space-6);\n width: 100%;\n max-width: var(--e-shell-width, 72rem);\n margin-inline: auto;\n padding: var(--e-space-6) var(--e-space-4);\n }\n\n /* Hairlines
|
|
1
|
+
{"version":3,"file":"EAppShell.js","names":["_sfc_main","EAppShell_vue_vue_type_script_setup_true_lang_default","EAppShell_default"],"sources":["../../../src/components/AppShell/EAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ESkipLink from \"../SkipLink/ESkipLink.vue\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The `id` of the `main` element, which the skip link targets. Keep it unique. */\n mainId?: string;\n /** The name of the sidebar landmark. @default \"Main\" */\n sidebarLabel?: string;\n }>(),\n { mainId: \"main\" },\n);\n\ndefineSlots<{\n /** An EAppHeader. */\n header?(): unknown;\n /** The side navigation, usually an ENavList. Two columns from 48rem wide; above the content below that. */\n sidebar?(): unknown;\n /** An EAppFooter. */\n footer?(): unknown;\n /** The page: start it with an EPageHeader. */\n default?(): unknown;\n}>();\n\nconst t = useMessages();\n</script>\n\n<template>\n <div class=\"e-shell\" :class=\"$slots.sidebar && 'e-shell--side'\">\n <ESkipLink :href=\"`#${mainId}`\" />\n <slot name=\"header\" />\n <div class=\"e-shell-body\">\n <aside v-if=\"$slots.sidebar\" class=\"e-shell-side\" :aria-label=\"sidebarLabel || t('mainNav')\">\n <slot name=\"sidebar\" />\n </aside>\n <main :id=\"mainId\" class=\"e-shell-main\" tabindex=\"-1\">\n <slot />\n </main>\n </div>\n <slot name=\"footer\" />\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-shell {\n position: relative;\n overflow-x: clip;\n display: grid;\n grid-template-rows: auto 1fr auto;\n min-height: 100%;\n background: var(--e-background);\n }\n\n .e-shell-body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--e-space-6);\n width: 100%;\n max-width: var(--e-shell-width, 72rem);\n margin-inline: auto;\n padding: var(--e-space-6) var(--e-space-4);\n }\n\n /* Hairlines just outside both edges of the page column, drawn over the header and footer. When the column fills the screen they fall off it and nothing shows. */\n .e-shell::after {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: 0;\n z-index: var(--e-z-sticky);\n width: min(100%, var(--e-shell-width, 72rem));\n margin-inline: auto;\n box-shadow:\n calc(-1 * var(--e-stroke-hair)) 0 0 0 var(--e-shell-rail, var(--e-border)),\n var(--e-stroke-hair) 0 0 0 var(--e-shell-rail, var(--e-border));\n pointer-events: none;\n }\n\n @media (min-width: 48rem) {\n .e-shell--side .e-shell-body {\n grid-template-columns: 15rem minmax(0, 1fr);\n }\n }\n\n .e-shell-main {\n min-width: 0;\n }\n\n .e-shell-main:focus:not(:focus-visible) {\n outline: none;\n }\n\n .e-shell-main:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n @media print {\n .e-root,\n body {\n background: var(--e-print-paper, #fff);\n color: var(--e-print-ink, #000);\n }\n\n .e-shell::after,\n .e-shell-side {\n display: none;\n }\n\n .e-shell-body {\n max-width: none;\n padding: 0;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_normalizeClass","_createVNode","ESkipLink","_renderSlot","_createElementVNode","_unref","_createCommentVNode","ESkipLink_default","_hoisted_1","_hoisted_2","_hoisted_3","EAppShell_vue_vue_type_script_setup_true_lang_default","t","useMessages","openBlock","createElementBlock","normalizeClass","_ctx","createVNode","__props","renderSlot","createElementVNode","unref","createCommentVNode"],"sources":["../../../src/components/AppShell/EAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ESkipLink from \"../SkipLink/ESkipLink.vue\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The `id` of the `main` element, which the skip link targets. Keep it unique. */\n mainId?: string;\n /** The name of the sidebar landmark. @default \"Main\" */\n sidebarLabel?: string;\n }>(),\n { mainId: \"main\" },\n);\n\ndefineSlots<{\n /** An EAppHeader. */\n header?(): unknown;\n /** The side navigation, usually an ENavList. Two columns from 48rem wide; above the content below that. */\n sidebar?(): unknown;\n /** An EAppFooter. */\n footer?(): unknown;\n /** The page: start it with an EPageHeader. */\n default?(): unknown;\n}>();\n\nconst t = useMessages();\n</script>\n\n<template>\n <div class=\"e-shell\" :class=\"$slots.sidebar && 'e-shell--side'\">\n <ESkipLink :href=\"`#${mainId}`\" />\n <slot name=\"header\" />\n <div class=\"e-shell-body\">\n <aside v-if=\"$slots.sidebar\" class=\"e-shell-side\" :aria-label=\"sidebarLabel || t('mainNav')\">\n <slot name=\"sidebar\" />\n </aside>\n <main :id=\"mainId\" class=\"e-shell-main\" tabindex=\"-1\">\n <slot />\n </main>\n </div>\n <slot name=\"footer\" />\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-shell {\n position: relative;\n display: grid;\n grid-template-rows: auto 1fr auto;\n min-height: 100%;\n background: var(--e-background);\n }\n\n .e-shell-body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--e-space-6);\n width: 100%;\n max-width: var(--e-shell-width, 72rem);\n margin-inline: auto;\n padding: var(--e-space-6) var(--e-space-4);\n }\n\n /* Hairlines
|
|
1
|
+
{"version":3,"file":"EAppShell.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_normalizeClass","_createVNode","ESkipLink","_renderSlot","_createElementVNode","_unref","_createCommentVNode","ESkipLink_default","_hoisted_1","_hoisted_2","_hoisted_3","EAppShell_vue_vue_type_script_setup_true_lang_default","t","useMessages","openBlock","createElementBlock","normalizeClass","_ctx","createVNode","__props","renderSlot","createElementVNode","unref","createCommentVNode"],"sources":["../../../src/components/AppShell/EAppShell.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport ESkipLink from \"../SkipLink/ESkipLink.vue\";\nimport { useMessages } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The `id` of the `main` element, which the skip link targets. Keep it unique. */\n mainId?: string;\n /** The name of the sidebar landmark. @default \"Main\" */\n sidebarLabel?: string;\n }>(),\n { mainId: \"main\" },\n);\n\ndefineSlots<{\n /** An EAppHeader. */\n header?(): unknown;\n /** The side navigation, usually an ENavList. Two columns from 48rem wide; above the content below that. */\n sidebar?(): unknown;\n /** An EAppFooter. */\n footer?(): unknown;\n /** The page: start it with an EPageHeader. */\n default?(): unknown;\n}>();\n\nconst t = useMessages();\n</script>\n\n<template>\n <div class=\"e-shell\" :class=\"$slots.sidebar && 'e-shell--side'\">\n <ESkipLink :href=\"`#${mainId}`\" />\n <slot name=\"header\" />\n <div class=\"e-shell-body\">\n <aside v-if=\"$slots.sidebar\" class=\"e-shell-side\" :aria-label=\"sidebarLabel || t('mainNav')\">\n <slot name=\"sidebar\" />\n </aside>\n <main :id=\"mainId\" class=\"e-shell-main\" tabindex=\"-1\">\n <slot />\n </main>\n </div>\n <slot name=\"footer\" />\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-shell {\n position: relative;\n overflow-x: clip;\n display: grid;\n grid-template-rows: auto 1fr auto;\n min-height: 100%;\n background: var(--e-background);\n }\n\n .e-shell-body {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: var(--e-space-6);\n width: 100%;\n max-width: var(--e-shell-width, 72rem);\n margin-inline: auto;\n padding: var(--e-space-6) var(--e-space-4);\n }\n\n /* Hairlines just outside both edges of the page column, drawn over the header and footer. When the column fills the screen they fall off it and nothing shows. */\n .e-shell::after {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline: 0;\n z-index: var(--e-z-sticky);\n width: min(100%, var(--e-shell-width, 72rem));\n margin-inline: auto;\n box-shadow:\n calc(-1 * var(--e-stroke-hair)) 0 0 0 var(--e-shell-rail, var(--e-border)),\n var(--e-stroke-hair) 0 0 0 var(--e-shell-rail, var(--e-border));\n pointer-events: none;\n }\n\n @media (min-width: 48rem) {\n .e-shell--side .e-shell-body {\n grid-template-columns: 15rem minmax(0, 1fr);\n }\n }\n\n .e-shell-main {\n min-width: 0;\n }\n\n .e-shell-main:focus:not(:focus-visible) {\n outline: none;\n }\n\n .e-shell-main:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n @media print {\n .e-root,\n body {\n background: var(--e-print-paper, #fff);\n color: var(--e-print-ink, #000);\n }\n\n .e-shell::after,\n .e-shell-side {\n display: none;\n }\n\n .e-shell-body {\n max-width: none;\n padding: 0;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;EA0BA,IAAMe,IAAIC,EAAY;E,kBAIpBf,EAAA,GAAAC,EAYM,OAAA,EAZD,OAAKC,EAAA,CAAC,WAAkBH,EAAAA,OAAO,WAAO,eAAA,CAAA,E;GACzCI,EAAkCC,GAAA,EAAtB,MAAI,IAAMiB,EAAA,S;GACtBhB,EAAsBc,EAAA,QAAA,QAAA;GACtBb,EAOM,OAPNI,GAOM,CANSX,EAAAA,OAAO,WAApBC,EAAA,GAAAC,EAEQ,SAAA;;IAFqB,OAAM;IAAgB,cAAYoB,EAAA,gBAAgBd,EAAAO,CAAA,CAAC,CAAA,SAAA;G,IAC9ET,EAAuBc,EAAA,QAAA,SAAA,C,uBAEzBb,EAEO,QAAA;IAFA,IAAIe,EAAA;IAAQ,OAAM;IAAe,UAAS;G,IAC/ChB,EAAQc,EAAA,QAAA,SAAA,C;GAGZd,EAAsBc,EAAA,QAAA,QAAA"}
|
|
@@ -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 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
|
|
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 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 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
|
+
{"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 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":"ESearchBar.js","names":["_sfc_main","ESearchBar_vue_vue_type_script_setup_true_lang_default","ESearchBar_default"],"sources":["../../../src/components/SearchBar/ESearchBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport { ref } from \"vue\";\nimport { useMessages } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nwithDefaults(\n defineProps<{\n /** Names the box and the search landmark; there is no visible label. @default \"Search\" */\n label?: string;\n /** Say what can be searched, briefly. @default \"Search\" */\n placeholder?: string;\n /** The text on the button. @default \"Search\" */\n action?: string;\n /** Leaves out the button, for a box that filters or searches as you type. Enter still submits. */\n hideAction?: boolean;\n /** The clear button, shown when there is text. */\n clearable?: boolean;\n /** The name submitted with a form. @default \"q\" */\n name?: string;\n /** Disables the box and button. Say why in an `ENotice`. */\n disabled?: boolean;\n }>(),\n { clearable: true },\n);\n\nconst emit = defineEmits<{\n /** The person pressed Enter or the button. */\n submit: [value: string];\n}>();\n\n/** The text. */\nconst model = defineModel<string>({ default: \"\" });\n\nconst t = useMessages();\nconst attrs = useFieldAttrs();\nconst box = ref<HTMLInputElement | null>(null);\n\nfunction clear() {\n model.value = \"\";\n box.value?.focus();\n}\n\ndefineExpose({\n input: box,\n focus: () => box.value?.focus(),\n});\n</script>\n\n<template>\n <form\n class=\"e-search\"\n v-bind=\"attrs.wrapper()\"\n role=\"search\"\n :aria-label=\"label || t('search')\"\n @submit.prevent=\"emit('submit', model)\"\n >\n <span class=\"e-search-lead\"><EIcon name=\"search\" /></span>\n <input\n ref=\"box\"\n v-bind=\"attrs.input()\"\n class=\"e-input\"\n :name=\"name || 'q'\"\n :aria-label=\"label || t('search')\"\n :placeholder=\"placeholder || t('search')\"\n :value=\"model\"\n :disabled=\"disabled\"\n @input=\"model = ($event.target as HTMLInputElement).value\"\n />\n <button\n v-if=\"clearable && model && !disabled\"\n type=\"button\"\n class=\"e-search-clear\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <EButton v-if=\"!hideAction\" type=\"submit\" :disabled=\"disabled\">{{ action || t(\"search\") }}</EButton>\n </form>\n</template>\n\n<style>\n@layer e.controls {\n .e-search {\n --e-ring: var(--e-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-1) - var(--e-stroke-edge)) 0 calc(var(--e-space-2) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n background-clip: padding-box;\n box-shadow: var(--e-well);\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search
|
|
1
|
+
{"version":3,"file":"ESearchBar.js","names":["_sfc_main","ESearchBar_vue_vue_type_script_setup_true_lang_default","ESearchBar_default"],"sources":["../../../src/components/SearchBar/ESearchBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport { ref } from \"vue\";\nimport { useMessages } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nwithDefaults(\n defineProps<{\n /** Names the box and the search landmark; there is no visible label. @default \"Search\" */\n label?: string;\n /** Say what can be searched, briefly. @default \"Search\" */\n placeholder?: string;\n /** The text on the button. @default \"Search\" */\n action?: string;\n /** Leaves out the button, for a box that filters or searches as you type. Enter still submits. */\n hideAction?: boolean;\n /** The clear button, shown when there is text. */\n clearable?: boolean;\n /** The name submitted with a form. @default \"q\" */\n name?: string;\n /** Disables the box and button. Say why in an `ENotice`. */\n disabled?: boolean;\n }>(),\n { clearable: true },\n);\n\nconst emit = defineEmits<{\n /** The person pressed Enter or the button. */\n submit: [value: string];\n}>();\n\n/** The text. */\nconst model = defineModel<string>({ default: \"\" });\n\nconst t = useMessages();\nconst attrs = useFieldAttrs();\nconst box = ref<HTMLInputElement | null>(null);\n\nfunction clear() {\n model.value = \"\";\n box.value?.focus();\n}\n\ndefineExpose({\n input: box,\n focus: () => box.value?.focus(),\n});\n</script>\n\n<template>\n <form\n class=\"e-search\"\n v-bind=\"attrs.wrapper()\"\n role=\"search\"\n :aria-label=\"label || t('search')\"\n @submit.prevent=\"emit('submit', model)\"\n >\n <span class=\"e-search-lead\"><EIcon name=\"search\" /></span>\n <input\n ref=\"box\"\n v-bind=\"attrs.input()\"\n class=\"e-input\"\n :name=\"name || 'q'\"\n :aria-label=\"label || t('search')\"\n :placeholder=\"placeholder || t('search')\"\n :value=\"model\"\n :disabled=\"disabled\"\n @input=\"model = ($event.target as HTMLInputElement).value\"\n />\n <button\n v-if=\"clearable && model && !disabled\"\n type=\"button\"\n class=\"e-search-clear\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <EButton v-if=\"!hideAction\" type=\"submit\" :disabled=\"disabled\">{{ action || t(\"search\") }}</EButton>\n </form>\n</template>\n\n<style>\n@layer e.controls {\n .e-search {\n --e-ring: var(--e-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-1) - var(--e-stroke-edge)) 0 calc(var(--e-space-2) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n background-clip: padding-box;\n box-shadow: var(--e-well);\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search .e-btn {\n position: relative;\n height: calc(var(--e-control-height) - 6px);\n padding: 0 calc(var(--e-space-3) - var(--e-stroke-edge));\n font-size: var(--e-text-md);\n }\n\n .e-search .e-btn::after {\n content: \"\";\n position: absolute;\n inset: -3px;\n }\n\n .e-search-clear {\n display: inline-grid;\n place-items: center;\n position: relative;\n flex: none;\n width: calc(var(--e-control-height) - 9px);\n height: calc(var(--e-control-height) - 9px);\n padding: 0;\n border: 0;\n border-radius: var(--e-radius-sm);\n background: transparent;\n color: var(--e-ink);\n cursor: pointer;\n transition: background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search-clear::after {\n content: \"\";\n position: absolute;\n inset: -5px;\n }\n\n .e-search-clear:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-wash-ring);\n }\n\n .e-search-clear:active {\n background: var(--e-wash-press);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ink);\n }\n\n .e-search-clear:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-search-lead {\n display: grid;\n place-items: center;\n flex: none;\n width: var(--e-space-8);\n color: var(--e-muted);\n }\n\n .e-search .e-input {\n flex: 1;\n text-overflow: ellipsis;\n height: 100%;\n border: 0;\n outline: 0;\n background: transparent;\n box-shadow: none;\n font-size: var(--e-text-md);\n padding-inline: var(--e-space-2);\n }\n\n .e-search .e-input:hover,\n .e-search .e-input:focus {\n border: 0;\n background: transparent;\n box-shadow: none;\n }\n\n .e-search .e-input:focus-visible {\n outline: none;\n }\n\n .e-search:focus-within {\n --e-ring: var(--e-focus-field);\n\n background: var(--e-surface);\n outline: max(var(--e-stroke-focus), calc(2 * var(--e-stroke-edge))) solid var(--e-focus-field);\n outline-offset: var(--e-focus-gap-field);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-search {\n transition: none;\n }\n }\n\n @media print {\n .e-search {\n display: none;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ESearchBar.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_mergeProps","_unref","_withModifiers","_createElementVNode","_createVNode","EIcon","_createCommentVNode","_createBlock","EButton","_withCtx","_createTextVNode","_toDisplayString","EIcon_default","EButton_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","ESearchBar_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__expose","__emit","emit","model","useModel","__props","t","useMessages","attrs","useFieldAttrs","box","ref","clear","openBlock","createElementBlock","mergeProps","unref","_cache","withModifiers","createElementVNode","createVNode","$event","createCommentVNode","createBlock","withCtx","createTextVNode","toDisplayString"],"sources":["../../../src/components/SearchBar/ESearchBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport { ref } from \"vue\";\nimport { useMessages } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nwithDefaults(\n defineProps<{\n /** Names the box and the search landmark; there is no visible label. @default \"Search\" */\n label?: string;\n /** Say what can be searched, briefly. @default \"Search\" */\n placeholder?: string;\n /** The text on the button. @default \"Search\" */\n action?: string;\n /** Leaves out the button, for a box that filters or searches as you type. Enter still submits. */\n hideAction?: boolean;\n /** The clear button, shown when there is text. */\n clearable?: boolean;\n /** The name submitted with a form. @default \"q\" */\n name?: string;\n /** Disables the box and button. Say why in an `ENotice`. */\n disabled?: boolean;\n }>(),\n { clearable: true },\n);\n\nconst emit = defineEmits<{\n /** The person pressed Enter or the button. */\n submit: [value: string];\n}>();\n\n/** The text. */\nconst model = defineModel<string>({ default: \"\" });\n\nconst t = useMessages();\nconst attrs = useFieldAttrs();\nconst box = ref<HTMLInputElement | null>(null);\n\nfunction clear() {\n model.value = \"\";\n box.value?.focus();\n}\n\ndefineExpose({\n input: box,\n focus: () => box.value?.focus(),\n});\n</script>\n\n<template>\n <form\n class=\"e-search\"\n v-bind=\"attrs.wrapper()\"\n role=\"search\"\n :aria-label=\"label || t('search')\"\n @submit.prevent=\"emit('submit', model)\"\n >\n <span class=\"e-search-lead\"><EIcon name=\"search\" /></span>\n <input\n ref=\"box\"\n v-bind=\"attrs.input()\"\n class=\"e-input\"\n :name=\"name || 'q'\"\n :aria-label=\"label || t('search')\"\n :placeholder=\"placeholder || t('search')\"\n :value=\"model\"\n :disabled=\"disabled\"\n @input=\"model = ($event.target as HTMLInputElement).value\"\n />\n <button\n v-if=\"clearable && model && !disabled\"\n type=\"button\"\n class=\"e-search-clear\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <EButton v-if=\"!hideAction\" type=\"submit\" :disabled=\"disabled\">{{ action || t(\"search\") }}</EButton>\n </form>\n</template>\n\n<style>\n@layer e.controls {\n .e-search {\n --e-ring: var(--e-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-1) - var(--e-stroke-edge)) 0 calc(var(--e-space-2) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n background-clip: padding-box;\n box-shadow: var(--e-well);\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search
|
|
1
|
+
{"version":3,"file":"ESearchBar.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_mergeProps","_unref","_withModifiers","_createElementVNode","_createVNode","EIcon","_createCommentVNode","_createBlock","EButton","_withCtx","_createTextVNode","_toDisplayString","EIcon_default","EButton_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","ESearchBar_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","__expose","__emit","emit","model","useModel","__props","t","useMessages","attrs","useFieldAttrs","box","ref","clear","openBlock","createElementBlock","mergeProps","unref","_cache","withModifiers","createElementVNode","createVNode","$event","createCommentVNode","createBlock","withCtx","createTextVNode","toDisplayString"],"sources":["../../../src/components/SearchBar/ESearchBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EIcon from \"../Icon/EIcon.vue\";\nimport EButton from \"../Button/EButton.vue\";\nimport { ref } from \"vue\";\nimport { useMessages } from \"../../config.js\";\nimport { useFieldAttrs } from \"../../composables/useFieldAttrs.js\";\nimport \"../../styles/base.css\";\nimport \"../TextField/input.css\";\n\ndefineOptions({ inheritAttrs: false });\n\nwithDefaults(\n defineProps<{\n /** Names the box and the search landmark; there is no visible label. @default \"Search\" */\n label?: string;\n /** Say what can be searched, briefly. @default \"Search\" */\n placeholder?: string;\n /** The text on the button. @default \"Search\" */\n action?: string;\n /** Leaves out the button, for a box that filters or searches as you type. Enter still submits. */\n hideAction?: boolean;\n /** The clear button, shown when there is text. */\n clearable?: boolean;\n /** The name submitted with a form. @default \"q\" */\n name?: string;\n /** Disables the box and button. Say why in an `ENotice`. */\n disabled?: boolean;\n }>(),\n { clearable: true },\n);\n\nconst emit = defineEmits<{\n /** The person pressed Enter or the button. */\n submit: [value: string];\n}>();\n\n/** The text. */\nconst model = defineModel<string>({ default: \"\" });\n\nconst t = useMessages();\nconst attrs = useFieldAttrs();\nconst box = ref<HTMLInputElement | null>(null);\n\nfunction clear() {\n model.value = \"\";\n box.value?.focus();\n}\n\ndefineExpose({\n input: box,\n focus: () => box.value?.focus(),\n});\n</script>\n\n<template>\n <form\n class=\"e-search\"\n v-bind=\"attrs.wrapper()\"\n role=\"search\"\n :aria-label=\"label || t('search')\"\n @submit.prevent=\"emit('submit', model)\"\n >\n <span class=\"e-search-lead\"><EIcon name=\"search\" /></span>\n <input\n ref=\"box\"\n v-bind=\"attrs.input()\"\n class=\"e-input\"\n :name=\"name || 'q'\"\n :aria-label=\"label || t('search')\"\n :placeholder=\"placeholder || t('search')\"\n :value=\"model\"\n :disabled=\"disabled\"\n @input=\"model = ($event.target as HTMLInputElement).value\"\n />\n <button\n v-if=\"clearable && model && !disabled\"\n type=\"button\"\n class=\"e-search-clear\"\n :aria-label=\"t('clear')\"\n @mousedown.prevent\n @click=\"clear\"\n >\n <EIcon name=\"x\" />\n </button>\n <EButton v-if=\"!hideAction\" type=\"submit\" :disabled=\"disabled\">{{ action || t(\"search\") }}</EButton>\n </form>\n</template>\n\n<style>\n@layer e.controls {\n .e-search {\n --e-ring: var(--e-border-strong);\n\n display: flex;\n align-items: center;\n gap: var(--e-space-1);\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-1) - var(--e-stroke-edge)) 0 calc(var(--e-space-2) - var(--e-stroke-edge));\n box-sizing: border-box;\n border: var(--e-stroke-edge) solid var(--e-ring);\n border-radius: var(--e-radius-md);\n background: var(--e-surface);\n background-clip: padding-box;\n box-shadow: var(--e-well);\n transition: border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search .e-btn {\n position: relative;\n height: calc(var(--e-control-height) - 6px);\n padding: 0 calc(var(--e-space-3) - var(--e-stroke-edge));\n font-size: var(--e-text-md);\n }\n\n .e-search .e-btn::after {\n content: \"\";\n position: absolute;\n inset: -3px;\n }\n\n .e-search-clear {\n display: inline-grid;\n place-items: center;\n position: relative;\n flex: none;\n width: calc(var(--e-control-height) - 9px);\n height: calc(var(--e-control-height) - 9px);\n padding: 0;\n border: 0;\n border-radius: var(--e-radius-sm);\n background: transparent;\n color: var(--e-ink);\n cursor: pointer;\n transition: background-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n .e-search-clear::after {\n content: \"\";\n position: absolute;\n inset: -5px;\n }\n\n .e-search-clear:hover {\n background: var(--e-wash-hover);\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-wash-ring);\n }\n\n .e-search-clear:active {\n background: var(--e-wash-press);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-ink);\n }\n\n .e-search-clear:focus-visible {\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: calc(-1 * var(--e-stroke-focus));\n }\n\n .e-search-lead {\n display: grid;\n place-items: center;\n flex: none;\n width: var(--e-space-8);\n color: var(--e-muted);\n }\n\n .e-search .e-input {\n flex: 1;\n text-overflow: ellipsis;\n height: 100%;\n border: 0;\n outline: 0;\n background: transparent;\n box-shadow: none;\n font-size: var(--e-text-md);\n padding-inline: var(--e-space-2);\n }\n\n .e-search .e-input:hover,\n .e-search .e-input:focus {\n border: 0;\n background: transparent;\n box-shadow: none;\n }\n\n .e-search .e-input:focus-visible {\n outline: none;\n }\n\n .e-search:focus-within {\n --e-ring: var(--e-focus-field);\n\n background: var(--e-surface);\n outline: max(var(--e-stroke-focus), calc(2 * var(--e-stroke-edge))) solid var(--e-focus-field);\n outline-offset: var(--e-focus-gap-field);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-search {\n transition: none;\n }\n }\n\n @media print {\n .e-search {\n display: none;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BA,IAAM0B,IAAOD,GAMPE,IAAQ3B,EAAmB6B,GAAA,YAAgB,GAE3CC,IAAIC,EAAY,GAChBC,IAAQC,EAAc,GACtBC,IAAMC,EAA6B,IAAI;EAE7C,SAASC,IAAQ;GAEf,AADA,EAAM,QAAQ,IACdF,EAAI,OAAO,MAAM;EACnB;E,OAEAV,EAAa;GACX,OAAOU;GACP,aAAaA,EAAI,OAAO,MAAM;EAChC,CAAC,I,UAICjC,EAAA,GAAAC,EA8BO,QA9BPC,EA8BO,EA7BL,OAAM,WAAU,GACRC,EAAA4B,CAAA,CAAK,CAAC,QAAO,GAAA;GACrB,MAAK;GACJ,cAAYH,EAAA,SAASzB,EAAA0B,CAAA,CAAC,CAAA,QAAA;GACtB,UAAM,AAAAW,EAAA,OAAApC,GAAA,MAAUqB,EAAI,UAAWC,EAAA,KAAK,GAAA,CAAA,SAAA,CAAA;;GAErCrB,EAA0D,QAA1DY,GAA0D,CAA9BX,EAAuBC,GAAA,EAAhB,MAAK,SAAQ,CAAA,C;GAChDF,EAUE,SAVFH,EAUE;IATI,SAAA;IAAJ,KAAI+B;GACI,GAAA9B,EAAA4B,CAAA,CAAK,CAAC,MAAK,GAAA;IACnB,OAAM;IACL,MAAMH,EAAA,QAAI;IACV,cAAYA,EAAA,SAASzB,EAAA0B,CAAA,CAAC,CAAA,QAAA;IACtB,aAAaD,EAAA,eAAezB,EAAA0B,CAAA,CAAC,CAAA,QAAA;IAC7B,OAAOH,EAAA;IACP,UAAUE,EAAA;IACV,SAAK,AAAAY,EAAA,QAAA,MAAE,EAAA,QAASI,EAAO,OAA4B;;GAG9ChB,EAAA,aAAaF,EAAA,SAAK,CAAKE,EAAA,YAD/B5B,EAAA,GAAAC,EASS,UAAA;;IAPP,MAAK;IACL,OAAM;IACL,cAAYE,EAAA0B,CAAA,CAAC,CAAA,OAAA;IACb,aAAS,AAAAW,EAAA,OAAApC,QAAV,CAAA,GAAkB,CAAA,SAAA,CAAA;IACjB,SAAO+B;G,IAER7B,EAAkBC,GAAA,EAAX,MAAK,IAAG,CAAA,C;GAEDqB,EAAA,a,aAAhB5B,EAAA,GAAAS,EAAoGC,GAAA;;IAAxE,MAAK;IAAU,UAAUkB,EAAA;;IAAU,SAAAjB,QAA2B,CAAxBC,EAAAC,EAAAe,EAAA,UAAUzB,EAAA0B,CAAA,CAAC,CAAA,QAAA,CAAA,GAAA,CAAA,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ETabs.js","names":["_sfc_main","ETabs_vue_vue_type_script_setup_true_lang_default","ETabs_default"],"sources":["../../../src/components/Tabs/ETabs.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface TabItem {\n /** Names the tab's slot, and is the value of `v-model`. */\n id: string;\n /** The tab's words. */\n label: string;\n /** A number or short word in a small badge after the label. */\n count?: number | string;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, watch } from \"vue\";\nimport { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"reka-ui\";\nimport { useConfig } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nconst props = defineProps<{\n /** The tabs, in order: `{ id, label, count? }`. Two to five across, with short labels; a vertical list can be longer. `id` names the slot and is the `v-model` value. */\n items?: TabItem[];\n /** Share the width equally between the tabs instead of letting each take its own. For a narrow container where the tabs must all fit; labels truncate. @default false */\n fill?: boolean;\n /** `vertical` stacks the tabs in a column beside their panel, for a long list of sections. Use it when there are more tabs than fit across; `fill` has no effect. @default \"horizontal\" */\n orientation?: \"horizontal\" | \"vertical\";\n /** Joins the tabs to their panel so the two read as one card: the panel is outlined, the row of tabs sits on its edge like folder tabs, and the chosen tab opens into the panel with no line between. The edge stays open where there are no tabs. @default false */\n framed?: boolean;\n}>();\n\ndefineSlots<{\n [id: string]: ((props: { item: TabItem }) => unknown) | undefined;\n /** The panel of any tab that has no slot of its own. */\n panel?(props: { item: TabItem }): unknown;\n}>();\n\nconst flat = computed(() => props.items ?? []);\n\n/** The `id` of the selected tab. Keeps its own state when unbound. @default first tab */\nconst model = defineModel<string>();\n\nconst config = useConfig();\nconst current = computed(() => model.value ?? flat.value[0]?.id);\nconst dir = computed<\"ltr\" | \"rtl\">(\n () => config.dir ?? (typeof document !== \"undefined\" && document.documentElement.dir === \"rtl\" ? \"rtl\" : \"ltr\"),\n);\n\nconst list = ref<{ $el: HTMLElement } | null>(null);\n\nasync function reveal(smooth: boolean) {\n await nextTick();\n const el = list.value?.$el;\n const tab = el?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n if (props.orientation === \"vertical\" || !el || !tab || el.scrollWidth <= el.clientWidth) return;\n const calm = typeof matchMedia !== \"undefined\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n const a = tab.getBoundingClientRect();\n const b = el.getBoundingClientRect();\n el.scrollBy({ left: a.left + a.width / 2 - (b.left + b.width / 2), behavior: smooth && !calm ? \"smooth\" : \"auto\" });\n}\n\nonMounted(() => reveal(false));\nwatch(current, () => reveal(true));\n</script>\n\n<template>\n <TabsRoot\n class=\"e-tabs\"\n :class=\"{ 'e-tabs--fill': fill, 'e-tabs--vertical': orientation === 'vertical', 'e-tabs--framed': framed }\"\n :orientation=\"orientation ?? 'horizontal'\"\n :model-value=\"current\"\n :dir=\"dir\"\n @update:model-value=\"model = String($event)\"\n >\n <TabsList ref=\"list\" class=\"e-tablist\">\n <TabsTrigger v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tab\">\n {{ item.label }}\n <span v-if=\"item.count != null\" class=\"e-tab-count\">{{ item.count }}</span>\n </TabsTrigger>\n </TabsList>\n <TabsContent v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tabpanel\">\n <slot :name=\"item.id\" :item=\"item\"><slot name=\"panel\" :item=\"item\" /></slot>\n </TabsContent>\n </TabsRoot>\n</template>\n\n<style>\n@layer e.containers {\n .e-tablist {\n display: flex;\n flex: none;\n gap: 0;\n /* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties -- the two axes are set apart */\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n }\n\n .e-tablist::-webkit-scrollbar {\n display: none;\n }\n\n /* Tabs are button-like: every tab is ringed and neighbours sit flush and share an edge, so only the outer ends of the row are rounded. The selected tab is outlined in the primary colour with a thick slab along its bottom. */\n .e-tab {\n --e-bc: var(--e-border-strong);\n\n /* A selected tab rises: the slab is a band the tab paints along one edge itself, so there is no second shape behind the corners. Every tab is one control height tall either way. */\n --e-lift: 0px;\n --e-slab: var(--e-primary);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-2);\n flex: none;\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-bc);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: 0;\n background: transparent;\n background-clip: padding-box;\n color: var(--e-muted);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n cursor: pointer;\n transition:\n color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out),\n border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n /* Only the outer ends of the row are rounded. */\n .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-end-start-radius: var(--e-radius-md);\n }\n\n .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tab + .e-tab {\n margin-inline-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tab:hover {\n --e-bc: var(--e-ink);\n\n z-index: var(--e-z-raised);\n color: var(--e-ink);\n background-color: var(--e-surface-hover);\n }\n\n .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n z-index: var(--e-z-sticky);\n border-bottom-color: var(--e-slab);\n background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n color: var(--e-ink);\n font-weight: 600;\n }\n\n /* The slab answers the pointer too: it darkens under the cursor, in step with the face. */\n .e-tab[aria-selected=\"true\"]:hover {\n --e-slab: color-mix(in srgb, var(--e-primary), var(--e-shade-slab));\n }\n\n .e-tab:focus-visible {\n z-index: var(--e-z-focus);\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n .e-tabs--fill > .e-tablist {\n overflow-x: hidden;\n }\n\n .e-tabs--fill > .e-tablist > .e-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: max(0px, calc(var(--e-space-1) - var(--e-stroke-edge)));\n }\n\n /* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab rises towards the panel, so its slab is a band down the inline-start side, away from the panel, instead of along the bottom, and only the top and bottom ends of the column are rounded. */\n .e-tabs--vertical {\n display: flex;\n align-items: flex-start;\n gap: var(--e-space-4);\n }\n\n .e-tabs--vertical > .e-tablist {\n flex-direction: column;\n flex: none;\n overflow: visible;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:last-child {\n border-end-start-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab + .e-tab {\n margin-inline-start: 0;\n margin-block-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n border-bottom-width: var(--e-stroke-edge);\n border-bottom-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n }\n\n .e-tabs--vertical > .e-tabpanel {\n flex: 1 1 0;\n min-width: 0;\n padding-top: 0;\n }\n\n /* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it. Tabs sit flush with their neighbours, square where they meet; only the card's outer corner at the first tab is rounded, and the panel's own corner beside it is square. The row always leaves a corner's width of open edge past the last tab, so the panel's curve never lands against a tab's straight edge. */\n .e-tabs--framed > .e-tablist {\n position: relative;\n z-index: var(--e-z-raised);\n margin-block-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed > .e-tablist > .e-tab {\n --e-bc: var(--e-border-strong);\n --e-lift: 0px;\n\n border-radius: 0;\n background-color: var(--e-surface-tint);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tablist > .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed > .e-tablist {\n padding-inline-end: var(--e-radius-md);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:hover {\n background-color: var(--e-surface-hover);\n }\n\n /* The chosen tab rises like a button does, with its primary slab as a band on the edge away from the panel, and its open sides outlined in the primary colour. */\n .e-tabs--framed > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block-end: var(--e-stroke-edge);\n border-bottom-width: 0;\n border-top-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-top-color: var(--e-slab);\n background-color: var(--e-surface);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-border-strong);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n background-clip: padding-box;\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tabpanel {\n border-start-end-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical {\n gap: 0;\n align-items: stretch;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist {\n align-self: flex-start;\n margin-block-end: var(--e-radius-md);\n margin-inline-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n border-block-start-width: var(--e-stroke-edge);\n border-block-start-color: var(--e-bc);\n border-block-end-width: var(--e-stroke-edge);\n border-block-end-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n border-inline-end-width: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"]:first-child {\n margin-block-start: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n }\n\n .e-tab-count {\n min-width: var(--e-space-6);\n padding: 0 var(--e-space-2);\n border-radius: var(--e-radius-pill);\n background: color-mix(in srgb, var(--e-primary) 12%, var(--e-surface));\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-primary);\n font: 600 var(--e-text-xs) / 20px var(--e-font-mono);\n text-align: center;\n color: var(--e-ink);\n }\n\n .e-tabpanel {\n padding-top: var(--e-space-4);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-tab {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-tab[aria-selected=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"ETabs.js","names":["_sfc_main","ETabs_vue_vue_type_script_setup_true_lang_default","ETabs_default"],"sources":["../../../src/components/Tabs/ETabs.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface TabItem {\n /** Names the tab's slot, and is the value of `v-model`. */\n id: string;\n /** The tab's words. */\n label: string;\n /** A number or short word in a small badge after the label. */\n count?: number | string;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, watch } from \"vue\";\nimport { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"reka-ui\";\nimport { useConfig } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nconst props = defineProps<{\n /** The tabs, in order: `{ id, label, count? }`. Two to five across, with short labels; a vertical list can be longer. `id` names the slot and is the `v-model` value. */\n items?: TabItem[];\n /** Share the width equally between the tabs instead of letting each take its own. For a narrow container where the tabs must all fit; labels truncate. @default false */\n fill?: boolean;\n /** `vertical` stacks the tabs in a column beside their panel, for a long list of sections. Use it when there are more tabs than fit across; `fill` has no effect. @default \"horizontal\" */\n orientation?: \"horizontal\" | \"vertical\";\n /** Joins the tabs to their panel so the two read as one card: the panel is outlined, the row of tabs sits on its edge like folder tabs, and the chosen tab opens into the panel with no line between. The edge stays open where there are no tabs. @default false */\n framed?: boolean;\n}>();\n\ndefineSlots<{\n [id: string]: ((props: { item: TabItem }) => unknown) | undefined;\n /** The panel of any tab that has no slot of its own. */\n panel?(props: { item: TabItem }): unknown;\n}>();\n\nconst flat = computed(() => props.items ?? []);\n\n/** The `id` of the selected tab. Keeps its own state when unbound. @default first tab */\nconst model = defineModel<string>();\n\nconst config = useConfig();\nconst current = computed(() => model.value ?? flat.value[0]?.id);\nconst dir = computed<\"ltr\" | \"rtl\">(\n () => config.dir ?? (typeof document !== \"undefined\" && document.documentElement.dir === \"rtl\" ? \"rtl\" : \"ltr\"),\n);\n\nconst list = ref<{ $el: HTMLElement } | null>(null);\n\nasync function reveal(smooth: boolean) {\n await nextTick();\n const el = list.value?.$el;\n const tab = el?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n if (props.orientation === \"vertical\" || !el || !tab || el.scrollWidth <= el.clientWidth) return;\n const calm = typeof matchMedia !== \"undefined\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n const a = tab.getBoundingClientRect();\n const b = el.getBoundingClientRect();\n el.scrollBy({ left: a.left + a.width / 2 - (b.left + b.width / 2), behavior: smooth && !calm ? \"smooth\" : \"auto\" });\n}\n\nonMounted(() => reveal(false));\nwatch(current, () => reveal(true));\n</script>\n\n<template>\n <TabsRoot\n class=\"e-tabs\"\n :class=\"{ 'e-tabs--fill': fill, 'e-tabs--vertical': orientation === 'vertical', 'e-tabs--framed': framed }\"\n :orientation=\"orientation ?? 'horizontal'\"\n :model-value=\"current\"\n :dir=\"dir\"\n @update:model-value=\"model = String($event)\"\n >\n <TabsList ref=\"list\" class=\"e-tablist\">\n <TabsTrigger v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tab\">\n {{ item.label }}\n <span v-if=\"item.count != null\" class=\"e-tab-count\">{{ item.count }}</span>\n </TabsTrigger>\n </TabsList>\n <TabsContent v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tabpanel\">\n <slot :name=\"item.id\" :item=\"item\"><slot name=\"panel\" :item=\"item\" /></slot>\n </TabsContent>\n </TabsRoot>\n</template>\n\n<style>\n@layer e.containers {\n .e-tablist {\n display: flex;\n flex: none;\n gap: 0;\n /* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties -- the two axes are set apart */\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n }\n\n .e-tablist::-webkit-scrollbar {\n display: none;\n }\n\n /* Tabs are button-like: every tab is ringed and neighbours sit flush and share an edge, so only the outer ends of the row are rounded. The selected tab is outlined in the primary colour with a thick slab along its bottom. */\n .e-tab {\n --e-bc: var(--e-border-strong);\n\n /* A selected tab rises: the slab is a band the tab paints along one edge itself, so there is no second shape behind the corners. Every tab is one control height tall either way. */\n --e-lift: 0px;\n --e-slab: var(--e-primary);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-2);\n flex: none;\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-bc);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: 0;\n background: transparent;\n background-clip: padding-box;\n color: var(--e-muted);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n cursor: pointer;\n transition:\n color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out),\n border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n /* Only the outer ends of the row are rounded. */\n .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-end-start-radius: var(--e-radius-md);\n }\n\n .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tab + .e-tab {\n margin-inline-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tab:hover {\n --e-bc: var(--e-ink);\n\n z-index: var(--e-z-raised);\n color: var(--e-ink);\n background-color: var(--e-surface-hover);\n }\n\n .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n z-index: var(--e-z-sticky);\n border-bottom-color: var(--e-slab);\n background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n color: var(--e-ink);\n font-weight: 600;\n }\n\n /* The slab answers the pointer too: it darkens under the cursor, in step with the face. */\n .e-tab[aria-selected=\"true\"]:hover {\n --e-slab: color-mix(in srgb, var(--e-primary), var(--e-shade-slab));\n }\n\n .e-tab:focus-visible {\n z-index: var(--e-z-focus);\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n .e-tabs--fill > .e-tablist {\n overflow-x: hidden;\n }\n\n .e-tabs--fill > .e-tablist > .e-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: max(0px, calc(var(--e-space-1) - var(--e-stroke-edge)));\n }\n\n /* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab's slab is a band down the inline-start side, and only the column's ends are rounded. */\n .e-tabs--vertical {\n display: flex;\n align-items: flex-start;\n gap: var(--e-space-4);\n }\n\n .e-tabs--vertical > .e-tablist {\n flex-direction: column;\n flex: none;\n overflow: visible;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:last-child {\n border-end-start-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab + .e-tab {\n margin-inline-start: 0;\n margin-block-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n border-bottom-width: var(--e-stroke-edge);\n border-bottom-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n }\n\n .e-tabs--vertical > .e-tabpanel {\n flex: 1 1 0;\n min-width: 0;\n padding-top: 0;\n }\n\n /* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it. Only the card's outer corner at the first tab is rounded. The row leaves a corner's width of open edge past the last tab, so the panel's curve never meets a tab's straight edge. */\n .e-tabs--framed > .e-tablist {\n position: relative;\n z-index: var(--e-z-raised);\n margin-block-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed > .e-tablist > .e-tab {\n --e-bc: var(--e-border-strong);\n --e-lift: 0px;\n\n border-radius: 0;\n background-color: var(--e-surface-tint);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tablist > .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed > .e-tablist {\n padding-inline-end: var(--e-radius-md);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:hover {\n background-color: var(--e-surface-hover);\n }\n\n /* The chosen tab rises like a button does, with its primary slab as a band on the edge away from the panel, and its open sides outlined in the primary colour. */\n .e-tabs--framed > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block-end: var(--e-stroke-edge);\n border-bottom-width: 0;\n border-top-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-top-color: var(--e-slab);\n background-color: var(--e-surface);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-border-strong);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n background-clip: padding-box;\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tabpanel {\n border-start-end-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical {\n gap: 0;\n align-items: stretch;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist {\n align-self: flex-start;\n margin-block-end: var(--e-radius-md);\n margin-inline-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n border-block-start-width: var(--e-stroke-edge);\n border-block-start-color: var(--e-bc);\n border-block-end-width: var(--e-stroke-edge);\n border-block-end-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n border-inline-end-width: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"]:first-child {\n margin-block-start: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n }\n\n .e-tab-count {\n min-width: var(--e-space-6);\n padding: 0 var(--e-space-2);\n border-radius: var(--e-radius-pill);\n background: color-mix(in srgb, var(--e-primary) 12%, var(--e-surface));\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-primary);\n font: 600 var(--e-text-xs) / 20px var(--e-font-mono);\n text-align: center;\n color: var(--e-ink);\n }\n\n .e-tabpanel {\n padding-top: var(--e-space-4);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-tab {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-tab[aria-selected=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ETabs.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","_createCommentVNode","_renderSlot","_hoisted_1","ETabs_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","props","__props","flat","computed","model","useModel","config","useConfig","current","dir","list","ref","reveal","nextTick","el","tab","calm","a","b","smooth","onMounted","watch","openBlock","createBlock","unref","TabsRoot","normalizeClass","_cache","$event","withCtx","createVNode","TabsList","createElementBlock","Fragment","renderList","TabsTrigger","item","createTextVNode","toDisplayString","createCommentVNode","TabsContent","renderSlot","_ctx"],"sources":["../../../src/components/Tabs/ETabs.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface TabItem {\n /** Names the tab's slot, and is the value of `v-model`. */\n id: string;\n /** The tab's words. */\n label: string;\n /** A number or short word in a small badge after the label. */\n count?: number | string;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, watch } from \"vue\";\nimport { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"reka-ui\";\nimport { useConfig } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nconst props = defineProps<{\n /** The tabs, in order: `{ id, label, count? }`. Two to five across, with short labels; a vertical list can be longer. `id` names the slot and is the `v-model` value. */\n items?: TabItem[];\n /** Share the width equally between the tabs instead of letting each take its own. For a narrow container where the tabs must all fit; labels truncate. @default false */\n fill?: boolean;\n /** `vertical` stacks the tabs in a column beside their panel, for a long list of sections. Use it when there are more tabs than fit across; `fill` has no effect. @default \"horizontal\" */\n orientation?: \"horizontal\" | \"vertical\";\n /** Joins the tabs to their panel so the two read as one card: the panel is outlined, the row of tabs sits on its edge like folder tabs, and the chosen tab opens into the panel with no line between. The edge stays open where there are no tabs. @default false */\n framed?: boolean;\n}>();\n\ndefineSlots<{\n [id: string]: ((props: { item: TabItem }) => unknown) | undefined;\n /** The panel of any tab that has no slot of its own. */\n panel?(props: { item: TabItem }): unknown;\n}>();\n\nconst flat = computed(() => props.items ?? []);\n\n/** The `id` of the selected tab. Keeps its own state when unbound. @default first tab */\nconst model = defineModel<string>();\n\nconst config = useConfig();\nconst current = computed(() => model.value ?? flat.value[0]?.id);\nconst dir = computed<\"ltr\" | \"rtl\">(\n () => config.dir ?? (typeof document !== \"undefined\" && document.documentElement.dir === \"rtl\" ? \"rtl\" : \"ltr\"),\n);\n\nconst list = ref<{ $el: HTMLElement } | null>(null);\n\nasync function reveal(smooth: boolean) {\n await nextTick();\n const el = list.value?.$el;\n const tab = el?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n if (props.orientation === \"vertical\" || !el || !tab || el.scrollWidth <= el.clientWidth) return;\n const calm = typeof matchMedia !== \"undefined\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n const a = tab.getBoundingClientRect();\n const b = el.getBoundingClientRect();\n el.scrollBy({ left: a.left + a.width / 2 - (b.left + b.width / 2), behavior: smooth && !calm ? \"smooth\" : \"auto\" });\n}\n\nonMounted(() => reveal(false));\nwatch(current, () => reveal(true));\n</script>\n\n<template>\n <TabsRoot\n class=\"e-tabs\"\n :class=\"{ 'e-tabs--fill': fill, 'e-tabs--vertical': orientation === 'vertical', 'e-tabs--framed': framed }\"\n :orientation=\"orientation ?? 'horizontal'\"\n :model-value=\"current\"\n :dir=\"dir\"\n @update:model-value=\"model = String($event)\"\n >\n <TabsList ref=\"list\" class=\"e-tablist\">\n <TabsTrigger v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tab\">\n {{ item.label }}\n <span v-if=\"item.count != null\" class=\"e-tab-count\">{{ item.count }}</span>\n </TabsTrigger>\n </TabsList>\n <TabsContent v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tabpanel\">\n <slot :name=\"item.id\" :item=\"item\"><slot name=\"panel\" :item=\"item\" /></slot>\n </TabsContent>\n </TabsRoot>\n</template>\n\n<style>\n@layer e.containers {\n .e-tablist {\n display: flex;\n flex: none;\n gap: 0;\n /* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties -- the two axes are set apart */\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n }\n\n .e-tablist::-webkit-scrollbar {\n display: none;\n }\n\n /* Tabs are button-like: every tab is ringed and neighbours sit flush and share an edge, so only the outer ends of the row are rounded. The selected tab is outlined in the primary colour with a thick slab along its bottom. */\n .e-tab {\n --e-bc: var(--e-border-strong);\n\n /* A selected tab rises: the slab is a band the tab paints along one edge itself, so there is no second shape behind the corners. Every tab is one control height tall either way. */\n --e-lift: 0px;\n --e-slab: var(--e-primary);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-2);\n flex: none;\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-bc);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: 0;\n background: transparent;\n background-clip: padding-box;\n color: var(--e-muted);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n cursor: pointer;\n transition:\n color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out),\n border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n /* Only the outer ends of the row are rounded. */\n .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-end-start-radius: var(--e-radius-md);\n }\n\n .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tab + .e-tab {\n margin-inline-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tab:hover {\n --e-bc: var(--e-ink);\n\n z-index: var(--e-z-raised);\n color: var(--e-ink);\n background-color: var(--e-surface-hover);\n }\n\n .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n z-index: var(--e-z-sticky);\n border-bottom-color: var(--e-slab);\n background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n color: var(--e-ink);\n font-weight: 600;\n }\n\n /* The slab answers the pointer too: it darkens under the cursor, in step with the face. */\n .e-tab[aria-selected=\"true\"]:hover {\n --e-slab: color-mix(in srgb, var(--e-primary), var(--e-shade-slab));\n }\n\n .e-tab:focus-visible {\n z-index: var(--e-z-focus);\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n .e-tabs--fill > .e-tablist {\n overflow-x: hidden;\n }\n\n .e-tabs--fill > .e-tablist > .e-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: max(0px, calc(var(--e-space-1) - var(--e-stroke-edge)));\n }\n\n /* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab rises towards the panel, so its slab is a band down the inline-start side, away from the panel, instead of along the bottom, and only the top and bottom ends of the column are rounded. */\n .e-tabs--vertical {\n display: flex;\n align-items: flex-start;\n gap: var(--e-space-4);\n }\n\n .e-tabs--vertical > .e-tablist {\n flex-direction: column;\n flex: none;\n overflow: visible;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:last-child {\n border-end-start-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab + .e-tab {\n margin-inline-start: 0;\n margin-block-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n border-bottom-width: var(--e-stroke-edge);\n border-bottom-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n }\n\n .e-tabs--vertical > .e-tabpanel {\n flex: 1 1 0;\n min-width: 0;\n padding-top: 0;\n }\n\n /* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it. Tabs sit flush with their neighbours, square where they meet; only the card's outer corner at the first tab is rounded, and the panel's own corner beside it is square. The row always leaves a corner's width of open edge past the last tab, so the panel's curve never lands against a tab's straight edge. */\n .e-tabs--framed > .e-tablist {\n position: relative;\n z-index: var(--e-z-raised);\n margin-block-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed > .e-tablist > .e-tab {\n --e-bc: var(--e-border-strong);\n --e-lift: 0px;\n\n border-radius: 0;\n background-color: var(--e-surface-tint);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tablist > .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed > .e-tablist {\n padding-inline-end: var(--e-radius-md);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:hover {\n background-color: var(--e-surface-hover);\n }\n\n /* The chosen tab rises like a button does, with its primary slab as a band on the edge away from the panel, and its open sides outlined in the primary colour. */\n .e-tabs--framed > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block-end: var(--e-stroke-edge);\n border-bottom-width: 0;\n border-top-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-top-color: var(--e-slab);\n background-color: var(--e-surface);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-border-strong);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n background-clip: padding-box;\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tabpanel {\n border-start-end-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical {\n gap: 0;\n align-items: stretch;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist {\n align-self: flex-start;\n margin-block-end: var(--e-radius-md);\n margin-inline-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n border-block-start-width: var(--e-stroke-edge);\n border-block-start-color: var(--e-bc);\n border-block-end-width: var(--e-stroke-edge);\n border-block-end-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n border-inline-end-width: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"]:first-child {\n margin-block-start: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n }\n\n .e-tab-count {\n min-width: var(--e-space-6);\n padding: 0 var(--e-space-2);\n border-radius: var(--e-radius-pill);\n background: color-mix(in srgb, var(--e-primary) 12%, var(--e-surface));\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-primary);\n font: 600 var(--e-text-xs) / 20px var(--e-font-mono);\n text-align: center;\n color: var(--e-ink);\n }\n\n .e-tabpanel {\n padding-top: var(--e-space-4);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-tab {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-tab[aria-selected=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAiBA,IAAMkB,IAAQC,GAiBRC,IAAOC,QAAeH,EAAM,SAAS,CAAC,CAAC,GAGvCI,IAAQtB,EAAmBmB,GAAA,YAAC,GAE5BK,IAASC,EAAU,GACnBC,IAAUL,QAAeC,EAAM,SAASF,EAAK,MAAM,EAAE,EAAE,EAAE,GACzDO,IAAMN,QACJG,EAAO,QAAQ,OAAO,WAAa,OAAe,SAAS,gBAAgB,QAAQ,QAAQ,QAAQ,MAC3G,GAEMI,IAAOC,EAAiC,IAAI;EAElD,eAAeC,EAAO,GAAiB;GACrC,MAAMC,EAAS;GACf,IAAMC,IAAKJ,EAAK,OAAO,KACjBK,IAAMD,GAAI,cAA2B,0BAAwB;GACnE,IAAId,EAAM,gBAAgB,cAAc,CAACc,KAAM,CAACC,KAAOD,EAAG,eAAeA,EAAG,aAAa;GACzF,IAAME,IAAO,OAAO,aAAe,OAAe,WAAW,kCAAkC,CAAC,CAAC,SAC3FC,IAAIF,EAAI,sBAAsB,GAC9BG,IAAIJ,EAAG,sBAAsB;GACnC,EAAG,SAAS;IAAE,MAAMG,EAAE,OAAOA,EAAE,QAAQ,KAAKC,EAAE,OAAOA,EAAE,QAAQ;IAAI,UAAUC,KAAU,CAACH,IAAO,WAAW;GAAO,CAAC;EACpH;E,OAEAI,QAAgBR,EAAO,EAAK,CAAC,GAC7BS,EAAMb,SAAeI,EAAO,EAAI,CAAC,I,UAI/B7B,EAAA,GAAAC,EAiBWC,EAAAwC,CAAA,GAAA;GAhBT,OAAKvC,EAAA,CAAC,UAAQ;IAAA,gBACYe,EAAA;IAAI,oBAAsBA,EAAA,gBAAW;IAAA,kBAAmCA,EAAA;GAAM,CAAA,CAAA;GACvG,aAAaA,EAAA,eAAW;GACxB,eAAaO,EAAA;GACb,KAAKC,EAAA;GACL,uBAAkB,AAAAkB,EAAA,QAAA,MAAE,EAAA,QAAQ,OAAOC,CAAM;;GAE1C,SAAAzC,QAKW,CALXC,EAKWH,EAAA8C,CAAA,GAAA;IALG,SAAA;IAAJ,KAAIrB;IAAO,OAAM;;IACZ,SAAAvB,QAAoB,EAAjCJ,EAAA,EAAA,GAAAM,EAGcC,GAAA,MAAAC,EAHcW,EAAA,QAAR,OAApBnB,EAAA,GAAAC,EAGcC,EAAAkD,CAAA,GAAA;KAHqB,KAAKC,EAAK;KAAK,OAAOA,EAAK;KAAI,OAAM;;KACtE,SAAAjD,QAAgB,CAAbK,EAAAC,EAAA2C,EAAK,KAAK,IAAG,KAChB,CAAA,GAAYA,EAAK,SAAK,O,aAAtBrD,EAAA,GAAAM,EAA2E,QAA3EO,GAA2EH,EAApB2C,EAAK,KAAK,GAAA,CAAA,E;;;;G,UAGrErD,EAAA,EAAA,GAAAM,EAEcC,GAAA,MAAAC,EAFcW,EAAA,QAAR,OAApBnB,EAAA,GAAAC,EAEcC,EAAAuD,CAAA,GAAA;IAFqB,KAAKJ,EAAK;IAAK,OAAOA,EAAK;IAAI,OAAM;;IACtE,SAAAjD,QAA4E,CAA5EQ,EAA4E+C,EAAA,QAA/DN,EAAK,IAAE,EAAS,QAAI,SAA2C,CAAzCzC,EAAkC+C,EAAA,QAAA,SAAA,EAAR,QAAI,CAAA,C"}
|
|
1
|
+
{"version":3,"file":"ETabs.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_createVNode","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","_createCommentVNode","_renderSlot","_hoisted_1","ETabs_vue_vue_type_script_setup_true_lang_default","\"modelValue\"","\"modelModifiers\"","props","__props","flat","computed","model","useModel","config","useConfig","current","dir","list","ref","reveal","nextTick","el","tab","calm","a","b","smooth","onMounted","watch","openBlock","createBlock","unref","TabsRoot","normalizeClass","_cache","$event","withCtx","createVNode","TabsList","createElementBlock","Fragment","renderList","TabsTrigger","item","createTextVNode","toDisplayString","createCommentVNode","TabsContent","renderSlot","_ctx"],"sources":["../../../src/components/Tabs/ETabs.vue"],"sourcesContent":["<script lang=\"ts\">\nexport interface TabItem {\n /** Names the tab's slot, and is the value of `v-model`. */\n id: string;\n /** The tab's words. */\n label: string;\n /** A number or short word in a small badge after the label. */\n count?: number | string;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, onMounted, ref, watch } from \"vue\";\nimport { TabsContent, TabsList, TabsRoot, TabsTrigger } from \"reka-ui\";\nimport { useConfig } from \"../../config.js\";\nimport \"../../styles/base.css\";\n\nconst props = defineProps<{\n /** The tabs, in order: `{ id, label, count? }`. Two to five across, with short labels; a vertical list can be longer. `id` names the slot and is the `v-model` value. */\n items?: TabItem[];\n /** Share the width equally between the tabs instead of letting each take its own. For a narrow container where the tabs must all fit; labels truncate. @default false */\n fill?: boolean;\n /** `vertical` stacks the tabs in a column beside their panel, for a long list of sections. Use it when there are more tabs than fit across; `fill` has no effect. @default \"horizontal\" */\n orientation?: \"horizontal\" | \"vertical\";\n /** Joins the tabs to their panel so the two read as one card: the panel is outlined, the row of tabs sits on its edge like folder tabs, and the chosen tab opens into the panel with no line between. The edge stays open where there are no tabs. @default false */\n framed?: boolean;\n}>();\n\ndefineSlots<{\n [id: string]: ((props: { item: TabItem }) => unknown) | undefined;\n /** The panel of any tab that has no slot of its own. */\n panel?(props: { item: TabItem }): unknown;\n}>();\n\nconst flat = computed(() => props.items ?? []);\n\n/** The `id` of the selected tab. Keeps its own state when unbound. @default first tab */\nconst model = defineModel<string>();\n\nconst config = useConfig();\nconst current = computed(() => model.value ?? flat.value[0]?.id);\nconst dir = computed<\"ltr\" | \"rtl\">(\n () => config.dir ?? (typeof document !== \"undefined\" && document.documentElement.dir === \"rtl\" ? \"rtl\" : \"ltr\"),\n);\n\nconst list = ref<{ $el: HTMLElement } | null>(null);\n\nasync function reveal(smooth: boolean) {\n await nextTick();\n const el = list.value?.$el;\n const tab = el?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n if (props.orientation === \"vertical\" || !el || !tab || el.scrollWidth <= el.clientWidth) return;\n const calm = typeof matchMedia !== \"undefined\" && matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n const a = tab.getBoundingClientRect();\n const b = el.getBoundingClientRect();\n el.scrollBy({ left: a.left + a.width / 2 - (b.left + b.width / 2), behavior: smooth && !calm ? \"smooth\" : \"auto\" });\n}\n\nonMounted(() => reveal(false));\nwatch(current, () => reveal(true));\n</script>\n\n<template>\n <TabsRoot\n class=\"e-tabs\"\n :class=\"{ 'e-tabs--fill': fill, 'e-tabs--vertical': orientation === 'vertical', 'e-tabs--framed': framed }\"\n :orientation=\"orientation ?? 'horizontal'\"\n :model-value=\"current\"\n :dir=\"dir\"\n @update:model-value=\"model = String($event)\"\n >\n <TabsList ref=\"list\" class=\"e-tablist\">\n <TabsTrigger v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tab\">\n {{ item.label }}\n <span v-if=\"item.count != null\" class=\"e-tab-count\">{{ item.count }}</span>\n </TabsTrigger>\n </TabsList>\n <TabsContent v-for=\"item in flat\" :key=\"item.id\" :value=\"item.id\" class=\"e-tabpanel\">\n <slot :name=\"item.id\" :item=\"item\"><slot name=\"panel\" :item=\"item\" /></slot>\n </TabsContent>\n </TabsRoot>\n</template>\n\n<style>\n@layer e.containers {\n .e-tablist {\n display: flex;\n flex: none;\n gap: 0;\n /* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties -- the two axes are set apart */\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n }\n\n .e-tablist::-webkit-scrollbar {\n display: none;\n }\n\n /* Tabs are button-like: every tab is ringed and neighbours sit flush and share an edge, so only the outer ends of the row are rounded. The selected tab is outlined in the primary colour with a thick slab along its bottom. */\n .e-tab {\n --e-bc: var(--e-border-strong);\n\n /* A selected tab rises: the slab is a band the tab paints along one edge itself, so there is no second shape behind the corners. Every tab is one control height tall either way. */\n --e-lift: 0px;\n --e-slab: var(--e-primary);\n\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--e-space-2);\n flex: none;\n height: var(--e-control-height);\n padding: 0 calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-bc);\n border-bottom-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-radius: 0;\n background: transparent;\n background-clip: padding-box;\n color: var(--e-muted);\n font: 500 var(--e-text-md) / 1 var(--e-font-sans);\n cursor: pointer;\n transition:\n color var(--e-duration-tap) var(--e-easing-out),\n background-color var(--e-duration-tap) var(--e-easing-out),\n border-color var(--e-duration-tap) var(--e-easing-out);\n }\n\n /* Only the outer ends of the row are rounded. */\n .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-end-start-radius: var(--e-radius-md);\n }\n\n .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tab + .e-tab {\n margin-inline-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tab:hover {\n --e-bc: var(--e-ink);\n\n z-index: var(--e-z-raised);\n color: var(--e-ink);\n background-color: var(--e-surface-hover);\n }\n\n .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n z-index: var(--e-z-sticky);\n border-bottom-color: var(--e-slab);\n background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n color: var(--e-ink);\n font-weight: 600;\n }\n\n /* The slab answers the pointer too: it darkens under the cursor, in step with the face. */\n .e-tab[aria-selected=\"true\"]:hover {\n --e-slab: color-mix(in srgb, var(--e-primary), var(--e-shade-slab));\n }\n\n .e-tab:focus-visible {\n z-index: var(--e-z-focus);\n outline: var(--e-stroke-focus) solid var(--e-focus-ring);\n outline-offset: var(--e-focus-gap);\n }\n\n .e-tabs--fill > .e-tablist {\n overflow-x: hidden;\n }\n\n .e-tabs--fill > .e-tablist > .e-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: max(0px, calc(var(--e-space-1) - var(--e-stroke-edge)));\n }\n\n /* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab's slab is a band down the inline-start side, and only the column's ends are rounded. */\n .e-tabs--vertical {\n display: flex;\n align-items: flex-start;\n gap: var(--e-space-4);\n }\n\n .e-tabs--vertical > .e-tablist {\n flex-direction: column;\n flex: none;\n overflow: visible;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab:last-child {\n border-end-start-radius: var(--e-radius-md);\n border-end-end-radius: var(--e-radius-md);\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab + .e-tab {\n margin-inline-start: 0;\n margin-block-start: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n border-bottom-width: var(--e-stroke-edge);\n border-bottom-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n }\n\n .e-tabs--vertical > .e-tabpanel {\n flex: 1 1 0;\n min-width: 0;\n padding-top: 0;\n }\n\n /* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it. Only the card's outer corner at the first tab is rounded. The row leaves a corner's width of open edge past the last tab, so the panel's curve never meets a tab's straight edge. */\n .e-tabs--framed > .e-tablist {\n position: relative;\n z-index: var(--e-z-raised);\n margin-block-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed > .e-tablist > .e-tab {\n --e-bc: var(--e-border-strong);\n --e-lift: 0px;\n\n border-radius: 0;\n background-color: var(--e-surface-tint);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tablist > .e-tab:last-child {\n border-start-end-radius: var(--e-radius-md);\n }\n\n .e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed > .e-tablist {\n padding-inline-end: var(--e-radius-md);\n }\n\n .e-tabs--framed > .e-tablist > .e-tab:hover {\n background-color: var(--e-surface-hover);\n }\n\n /* The chosen tab rises like a button does, with its primary slab as a band on the edge away from the panel, and its open sides outlined in the primary colour. */\n .e-tabs--framed > .e-tablist > .e-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block-end: var(--e-stroke-edge);\n border-bottom-width: 0;\n border-top-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-top-color: var(--e-slab);\n background-color: var(--e-surface);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n border: var(--e-stroke-edge) solid var(--e-border-strong);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n background-clip: padding-box;\n }\n\n .e-tabs--framed.e-tabs--fill > .e-tabpanel {\n border-start-end-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical {\n gap: 0;\n align-items: stretch;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist {\n align-self: flex-start;\n margin-block-end: var(--e-radius-md);\n margin-inline-end: calc(-1 * var(--e-stroke-edge));\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n border-block-start-width: var(--e-stroke-edge);\n border-block-start-color: var(--e-bc);\n border-block-end-width: var(--e-stroke-edge);\n border-block-end-color: var(--e-bc);\n border-inline-start-width: calc(var(--e-stroke-edge) + var(--e-lift));\n border-inline-start-color: var(--e-slab);\n border-inline-end-width: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"]:first-child {\n margin-block-start: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical > .e-tabpanel {\n padding: calc(var(--e-space-4) - var(--e-stroke-edge));\n }\n\n .e-tab-count {\n min-width: var(--e-space-6);\n padding: 0 var(--e-space-2);\n border-radius: var(--e-radius-pill);\n background: color-mix(in srgb, var(--e-primary) 12%, var(--e-surface));\n box-shadow: inset 0 0 0 var(--e-stroke-hair) var(--e-primary);\n font: 600 var(--e-text-xs) / 20px var(--e-font-mono);\n text-align: center;\n color: var(--e-ink);\n }\n\n .e-tabpanel {\n padding-top: var(--e-space-4);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .e-tab {\n transition: none;\n }\n }\n\n @media (forced-colors: active) {\n .e-tab[aria-selected=\"true\"] {\n forced-color-adjust: none;\n background: Highlight;\n color: HighlightText;\n }\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;EAiBA,IAAMkB,IAAQC,GAiBRC,IAAOC,QAAeH,EAAM,SAAS,CAAC,CAAC,GAGvCI,IAAQtB,EAAmBmB,GAAA,YAAC,GAE5BK,IAASC,EAAU,GACnBC,IAAUL,QAAeC,EAAM,SAASF,EAAK,MAAM,EAAE,EAAE,EAAE,GACzDO,IAAMN,QACJG,EAAO,QAAQ,OAAO,WAAa,OAAe,SAAS,gBAAgB,QAAQ,QAAQ,QAAQ,MAC3G,GAEMI,IAAOC,EAAiC,IAAI;EAElD,eAAeC,EAAO,GAAiB;GACrC,MAAMC,EAAS;GACf,IAAMC,IAAKJ,EAAK,OAAO,KACjBK,IAAMD,GAAI,cAA2B,0BAAwB;GACnE,IAAId,EAAM,gBAAgB,cAAc,CAACc,KAAM,CAACC,KAAOD,EAAG,eAAeA,EAAG,aAAa;GACzF,IAAME,IAAO,OAAO,aAAe,OAAe,WAAW,kCAAkC,CAAC,CAAC,SAC3FC,IAAIF,EAAI,sBAAsB,GAC9BG,IAAIJ,EAAG,sBAAsB;GACnC,EAAG,SAAS;IAAE,MAAMG,EAAE,OAAOA,EAAE,QAAQ,KAAKC,EAAE,OAAOA,EAAE,QAAQ;IAAI,UAAUC,KAAU,CAACH,IAAO,WAAW;GAAO,CAAC;EACpH;E,OAEAI,QAAgBR,EAAO,EAAK,CAAC,GAC7BS,EAAMb,SAAeI,EAAO,EAAI,CAAC,I,UAI/B7B,EAAA,GAAAC,EAiBWC,EAAAwC,CAAA,GAAA;GAhBT,OAAKvC,EAAA,CAAC,UAAQ;IAAA,gBACYe,EAAA;IAAI,oBAAsBA,EAAA,gBAAW;IAAA,kBAAmCA,EAAA;GAAM,CAAA,CAAA;GACvG,aAAaA,EAAA,eAAW;GACxB,eAAaO,EAAA;GACb,KAAKC,EAAA;GACL,uBAAkB,AAAAkB,EAAA,QAAA,MAAE,EAAA,QAAQ,OAAOC,CAAM;;GAE1C,SAAAzC,QAKW,CALXC,EAKWH,EAAA8C,CAAA,GAAA;IALG,SAAA;IAAJ,KAAIrB;IAAO,OAAM;;IACZ,SAAAvB,QAAoB,EAAjCJ,EAAA,EAAA,GAAAM,EAGcC,GAAA,MAAAC,EAHcW,EAAA,QAAR,OAApBnB,EAAA,GAAAC,EAGcC,EAAAkD,CAAA,GAAA;KAHqB,KAAKC,EAAK;KAAK,OAAOA,EAAK;KAAI,OAAM;;KACtE,SAAAjD,QAAgB,CAAbK,EAAAC,EAAA2C,EAAK,KAAK,IAAG,KAChB,CAAA,GAAYA,EAAK,SAAK,O,aAAtBrD,EAAA,GAAAM,EAA2E,QAA3EO,GAA2EH,EAApB2C,EAAK,KAAK,GAAA,CAAA,E;;;;G,UAGrErD,EAAA,EAAA,GAAAM,EAEcC,GAAA,MAAAC,EAFcW,EAAA,QAAR,OAApBnB,EAAA,GAAAC,EAEcC,EAAAuD,CAAA,GAAA;IAFqB,KAAKJ,EAAK;IAAK,OAAOA,EAAK;IAAI,OAAM;;IACtE,SAAAjD,QAA4E,CAA5EQ,EAA4E+C,EAAA,QAA/DN,EAAK,IAAE,EAAS,QAAI,SAA2C,CAAzCzC,EAAkC+C,EAAA,QAAA,SAAA,EAAR,QAAI,CAAA,C"}
|
package/dist/style.css
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
--e-background: #ffffff;
|
|
19
19
|
--e-surface: #ffffff;
|
|
20
20
|
--e-surface-tint: #eaf4f8;
|
|
21
|
-
--e-surface-hover: color-mix(in srgb, var(--e-surface
|
|
21
|
+
--e-surface-hover: color-mix(in srgb, var(--e-surface), var(--e-ink) 9%);
|
|
22
22
|
--e-ink: #000000;
|
|
23
23
|
--e-print-ink: #000000;
|
|
24
24
|
--e-print-paper: #ffffff;
|
|
@@ -402,6 +402,7 @@
|
|
|
402
402
|
@layer e.page {
|
|
403
403
|
.e-shell {
|
|
404
404
|
position: relative;
|
|
405
|
+
overflow-x: clip;
|
|
405
406
|
display: grid;
|
|
406
407
|
grid-template-rows: auto 1fr auto;
|
|
407
408
|
min-height: 100%;
|
|
@@ -417,20 +418,19 @@
|
|
|
417
418
|
padding: var(--e-space-6) var(--e-space-4);
|
|
418
419
|
}
|
|
419
420
|
|
|
420
|
-
/* Hairlines
|
|
421
|
-
@media (min-width: 64rem) {
|
|
421
|
+
/* Hairlines just outside both edges of the page column, drawn over the header and footer. When the column fills the screen they fall off it and nothing shows. */
|
|
422
422
|
.e-shell::after {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
423
|
+
content: "";
|
|
424
|
+
position: absolute;
|
|
425
|
+
inset-block: 0;
|
|
426
|
+
inset-inline: 0;
|
|
427
|
+
z-index: var(--e-z-sticky);
|
|
428
|
+
width: min(100%, var(--e-shell-width, 72rem));
|
|
429
|
+
margin-inline: auto;
|
|
430
|
+
box-shadow:
|
|
431
|
+
calc(-1 * var(--e-stroke-hair)) 0 0 0 var(--e-shell-rail, var(--e-border)),
|
|
432
|
+
var(--e-stroke-hair) 0 0 0 var(--e-shell-rail, var(--e-border));
|
|
433
|
+
pointer-events: none;
|
|
434
434
|
}
|
|
435
435
|
@media (min-width: 48rem) {
|
|
436
436
|
.e-shell--side .e-shell-body {
|
|
@@ -720,7 +720,7 @@
|
|
|
720
720
|
animation: e-btn-spin 0.9s linear infinite;
|
|
721
721
|
}
|
|
722
722
|
|
|
723
|
-
/* 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
|
|
723
|
+
/* 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 edge is a pseudo-element, so a page's focus reset cannot remove it. */
|
|
724
724
|
.e-btn--loading {
|
|
725
725
|
--e-lift: 0px;
|
|
726
726
|
--e-tint: var(--e-fill);
|
|
@@ -1418,14 +1418,18 @@ to {
|
|
|
1418
1418
|
color: var(--e-muted);
|
|
1419
1419
|
}
|
|
1420
1420
|
|
|
1421
|
-
|
|
1422
|
-
|
|
1421
|
+
/* The hover fill is laid over the well, so it runs unbroken to the top edge. */
|
|
1422
|
+
.e-input:hover,
|
|
1423
|
+
.e-input-wrap:hover,
|
|
1424
|
+
.e-search:hover {
|
|
1425
|
+
box-shadow: inset 0 0 0 100vmax var(--e-over, var(--e-surface-hover));
|
|
1423
1426
|
}
|
|
1424
1427
|
|
|
1425
1428
|
.e-input:focus {
|
|
1426
1429
|
--e-ring: var(--e-focus-field);
|
|
1427
1430
|
|
|
1428
1431
|
background-color: var(--e-surface);
|
|
1432
|
+
box-shadow: var(--e-well);
|
|
1429
1433
|
}
|
|
1430
1434
|
|
|
1431
1435
|
/* A field's focus outline lies over its border and then reaches at least as far outside it again, so the field looks thicker on every stroke preset. */
|
|
@@ -1441,12 +1445,14 @@ to {
|
|
|
1441
1445
|
background-color: var(--e-surface);
|
|
1442
1446
|
}
|
|
1443
1447
|
|
|
1444
|
-
.e-input[aria-invalid="true"]:hover
|
|
1445
|
-
|
|
1448
|
+
.e-input[aria-invalid="true"]:hover,
|
|
1449
|
+
.e-input-wrap[data-invalid]:hover {
|
|
1450
|
+
--e-over: var(--e-danger-soft);
|
|
1446
1451
|
}
|
|
1447
1452
|
|
|
1448
1453
|
.e-input[aria-invalid="true"]:focus {
|
|
1449
1454
|
background-color: var(--e-surface);
|
|
1455
|
+
box-shadow: var(--e-well);
|
|
1450
1456
|
}
|
|
1451
1457
|
|
|
1452
1458
|
.e-input[aria-invalid="true"]:focus-visible {
|
|
@@ -1465,6 +1471,7 @@ to {
|
|
|
1465
1471
|
|
|
1466
1472
|
.e-input[readonly]:not(:disabled) {
|
|
1467
1473
|
background-color: var(--e-surface-tint);
|
|
1474
|
+
box-shadow: none;
|
|
1468
1475
|
}
|
|
1469
1476
|
|
|
1470
1477
|
.e-input-wrap {
|
|
@@ -1485,14 +1492,11 @@ to {
|
|
|
1485
1492
|
background-color var(--e-duration-tap) var(--e-easing-out);
|
|
1486
1493
|
}
|
|
1487
1494
|
|
|
1488
|
-
.e-input-wrap:hover {
|
|
1489
|
-
background: var(--e-surface-hover);
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
1495
|
.e-input-wrap:focus-within {
|
|
1493
1496
|
--e-ring: var(--e-focus-field);
|
|
1494
1497
|
|
|
1495
1498
|
background: var(--e-surface);
|
|
1499
|
+
box-shadow: var(--e-well);
|
|
1496
1500
|
outline: max(var(--e-stroke-focus), calc(2 * var(--e-stroke-edge))) solid var(--e-focus-field);
|
|
1497
1501
|
outline-offset: var(--e-focus-gap-field);
|
|
1498
1502
|
}
|
|
@@ -1503,12 +1507,9 @@ to {
|
|
|
1503
1507
|
background: var(--e-surface);
|
|
1504
1508
|
}
|
|
1505
1509
|
|
|
1506
|
-
.e-input-wrap[data-invalid]:hover {
|
|
1507
|
-
background: var(--e-danger-soft);
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
1510
|
.e-input-wrap[data-invalid]:focus-within {
|
|
1511
1511
|
background: var(--e-surface);
|
|
1512
|
+
box-shadow: var(--e-well);
|
|
1512
1513
|
outline-color: var(--e-danger);
|
|
1513
1514
|
}
|
|
1514
1515
|
|
|
@@ -1535,6 +1536,7 @@ to {
|
|
|
1535
1536
|
.e-input-wrap .e-input:hover,
|
|
1536
1537
|
.e-input-wrap .e-input:focus {
|
|
1537
1538
|
background: transparent;
|
|
1539
|
+
box-shadow: none;
|
|
1538
1540
|
}
|
|
1539
1541
|
|
|
1540
1542
|
.e-input-wrap .e-input:focus-visible {
|
|
@@ -4197,9 +4199,6 @@ to {
|
|
|
4197
4199
|
box-shadow: var(--e-well);
|
|
4198
4200
|
transition: border-color var(--e-duration-tap) var(--e-easing-out);
|
|
4199
4201
|
}
|
|
4200
|
-
.e-search:hover {
|
|
4201
|
-
background: var(--e-surface-hover);
|
|
4202
|
-
}
|
|
4203
4202
|
.e-search .e-btn {
|
|
4204
4203
|
position: relative;
|
|
4205
4204
|
height: calc(var(--e-control-height) - 6px);
|
|
@@ -4265,6 +4264,7 @@ to {
|
|
|
4265
4264
|
.e-search .e-input:focus {
|
|
4266
4265
|
border: 0;
|
|
4267
4266
|
background: transparent;
|
|
4267
|
+
box-shadow: none;
|
|
4268
4268
|
}
|
|
4269
4269
|
.e-search .e-input:focus-visible {
|
|
4270
4270
|
outline: none;
|
|
@@ -4995,7 +4995,7 @@ to {
|
|
|
4995
4995
|
padding-inline: max(0px, calc(var(--e-space-1) - var(--e-stroke-edge)));
|
|
4996
4996
|
}
|
|
4997
4997
|
|
|
4998
|
-
/* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab
|
|
4998
|
+
/* Vertical: the tabs stack beside the panel, flush and sharing edges. The selected tab's slab is a band down the inline-start side, and only the column's ends are rounded. */
|
|
4999
4999
|
.e-tabs--vertical {
|
|
5000
5000
|
display: flex;
|
|
5001
5001
|
align-items: flex-start;
|
|
@@ -5039,7 +5039,7 @@ to {
|
|
|
5039
5039
|
padding-top: 0;
|
|
5040
5040
|
}
|
|
5041
5041
|
|
|
5042
|
-
/* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it.
|
|
5042
|
+
/* Framed: tabs and panel are one outlined card. The tab row sits over the panel's edge by one stroke, so a tab's lower edge and the panel's upper edge are the same line; the chosen tab has no edge on that side and its fill covers the panel's, opening into it. Only the card's outer corner at the first tab is rounded. The row leaves a corner's width of open edge past the last tab, so the panel's curve never meets a tab's straight edge. */
|
|
5043
5043
|
.e-tabs--framed > .e-tablist {
|
|
5044
5044
|
position: relative;
|
|
5045
5045
|
z-index: var(--e-z-raised);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eos-ui/vue",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Eos: accessible Vue 3 components for the Eos portal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@eos-ui/tokens": "0.5.
|
|
60
|
+
"@eos-ui/tokens": "0.5.3",
|
|
61
61
|
"@tanstack/vue-table": "^9.3.1",
|
|
62
62
|
"@tanstack/vue-virtual": "^3.13.47",
|
|
63
63
|
"@vueuse/core": "^15.0.0",
|