11<script setup lang="ts">
2- import { useCssModule , computed } from ' vue' ;
2+ import { useCssModule , computed , ref , onMounted , nextTick } from ' vue' ;
33import type { ObjectOverlayProps } from ' ../../types/interfaces' ;
44
55/** Component for positioning content in 9 different positions relative to a container */
@@ -10,9 +10,31 @@ const props = withDefaults(defineProps<ObjectOverlayProps>(), {
1010 position: ' center-center' ,
1111 margin: ' zero' ,
1212 tag: ' div' ,
13+ gradientTheme: ' dark'
1314});
1415
15- // Helper function to process component properties (position, gradient)
16+ // Refs for DOM elements
17+ const containerRef = ref <HTMLElement | null >(null );
18+ const overlayRef = ref <HTMLElement | null >(null );
19+
20+ // Helper function to determine gradient direction based on position
21+ const getGradientDirection = (position : string ): string | null => {
22+ if (position === ' center-center' ) return null ;
23+
24+ if ([' left-top' , ' center-top' , ' right-top' ].includes (position )) {
25+ return ' to-bottom' ;
26+ } else if (position === ' left-center' ) {
27+ return ' to-right' ;
28+ } else if (position === ' right-center' ) {
29+ return ' to-left' ;
30+ } else if ([' left-bottom' , ' center-bottom' , ' right-bottom' ].includes (position )) {
31+ return ' to-top' ;
32+ }
33+
34+ return null ;
35+ };
36+
37+ // Helper function to process component properties (position, withGradient)
1638const processComponentProperty = (property : string , prop : any ): Record <string , string > => {
1739 const result: Record <string , string > = {};
1840
@@ -71,13 +93,38 @@ const attrs = computed(() => {
7193 const component: Record <string , string > = {};
7294 const content: Record <string , any > = { style: {} };
7395
74- // Process component properties
75- [' position' , ' gradient' ].forEach ((property ) => {
76- const prop = props [property as keyof typeof props ];
77- if (prop ) {
78- Object .assign (component , processComponentProperty (property , prop ));
96+ // Process position property
97+ if (props .position ) {
98+ Object .assign (component , processComponentProperty (' position' , props .position ));
99+ }
100+
101+ // Process gradient based on position if withGradient is true
102+ if (props .withGradient ) {
103+ // Set gradient theme
104+ if (props .gradientTheme ) {
105+ component [' data-gradient-theme' ] = props .gradientTheme ;
79106 }
80- });
107+
108+ // For responsive positions, we need to determine gradient for each breakpoint
109+ if (typeof props .position === ' object' ) {
110+ Object .entries (props .position ).forEach (([mq , pos ]) => {
111+ const direction = getGradientDirection (pos as string );
112+ if (direction ) {
113+ if (mq === ' xs' ) {
114+ component [' data-gradient' ] = direction ;
115+ } else {
116+ component [` data-gradient-${mq } ` ] = direction ;
117+ }
118+ }
119+ });
120+ } else {
121+ // For single position value
122+ const direction = getGradientDirection (props .position as string );
123+ if (direction ) {
124+ component [' data-gradient' ] = direction ;
125+ }
126+ }
127+ }
81128
82129 // Process content properties
83130 [' margin' , ' padding' ].forEach ((property ) => {
@@ -97,6 +144,59 @@ const attrs = computed(() => {
97144 };
98145});
99146
147+ // Function to inherit border radius from container
148+ const inheritBorderRadius = () => {
149+ if (! containerRef .value || ! overlayRef .value ) return ;
150+
151+ // Get the first child of the container (the actual content element)
152+ const containerContent = containerRef .value .firstElementChild as HTMLElement ;
153+ if (! containerContent ) return ;
154+
155+ requestAnimationFrame (() => {
156+ // Get computed style of the container content
157+ const computedStyle = window .getComputedStyle (containerContent );
158+ const borderRadius = computedStyle .borderRadius ;
159+
160+ if (! overlayRef .value ) return ;
161+
162+ // Apply the same border radius to the overlay component
163+ if (borderRadius && borderRadius !== ' 0px' ) {
164+ overlayRef .value .style .borderRadius = borderRadius ;
165+ } else {
166+ // Try to get border-radius from individual properties if the shorthand is not set
167+ const topLeft = computedStyle .borderTopLeftRadius ;
168+ const topRight = computedStyle .borderTopRightRadius ;
169+ const bottomLeft = computedStyle .borderBottomLeftRadius ;
170+ const bottomRight = computedStyle .borderBottomRightRadius ;
171+
172+ if (
173+ topLeft !== ' 0px' || topRight !== ' 0px' || bottomLeft !== ' 0px' || bottomRight !== ' 0px'
174+ ) {
175+ overlayRef .value .style .borderTopLeftRadius = topLeft ;
176+ overlayRef .value .style .borderTopRightRadius = topRight ;
177+ overlayRef .value .style .borderBottomLeftRadius = bottomLeft ;
178+ overlayRef .value .style .borderBottomRightRadius = bottomRight ;
179+ }
180+ }
181+ }); // Small delay to ensure styles are applied
182+ };
183+
184+ // Apply border radius after component is mounted and when it updates
185+ onMounted (() => {
186+ nextTick (inheritBorderRadius );
187+
188+ // Set up MutationObserver to detect when children are added/changed
189+ if (containerRef .value ) {
190+ const observer = new MutationObserver (inheritBorderRadius );
191+ observer .observe (containerRef .value , {
192+ childList: true ,
193+ subtree: true ,
194+ attributes: true ,
195+ attributeFilter: [' style' , ' class' ]
196+ });
197+ }
198+ });
199+
100200const styles = useCssModule ();
101201 </script >
102202
@@ -105,8 +205,12 @@ const styles = useCssModule();
105205 :is =" tag"
106206 :class =" styles['cdr-object-overlay']"
107207 v-bind =" attrs.component"
208+ ref =" overlayRef"
108209 >
109- <div :class =" styles['cdr-object-overlay__container']" >
210+ <div
211+ :class =" styles['cdr-object-overlay__container']"
212+ ref =" containerRef"
213+ >
110214 <!-- @slot Container content that the overlay will be positioned relative to -->
111215 <slot name =" container" />
112216 </div >
0 commit comments