From c70337d9c9f64446d917608436de727052a1c24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krystian=20Dro=C5=BCd=C5=BCy=C5=84ski?= Date: Wed, 26 Nov 2025 08:06:35 +0100 Subject: [PATCH] Expose `element` ref from styled component --- .changeset/old-pandas-lose.md | 5 +++++ packages/vue/src/Styled.ts | 12 ++++++++---- packages/vue/src/component.ts | 2 +- packages/vue/src/index.test.ts | 3 +++ 4 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 .changeset/old-pandas-lose.md diff --git a/.changeset/old-pandas-lose.md b/.changeset/old-pandas-lose.md new file mode 100644 index 0000000..ce2d6d0 --- /dev/null +++ b/.changeset/old-pandas-lose.md @@ -0,0 +1,5 @@ +--- +'@teiler/vue': patch +--- + +Expose `element` ref from styled component diff --git a/packages/vue/src/Styled.ts b/packages/vue/src/Styled.ts index 4cf2d04..7eabe8d 100644 --- a/packages/vue/src/Styled.ts +++ b/packages/vue/src/Styled.ts @@ -1,7 +1,7 @@ import type { HTMLElements, Sheet, StyleDefinition } from '@teiler/core' import { DefaultTheme, insert } from '@teiler/core' -import { defineComponent, h, inject, toRaw } from 'vue' +import { defineComponent, h, inject, ref, toRaw } from 'vue' import { context } from './ThemeProvider' import { getStyleSheet } from './sheet' @@ -9,11 +9,15 @@ export default function (styleDefinition: St const component = defineComponent({ inheritAttrs: false, styleDefinition, - setup() { + setup(_, { expose }) { const styleSheet: Sheet = getStyleSheet() const theme = inject(context, {}) - return { styleSheet, theme } + const element = ref(null) + + expose({ element }) + + return { styleSheet, theme, element } }, render() { const slots = this.$slots @@ -30,7 +34,7 @@ export default function (styleDefinition: St const defaultSlot = slots.default ? slots.default() : undefined if (styleDefinition.tag) { - return h(styleDefinition.tag, { ...filtredProps, class: className }, defaultSlot) + return h(styleDefinition.tag, { ...filtredProps, class: className, ref: 'element' }, defaultSlot) } else { return null } diff --git a/packages/vue/src/component.ts b/packages/vue/src/component.ts index eadd152..58fc0ee 100644 --- a/packages/vue/src/component.ts +++ b/packages/vue/src/component.ts @@ -7,7 +7,7 @@ import { component, global, keyframes, styled, tags } from '@teiler/core' type ElementAttributes = Target extends keyof IntrinsicElementAttributes ? IntrinsicElementAttributes[Target] : {} -type VueRawBindings = { styleSheet: Sheet; theme: DefaultTheme } +type VueRawBindings = { styleSheet: Sheet; theme: DefaultTheme; element: HTMLElement | null } type VueTeilerComponent = TeilerComponent & DefineComponent> const createComponent = (styleDefinition: StyleDefinition): VueTeilerComponent => { diff --git a/packages/vue/src/index.test.ts b/packages/vue/src/index.test.ts index 05dae0d..cacb7f9 100644 --- a/packages/vue/src/index.test.ts +++ b/packages/vue/src/index.test.ts @@ -64,6 +64,9 @@ describe('component', () => { setup: expect.any(Function), }) + expect(wrapper.vm.element).toBeDefined() + expect(wrapper.vm.element).not.toBeNull() + expect(wrapper.html()).toBe('
') })