@eos-ui/vue 0.5.0 → 0.5.1
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/PageHeader/EPageHeader.js.map +1 -1
- package/dist/components/PageHeader/EPageHeader.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 +26 -29
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EPageHeader.js","names":["_sfc_main","EPageHeader_vue_vue_type_script_setup_true_lang_default","EPageHeader_default"],"sources":["../../../src/components/PageHeader/EPageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EActions from \"../Actions/EActions.vue\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The page's title: where the person is, in their words (\"Visit on Oct 2\"). */\n title: string;\n /** A short line under the title. */\n description?: string;\n /** The heading level of the title, 1 by default. A page has exactly one h1; change it only when the header is not the page's title. */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n }>(),\n { headingLevel: 1 },\n);\n\ndefineSlots<{\n /** An EBreadcrumb above the title. */\n breadcrumb?(): unknown;\n /** An EStamp beside the title. */\n status?(): unknown;\n /** The page's Buttons, the main one first. */\n actions?(): unknown;\n}>();\n</script>\n\n<template>\n <div class=\"e-pagehead\">\n <slot name=\"breadcrumb\" />\n <div class=\"e-pagehead-row\">\n <div class=\"e-pagehead-text\">\n <div class=\"e-pagehead-titlerow\">\n <component :is=\"`h${headingLevel}`\" class=\"e-pagehead-title\">{{ title }}</component>\n <slot name=\"status\" />\n </div>\n <p v-if=\"description\" class=\"e-pagehead-desc\">{{ description }}</p>\n </div>\n <EActions v-if=\"$slots.actions\" class=\"e-pagehead-actions\"><slot name=\"actions\" /></EActions>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-pagehead {\n display: grid;\n gap: var(--e-space-3);\n margin-bottom: var(--e-space-6);\n }\n\n .e-pagehead-row {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--e-space-3) var(--e-space-4);\n }\n\n .e-pagehead-text {\n flex: 1 1 18rem;\n min-width: 0;\n }\n\n .e-pagehead-title {\n margin: 0;\n font: 500 var(--e-text-4xl) / 1.1 var(--e-font-sans);\n text-wrap: balance;\n }\n\n .e-pagehead-desc {\n margin: var(--e-space-2) 0 0;\n max-width: var(--e-measure);\n font: 400 var(--e-text-lg) / 1.45 var(--e-font-sans);\n color: var(--e-muted);\n }\n\n @media (max-width: 32rem) {\n .e-pagehead-title {\n font-size: var(--e-text-2xl);\n }\n }\n\n .e-pagehead-titlerow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-2) var(--e-space-4);\n }\n
|
|
1
|
+
{"version":3,"file":"EPageHeader.js","names":["_sfc_main","EPageHeader_vue_vue_type_script_setup_true_lang_default","EPageHeader_default"],"sources":["../../../src/components/PageHeader/EPageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EActions from \"../Actions/EActions.vue\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The page's title: where the person is, in their words (\"Visit on Oct 2\"). */\n title: string;\n /** A short line under the title. */\n description?: string;\n /** The heading level of the title, 1 by default. A page has exactly one h1; change it only when the header is not the page's title. */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n }>(),\n { headingLevel: 1 },\n);\n\ndefineSlots<{\n /** An EBreadcrumb above the title. */\n breadcrumb?(): unknown;\n /** An EStamp beside the title. */\n status?(): unknown;\n /** The page's Buttons, the main one first. */\n actions?(): unknown;\n}>();\n</script>\n\n<template>\n <div class=\"e-pagehead\">\n <slot name=\"breadcrumb\" />\n <div class=\"e-pagehead-row\">\n <div class=\"e-pagehead-text\">\n <div class=\"e-pagehead-titlerow\">\n <component :is=\"`h${headingLevel}`\" class=\"e-pagehead-title\">{{ title }}</component>\n <slot name=\"status\" />\n </div>\n <p v-if=\"description\" class=\"e-pagehead-desc\">{{ description }}</p>\n </div>\n <EActions v-if=\"$slots.actions\" class=\"e-pagehead-actions\"><slot name=\"actions\" /></EActions>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-pagehead {\n display: grid;\n gap: var(--e-space-3);\n margin-bottom: var(--e-space-6);\n }\n\n .e-pagehead-row {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--e-space-3) var(--e-space-4);\n }\n\n .e-pagehead-text {\n flex: 1 1 18rem;\n min-width: 0;\n }\n\n .e-pagehead-title {\n margin: 0;\n font: 500 var(--e-text-4xl) / 1.1 var(--e-font-sans);\n text-wrap: balance;\n }\n\n .e-pagehead-desc {\n margin: var(--e-space-2) 0 0;\n max-width: var(--e-measure);\n font: 400 var(--e-text-lg) / 1.45 var(--e-font-sans);\n color: var(--e-muted);\n }\n\n @media (max-width: 32rem) {\n .e-pagehead-title {\n font-size: var(--e-text-2xl);\n }\n }\n\n .e-pagehead-titlerow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-2) var(--e-space-4);\n }\n}\n</style>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EPageHeader.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_renderSlot","_createElementVNode","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","EActions","EActions_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","EPageHeader_vue_vue_type_script_setup_true_lang_default","openBlock","createElementBlock","renderSlot","_ctx","createElementVNode","createBlock","resolveDynamicComponent","__props","withCtx","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/PageHeader/EPageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EActions from \"../Actions/EActions.vue\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The page's title: where the person is, in their words (\"Visit on Oct 2\"). */\n title: string;\n /** A short line under the title. */\n description?: string;\n /** The heading level of the title, 1 by default. A page has exactly one h1; change it only when the header is not the page's title. */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n }>(),\n { headingLevel: 1 },\n);\n\ndefineSlots<{\n /** An EBreadcrumb above the title. */\n breadcrumb?(): unknown;\n /** An EStamp beside the title. */\n status?(): unknown;\n /** The page's Buttons, the main one first. */\n actions?(): unknown;\n}>();\n</script>\n\n<template>\n <div class=\"e-pagehead\">\n <slot name=\"breadcrumb\" />\n <div class=\"e-pagehead-row\">\n <div class=\"e-pagehead-text\">\n <div class=\"e-pagehead-titlerow\">\n <component :is=\"`h${headingLevel}`\" class=\"e-pagehead-title\">{{ title }}</component>\n <slot name=\"status\" />\n </div>\n <p v-if=\"description\" class=\"e-pagehead-desc\">{{ description }}</p>\n </div>\n <EActions v-if=\"$slots.actions\" class=\"e-pagehead-actions\"><slot name=\"actions\" /></EActions>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-pagehead {\n display: grid;\n gap: var(--e-space-3);\n margin-bottom: var(--e-space-6);\n }\n\n .e-pagehead-row {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--e-space-3) var(--e-space-4);\n }\n\n .e-pagehead-text {\n flex: 1 1 18rem;\n min-width: 0;\n }\n\n .e-pagehead-title {\n margin: 0;\n font: 500 var(--e-text-4xl) / 1.1 var(--e-font-sans);\n text-wrap: balance;\n }\n\n .e-pagehead-desc {\n margin: var(--e-space-2) 0 0;\n max-width: var(--e-measure);\n font: 400 var(--e-text-lg) / 1.45 var(--e-font-sans);\n color: var(--e-muted);\n }\n\n @media (max-width: 32rem) {\n .e-pagehead-title {\n font-size: var(--e-text-2xl);\n }\n }\n\n .e-pagehead-titlerow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-2) var(--e-space-4);\n }\n
|
|
1
|
+
{"version":3,"file":"EPageHeader.vue_vue_type_script_setup_true_lang.js","names":["$slots","_openBlock","_createElementBlock","_renderSlot","_createElementVNode","_createBlock","_resolveDynamicComponent","_withCtx","_createTextVNode","_toDisplayString","_createCommentVNode","EActions","EActions_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","EPageHeader_vue_vue_type_script_setup_true_lang_default","openBlock","createElementBlock","renderSlot","_ctx","createElementVNode","createBlock","resolveDynamicComponent","__props","withCtx","createTextVNode","toDisplayString","createCommentVNode"],"sources":["../../../src/components/PageHeader/EPageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport EActions from \"../Actions/EActions.vue\";\nimport \"../../styles/base.css\";\n\nwithDefaults(\n defineProps<{\n /** The page's title: where the person is, in their words (\"Visit on Oct 2\"). */\n title: string;\n /** A short line under the title. */\n description?: string;\n /** The heading level of the title, 1 by default. A page has exactly one h1; change it only when the header is not the page's title. */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n }>(),\n { headingLevel: 1 },\n);\n\ndefineSlots<{\n /** An EBreadcrumb above the title. */\n breadcrumb?(): unknown;\n /** An EStamp beside the title. */\n status?(): unknown;\n /** The page's Buttons, the main one first. */\n actions?(): unknown;\n}>();\n</script>\n\n<template>\n <div class=\"e-pagehead\">\n <slot name=\"breadcrumb\" />\n <div class=\"e-pagehead-row\">\n <div class=\"e-pagehead-text\">\n <div class=\"e-pagehead-titlerow\">\n <component :is=\"`h${headingLevel}`\" class=\"e-pagehead-title\">{{ title }}</component>\n <slot name=\"status\" />\n </div>\n <p v-if=\"description\" class=\"e-pagehead-desc\">{{ description }}</p>\n </div>\n <EActions v-if=\"$slots.actions\" class=\"e-pagehead-actions\"><slot name=\"actions\" /></EActions>\n </div>\n </div>\n</template>\n\n<style>\n@layer e.page {\n .e-pagehead {\n display: grid;\n gap: var(--e-space-3);\n margin-bottom: var(--e-space-6);\n }\n\n .e-pagehead-row {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--e-space-3) var(--e-space-4);\n }\n\n .e-pagehead-text {\n flex: 1 1 18rem;\n min-width: 0;\n }\n\n .e-pagehead-title {\n margin: 0;\n font: 500 var(--e-text-4xl) / 1.1 var(--e-font-sans);\n text-wrap: balance;\n }\n\n .e-pagehead-desc {\n margin: var(--e-space-2) 0 0;\n max-width: var(--e-measure);\n font: 400 var(--e-text-lg) / 1.45 var(--e-font-sans);\n color: var(--e-muted);\n }\n\n @media (max-width: 32rem) {\n .e-pagehead-title {\n font-size: var(--e-text-2xl);\n }\n }\n\n .e-pagehead-titlerow {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--e-space-2) var(--e-space-4);\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;E,kBA2BEC,EAAA,GAAAC,EAYM,OAZNW,GAYM,CAXJV,EAA0BmB,EAAA,QAAA,YAAA,GAC1BlB,EASM,OATNU,GASM,CARJV,EAMM,OANNW,GAMM,CALJX,EAGM,OAHNY,GAGM,EAFJf,EAAA,GAAAI,EAAoFC,EAAA,IAAhEoB,EAAA,cAAY,GAAA,EAAI,OAAM,mBAAkB,GAAA;GAAC,SAAAnB,QAAW,CAARC,EAAAC,EAAAiB,EAAA,KAAK,GAAA,CAAA,C;;E,KACrEvB,EAAsBmB,EAAA,QAAA,QAAA,C,IAEfI,EAAA,eAATzB,EAAA,GAAAC,EAAmE,KAAnEe,GAAmER,EAAlBiB,EAAA,WAAW,GAAA,CAAA,K,aAE9C1B,EAAAA,OAAO,WAAvBC,EAAA,GAAAI,EAA6FM,GAAA;;GAA7D,OAAM;;GAAqB,SAAAJ,QAAuB,CAAvBJ,EAAuBmB,EAAA,QAAA,SAAA,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-band: calc(var(--e-lift) + var(--e-stroke-edge));\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 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-bc);\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 box-shadow 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 background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\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-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: var(--e-space-1);\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-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n padding-block-end: 0;\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical .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-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-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-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset var(--e-band) 0 0 0 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 :dir(rtl) .e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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-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-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill .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-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-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block: var(--e-lift) 0;\n background-color: var(--e-surface);\n box-shadow:\n inset var(--e-stroke-edge) 0 0 0 var(--e-bc),\n inset calc(-1 * var(--e-stroke-edge)) 0 0 0 var(--e-bc),\n inset 0 var(--e-band) 0 0 var(--e-slab);\n }\n\n .e-tabs--framed .e-tabpanel {\n padding: var(--e-space-4);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-border-strong);\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-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset var(--e-band) 0 0 0 var(--e-slab);\n }\n\n :dir(rtl) .e-tabs--framed.e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\n }\n\n .e-tabs--framed.e-tabs--vertical .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: var(--e-space-4);\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-band: calc(var(--e-lift) + var(--e-stroke-edge));\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 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-bc);\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 box-shadow 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 background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\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: var(--e-space-1);\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 padding-block-end: 0;\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 padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset var(--e-band) 0 0 0 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 :dir(rtl) .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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: var(--e-lift) 0;\n background-color: var(--e-surface);\n box-shadow:\n inset var(--e-stroke-edge) 0 0 0 var(--e-bc),\n inset calc(-1 * var(--e-stroke-edge)) 0 0 0 var(--e-bc),\n inset 0 var(--e-band) 0 0 var(--e-slab);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: var(--e-space-4);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-border-strong);\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 padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset var(--e-band) 0 0 0 var(--e-slab);\n }\n\n :dir(rtl) .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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: var(--e-space-4);\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-band: calc(var(--e-lift) + var(--e-stroke-edge));\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 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-bc);\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 box-shadow 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 background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\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-tab {\n flex: 1 1 0;\n min-width: 0;\n justify-content: center;\n padding-inline: var(--e-space-1);\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-tab {\n --e-lift: 0px;\n\n height: var(--e-control-height);\n padding-block-end: 0;\n justify-content: flex-start;\n border-radius: 0;\n }\n\n .e-tabs--vertical .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-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-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-tab[aria-selected=\"true\"] {\n --e-lift: var(--e-depth);\n\n padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset var(--e-band) 0 0 0 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 :dir(rtl) .e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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-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-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--fill .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-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-tab[aria-selected=\"true\"] {\n --e-bc: var(--e-primary);\n --e-lift: var(--e-depth);\n\n padding-block: var(--e-lift) 0;\n background-color: var(--e-surface);\n box-shadow:\n inset var(--e-stroke-edge) 0 0 0 var(--e-bc),\n inset calc(-1 * var(--e-stroke-edge)) 0 0 0 var(--e-bc),\n inset 0 var(--e-band) 0 0 var(--e-slab);\n }\n\n .e-tabs--framed .e-tabpanel {\n padding: var(--e-space-4);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-border-strong);\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-tab {\n border-radius: 0;\n }\n\n .e-tabs--framed.e-tabs--vertical .e-tab:first-child {\n border-start-start-radius: var(--e-radius-md);\n }\n\n .e-tabs--framed.e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n margin-block: calc(-1 * var(--e-stroke-edge)) 0;\n padding-block: 0;\n padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset var(--e-band) 0 0 0 var(--e-slab);\n }\n\n :dir(rtl) .e-tabs--framed.e-tabs--vertical .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\n }\n\n .e-tabs--framed.e-tabs--vertical .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: var(--e-space-4);\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-band: calc(var(--e-lift) + var(--e-stroke-edge));\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 var(--e-space-4) var(--e-lift);\n border: 0;\n border-radius: 0;\n background: transparent;\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-bc);\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 box-shadow 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 background-color: color-mix(in srgb, var(--e-surface-tint), var(--e-ink) 3%);\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset 0 calc(-1 * var(--e-band)) 0 0 var(--e-slab);\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: var(--e-space-1);\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 padding-block-end: 0;\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 padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset var(--e-band) 0 0 0 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 :dir(rtl) .e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 0 0 var(--e-stroke-edge) var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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: var(--e-lift) 0;\n background-color: var(--e-surface);\n box-shadow:\n inset var(--e-stroke-edge) 0 0 0 var(--e-bc),\n inset calc(-1 * var(--e-stroke-edge)) 0 0 0 var(--e-bc),\n inset 0 var(--e-band) 0 0 var(--e-slab);\n }\n\n .e-tabs--framed > .e-tabpanel {\n padding: var(--e-space-4);\n border-radius: var(--e-radius-md);\n border-start-start-radius: 0;\n background: var(--e-surface);\n box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-border-strong);\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 padding-inline-start: calc(var(--e-space-4) + var(--e-lift));\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset var(--e-band) 0 0 0 var(--e-slab);\n }\n\n :dir(rtl) .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected=\"true\"] {\n box-shadow:\n inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),\n inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),\n inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);\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: var(--e-space-4);\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
|
@@ -3992,9 +3992,6 @@ a:any-link > .e-highlight {
|
|
|
3992
3992
|
align-items: center;
|
|
3993
3993
|
gap: var(--e-space-2) var(--e-space-4);
|
|
3994
3994
|
}
|
|
3995
|
-
.e-pagehead-titlerow > :not(.e-pagehead-title) {
|
|
3996
|
-
margin-top: var(--e-space-1);
|
|
3997
|
-
}
|
|
3998
3995
|
}
|
|
3999
3996
|
@layer e.reset, e.tokens, e.base, e.primitives, e.blocks, e.controls, e.composites, e.containers, e.page;
|
|
4000
3997
|
@layer e.composites {
|
|
@@ -4955,10 +4952,10 @@ to {
|
|
|
4955
4952
|
outline: var(--e-stroke-focus) solid var(--e-focus-ring);
|
|
4956
4953
|
outline-offset: var(--e-focus-gap);
|
|
4957
4954
|
}
|
|
4958
|
-
.e-tabs--fill .e-tablist {
|
|
4955
|
+
.e-tabs--fill > .e-tablist {
|
|
4959
4956
|
overflow-x: hidden;
|
|
4960
4957
|
}
|
|
4961
|
-
.e-tabs--fill .e-tab {
|
|
4958
|
+
.e-tabs--fill > .e-tablist > .e-tab {
|
|
4962
4959
|
flex: 1 1 0;
|
|
4963
4960
|
min-width: 0;
|
|
4964
4961
|
justify-content: center;
|
|
@@ -4971,12 +4968,12 @@ to {
|
|
|
4971
4968
|
align-items: flex-start;
|
|
4972
4969
|
gap: var(--e-space-4);
|
|
4973
4970
|
}
|
|
4974
|
-
.e-tabs--vertical .e-tablist {
|
|
4971
|
+
.e-tabs--vertical > .e-tablist {
|
|
4975
4972
|
flex-direction: column;
|
|
4976
4973
|
flex: none;
|
|
4977
4974
|
overflow: visible;
|
|
4978
4975
|
}
|
|
4979
|
-
.e-tabs--vertical .e-tab {
|
|
4976
|
+
.e-tabs--vertical > .e-tablist > .e-tab {
|
|
4980
4977
|
--e-lift: 0px;
|
|
4981
4978
|
|
|
4982
4979
|
height: var(--e-control-height);
|
|
@@ -4984,19 +4981,19 @@ to {
|
|
|
4984
4981
|
justify-content: flex-start;
|
|
4985
4982
|
border-radius: 0;
|
|
4986
4983
|
}
|
|
4987
|
-
.e-tabs--vertical .e-tab:first-child {
|
|
4984
|
+
.e-tabs--vertical > .e-tablist > .e-tab:first-child {
|
|
4988
4985
|
border-start-start-radius: var(--e-radius-md);
|
|
4989
4986
|
border-start-end-radius: var(--e-radius-md);
|
|
4990
4987
|
}
|
|
4991
|
-
.e-tabs--vertical .e-tab:last-child {
|
|
4988
|
+
.e-tabs--vertical > .e-tablist > .e-tab:last-child {
|
|
4992
4989
|
border-end-start-radius: var(--e-radius-md);
|
|
4993
4990
|
border-end-end-radius: var(--e-radius-md);
|
|
4994
4991
|
}
|
|
4995
|
-
.e-tabs--vertical .e-tab + .e-tab {
|
|
4992
|
+
.e-tabs--vertical > .e-tablist > .e-tab + .e-tab {
|
|
4996
4993
|
margin-inline-start: 0;
|
|
4997
4994
|
margin-block-start: calc(-1 * var(--e-stroke-edge));
|
|
4998
4995
|
}
|
|
4999
|
-
.e-tabs--vertical .e-tab[aria-selected="true"] {
|
|
4996
|
+
.e-tabs--vertical > .e-tablist > .e-tab[aria-selected="true"] {
|
|
5000
4997
|
--e-lift: var(--e-depth);
|
|
5001
4998
|
|
|
5002
4999
|
padding-inline-start: calc(var(--e-space-4) + var(--e-lift));
|
|
@@ -5004,45 +5001,45 @@ to {
|
|
|
5004
5001
|
inset 0 0 0 var(--e-stroke-edge) var(--e-bc),
|
|
5005
5002
|
inset var(--e-band) 0 0 0 var(--e-slab);
|
|
5006
5003
|
}
|
|
5007
|
-
.e-tabs--vertical .e-tabpanel {
|
|
5004
|
+
.e-tabs--vertical > .e-tabpanel {
|
|
5008
5005
|
flex: 1 1 0;
|
|
5009
5006
|
min-width: 0;
|
|
5010
5007
|
padding-top: 0;
|
|
5011
5008
|
}
|
|
5012
|
-
:dir(rtl) .e-tabs--vertical .e-tab[aria-selected="true"] {
|
|
5009
|
+
:dir(rtl) .e-tabs--vertical > .e-tablist > .e-tab[aria-selected="true"] {
|
|
5013
5010
|
box-shadow:
|
|
5014
5011
|
inset 0 0 0 var(--e-stroke-edge) var(--e-bc),
|
|
5015
5012
|
inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);
|
|
5016
5013
|
}
|
|
5017
5014
|
|
|
5018
5015
|
/* 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. */
|
|
5019
|
-
.e-tabs--framed .e-tablist {
|
|
5016
|
+
.e-tabs--framed > .e-tablist {
|
|
5020
5017
|
position: relative;
|
|
5021
5018
|
z-index: var(--e-z-raised);
|
|
5022
5019
|
margin-block-end: calc(-1 * var(--e-stroke-edge));
|
|
5023
5020
|
}
|
|
5024
|
-
.e-tabs--framed .e-tab {
|
|
5021
|
+
.e-tabs--framed > .e-tablist > .e-tab {
|
|
5025
5022
|
--e-bc: var(--e-border-strong);
|
|
5026
5023
|
--e-lift: 0px;
|
|
5027
5024
|
|
|
5028
5025
|
border-radius: 0;
|
|
5029
5026
|
background-color: var(--e-surface-tint);
|
|
5030
5027
|
}
|
|
5031
|
-
.e-tabs--framed .e-tab:first-child {
|
|
5028
|
+
.e-tabs--framed > .e-tablist > .e-tab:first-child {
|
|
5032
5029
|
border-start-start-radius: var(--e-radius-md);
|
|
5033
5030
|
}
|
|
5034
|
-
.e-tabs--framed.e-tabs--fill .e-tab:last-child {
|
|
5031
|
+
.e-tabs--framed.e-tabs--fill > .e-tablist > .e-tab:last-child {
|
|
5035
5032
|
border-start-end-radius: var(--e-radius-md);
|
|
5036
5033
|
}
|
|
5037
|
-
.e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed .e-tablist {
|
|
5034
|
+
.e-tabs:not(.e-tabs--fill, .e-tabs--vertical).e-tabs--framed > .e-tablist {
|
|
5038
5035
|
padding-inline-end: var(--e-radius-md);
|
|
5039
5036
|
}
|
|
5040
|
-
.e-tabs--framed .e-tab:hover {
|
|
5037
|
+
.e-tabs--framed > .e-tablist > .e-tab:hover {
|
|
5041
5038
|
background-color: var(--e-surface-hover);
|
|
5042
5039
|
}
|
|
5043
5040
|
|
|
5044
5041
|
/* 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. */
|
|
5045
|
-
.e-tabs--framed .e-tab[aria-selected="true"] {
|
|
5042
|
+
.e-tabs--framed > .e-tablist > .e-tab[aria-selected="true"] {
|
|
5046
5043
|
--e-bc: var(--e-primary);
|
|
5047
5044
|
--e-lift: var(--e-depth);
|
|
5048
5045
|
|
|
@@ -5053,32 +5050,32 @@ to {
|
|
|
5053
5050
|
inset calc(-1 * var(--e-stroke-edge)) 0 0 0 var(--e-bc),
|
|
5054
5051
|
inset 0 var(--e-band) 0 0 var(--e-slab);
|
|
5055
5052
|
}
|
|
5056
|
-
.e-tabs--framed .e-tabpanel {
|
|
5053
|
+
.e-tabs--framed > .e-tabpanel {
|
|
5057
5054
|
padding: var(--e-space-4);
|
|
5058
5055
|
border-radius: var(--e-radius-md);
|
|
5059
5056
|
border-start-start-radius: 0;
|
|
5060
5057
|
background: var(--e-surface);
|
|
5061
5058
|
box-shadow: inset 0 0 0 var(--e-stroke-edge) var(--e-border-strong);
|
|
5062
5059
|
}
|
|
5063
|
-
.e-tabs--framed.e-tabs--fill .e-tabpanel {
|
|
5060
|
+
.e-tabs--framed.e-tabs--fill > .e-tabpanel {
|
|
5064
5061
|
border-start-end-radius: 0;
|
|
5065
5062
|
}
|
|
5066
5063
|
.e-tabs--framed.e-tabs--vertical {
|
|
5067
5064
|
gap: 0;
|
|
5068
5065
|
align-items: stretch;
|
|
5069
5066
|
}
|
|
5070
|
-
.e-tabs--framed.e-tabs--vertical .e-tablist {
|
|
5067
|
+
.e-tabs--framed.e-tabs--vertical > .e-tablist {
|
|
5071
5068
|
align-self: flex-start;
|
|
5072
5069
|
margin-block-end: var(--e-radius-md);
|
|
5073
5070
|
margin-inline-end: calc(-1 * var(--e-stroke-edge));
|
|
5074
5071
|
}
|
|
5075
|
-
.e-tabs--framed.e-tabs--vertical .e-tab {
|
|
5072
|
+
.e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab {
|
|
5076
5073
|
border-radius: 0;
|
|
5077
5074
|
}
|
|
5078
|
-
.e-tabs--framed.e-tabs--vertical .e-tab:first-child {
|
|
5075
|
+
.e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab:first-child {
|
|
5079
5076
|
border-start-start-radius: var(--e-radius-md);
|
|
5080
5077
|
}
|
|
5081
|
-
.e-tabs--framed.e-tabs--vertical .e-tab[aria-selected="true"] {
|
|
5078
|
+
.e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected="true"] {
|
|
5082
5079
|
margin-block: calc(-1 * var(--e-stroke-edge)) 0;
|
|
5083
5080
|
padding-block: 0;
|
|
5084
5081
|
padding-inline-start: calc(var(--e-space-4) + var(--e-lift));
|
|
@@ -5087,16 +5084,16 @@ to {
|
|
|
5087
5084
|
inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),
|
|
5088
5085
|
inset var(--e-band) 0 0 0 var(--e-slab);
|
|
5089
5086
|
}
|
|
5090
|
-
:dir(rtl) .e-tabs--framed.e-tabs--vertical .e-tab[aria-selected="true"] {
|
|
5087
|
+
:dir(rtl) .e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected="true"] {
|
|
5091
5088
|
box-shadow:
|
|
5092
5089
|
inset 0 var(--e-stroke-edge) 0 0 var(--e-bc),
|
|
5093
5090
|
inset 0 calc(-1 * var(--e-stroke-edge)) 0 0 var(--e-bc),
|
|
5094
5091
|
inset calc(-1 * var(--e-band)) 0 0 0 var(--e-slab);
|
|
5095
5092
|
}
|
|
5096
|
-
.e-tabs--framed.e-tabs--vertical .e-tab[aria-selected="true"]:first-child {
|
|
5093
|
+
.e-tabs--framed.e-tabs--vertical > .e-tablist > .e-tab[aria-selected="true"]:first-child {
|
|
5097
5094
|
margin-block-start: 0;
|
|
5098
5095
|
}
|
|
5099
|
-
.e-tabs--framed.e-tabs--vertical .e-tabpanel {
|
|
5096
|
+
.e-tabs--framed.e-tabs--vertical > .e-tabpanel {
|
|
5100
5097
|
padding: var(--e-space-4);
|
|
5101
5098
|
}
|
|
5102
5099
|
.e-tab-count {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eos-ui/vue",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
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.1",
|
|
61
61
|
"@tanstack/vue-table": "^9.3.1",
|
|
62
62
|
"@tanstack/vue-virtual": "^3.13.47",
|
|
63
63
|
"@vueuse/core": "^15.0.0",
|