srcdev-nuxt-components 9.4.9 → 9.4.10
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/.claude/commands/migrate-component.md +20 -6
- package/.claude/component-ledger/audit.json +1 -1
- package/.claude/component-ledger/build.mjs +26 -0
- package/.claude/component-ledger/output.html +8 -3
- package/.claude/component-ledger/template.html +7 -2
- package/.claude/skills/component-dynamic-slots.md +1 -1
- package/.claude/skills/components/alert-mask-core.md +84 -0
- package/.claude/skills/components/canvas-switcher.md +1 -1
- package/.claude/skills/components/carousel-flip.md +112 -168
- package/.claude/skills/components/container-glow.md +123 -0
- package/.claude/skills/components/dashboard-quad-grid.md +98 -0
- package/.claude/skills/components/dashboard-stats-grid.md +103 -0
- package/.claude/skills/components/display-theme-switch.md +60 -0
- package/.claude/skills/components/glowing-border.md +66 -0
- package/.claude/skills/components/input-range-core.md +142 -0
- package/.claude/skills/components/section-parallax.md +32 -10
- package/.claude/skills/components/ui-block-decorated.md +56 -0
- package/.claude/skills/components/wipe-away-vertical.md +98 -0
- package/.claude/skills/icon-sets.md +1 -1
- package/.claude/skills/index.md +10 -1
- package/.vscode/css-custom-data.json +38 -0
- package/.vscode/settings.json +3 -0
- package/.vscode/srcdev-component-alert-mask-core.code-snippets +31 -0
- package/.vscode/srcdev-component-carousel-flip.code-snippets +41 -0
- package/.vscode/srcdev-component-container-glow.code-snippets +33 -0
- package/.vscode/srcdev-component-dashboard-quad-grid.code-snippets +36 -0
- package/.vscode/srcdev-component-dashboard-stats-grid.code-snippets +35 -0
- package/.vscode/srcdev-component-display-theme-switch.code-snippets +27 -0
- package/.vscode/srcdev-component-glowing-border.code-snippets +23 -0
- package/.vscode/srcdev-component-input-range.code-snippets +85 -0
- package/.vscode/srcdev-component-section-parallax.code-snippets +27 -0
- package/.vscode/srcdev-component-ui-block-decorated.code-snippets +24 -0
- package/.vscode/srcdev-component-wipe-away-vertical.code-snippets +25 -0
- package/README.md +18 -37
- package/app/components/{alert-mask → 01.atoms/alert-mask}/AlertMaskCore.vue +16 -17
- package/app/components/01.atoms/alert-mask/CONSUMER-STYLING.md +46 -0
- package/app/components/01.atoms/alert-mask/stories/AlertMaskCore.stories.ts +79 -0
- package/app/components/{alert-mask → 01.atoms/alert-mask}/tests/AlertMaskCore.spec.ts +10 -10
- package/app/components/01.atoms/animations/container-glow/CONSUMER-STYLING.md +86 -0
- package/app/components/01.atoms/animations/container-glow/ContainerGlow.vue +299 -0
- package/app/components/01.atoms/animations/container-glow/stories/ContainerGlow.stories.ts +175 -0
- package/app/components/01.atoms/animations/container-glow/tests/ContainerGlow.spec.ts +131 -0
- package/app/components/01.atoms/animations/container-glow/tests/__snapshots__/ContainerGlow.spec.ts.snap +14 -0
- package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +61 -0
- package/app/components/01.atoms/animations/glowing-border/GlowingBorder.vue +132 -0
- package/app/components/01.atoms/animations/glowing-border/stories/GlowingBorder.stories.ts +165 -0
- package/app/components/01.atoms/animations/glowing-border/tests/GlowingBorder.spec.ts +94 -0
- package/app/components/01.atoms/animations/glowing-border/tests/__snapshots__/GlowingBorder.spec.ts.snap +3 -0
- package/app/components/01.atoms/animations/section-parallax/CONSUMER-STYLING.md +44 -0
- package/app/components/{parallax → 01.atoms/animations/section-parallax}/SectionParallax.vue +11 -10
- package/app/components/01.atoms/animations/section-parallax/stories/SectionParallax.stories.ts +98 -0
- package/app/components/01.atoms/animations/section-parallax/tests/SectionParallax.spec.ts +102 -0
- package/app/components/01.atoms/animations/section-parallax/tests/__snapshots__/SectionParallax.spec.ts.snap +9 -0
- package/app/components/01.atoms/animations/view-timeline/CONSUMER-STYLING.md +70 -0
- package/app/components/01.atoms/animations/view-timeline/WipeAwayVertical.vue +181 -0
- package/app/components/01.atoms/animations/view-timeline/stories/WipeAwayVertical.stories.ts +269 -0
- package/app/components/01.atoms/animations/view-timeline/tests/WipeAwayVertical.spec.ts +127 -0
- package/app/components/01.atoms/canvas-switcher/CONSUMER-STYLING.md +1 -1
- package/app/components/01.atoms/canvas-switcher/stories/CanvasSwitcher.stories.ts +1 -1
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/CONSUMER-STYLING.md +42 -0
- package/app/components/{layout-grids/LayoutGridA.vue → 01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/DashboardQuadGrid.vue} +23 -13
- package/app/components/{layout-grids/stories/LayoutGridA.stories.ts → 01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/stories/DashboardQuadGrid.stories.ts} +151 -23
- package/app/components/{layout-grids/tests/LayoutGridA.spec.ts → 01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/tests/DashboardQuadGrid.spec.ts} +25 -25
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/CONSUMER-STYLING.md +41 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/DashboardStatsGrid.vue +133 -0
- package/app/components/{layout-grids/stories/LayoutGridB.stories.ts → 01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/stories/DashboardStatsGrid.stories.ts} +24 -24
- package/app/components/{layout-grids/tests/LayoutGridB.spec.ts → 01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/tests/DashboardStatsGrid.spec.ts} +23 -23
- package/app/components/01.atoms/ui-block-decorated/CONSUMER-STYLING.md +39 -0
- package/app/components/01.atoms/ui-block-decorated/UiBlockDecorated.vue +141 -0
- package/app/components/01.atoms/ui-block-decorated/stories/UiBlockDecorated.stories.ts +148 -0
- package/app/components/01.atoms/ui-block-decorated/tests/UiBlockDecorated.spec.ts +80 -0
- package/app/components/01.atoms/ui-block-decorated/tests/__snapshots__/UiBlockDecorated.spec.ts.snap +3 -0
- package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +6 -6
- package/app/components/02.molecules/display-theme-switch/CONSUMER-STYLING.md +34 -0
- package/app/components/02.molecules/display-theme-switch/DisplayThemeSwitch.vue +102 -0
- package/app/components/02.molecules/display-theme-switch/stories/DisplayThemeSwitch.stories.ts +115 -0
- package/app/components/02.molecules/display-theme-switch/tests/DisplayThemeSwitch.spec.ts +86 -0
- package/app/components/03.organisms/image-galleries/carousel-flip/CONSUMER-STYLING.md +46 -0
- package/app/components/{carousels → 03.organisms/image-galleries/carousel-flip}/CarouselFlip.vue +63 -42
- package/app/components/{carousels → 03.organisms/image-galleries/carousel-flip}/stories/CarouselFlip.stories.ts +96 -11
- package/app/components/{carousels → 03.organisms/image-galleries/carousel-flip}/tests/CarouselFlip.spec.ts +80 -0
- package/app/components/05.forms/form-field/FormField.vue +1 -1
- package/app/components/05.forms/form-wrapper/FormWrapper.vue +1 -1
- package/app/components/05.forms/input-range/CONSUMER-STYLING.md +45 -0
- package/app/components/05.forms/input-range/InputRangeCore.vue +79 -143
- package/app/components/05.forms/input-range/stories/InputRangeCore.stories.ts +126 -0
- package/app/components/05.forms/input-range/tests/InputRangeCore.spec.ts +124 -0
- package/app/components/05.forms/input-range/variants/InputRangeDefault.vue +9 -32
- package/app/components/05.forms/input-range/variants/stories/InputRangeDefault.stories.ts +108 -0
- package/app/components/05.forms/input-range/variants/tests/InputRangeDefault.spec.ts +140 -0
- package/app/components/05.forms/patterns/stories/MigratedFieldsForm.stories.ts +135 -0
- package/app/components/05.forms/triple-toggle-switch/CONSUMER-STYLING.md +16 -2
- package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +6 -4
- package/app/types/components/container-glow.d.ts +8 -0
- package/app/types/components/index.ts +1 -1
- package/package.json +3 -2
- package/app/components/05.forms/input-range-fancy/InputRangeFancyCore.vue +0 -426
- package/app/components/05.forms/input-range-fancy/InputRangeFancyWithLabel.vue +0 -94
- package/app/components/carousels/CarouselBasic.vue +0 -317
- package/app/components/carousels/CarouselInfinite.vue +0 -358
- package/app/components/container-glow/ContainerGlowCore.vue +0 -296
- package/app/components/container-glow/stories/ContainerGlowCore.stories.ts +0 -337
- package/app/components/display-theme-switch/DisplayThemeSwitch.vue +0 -189
- package/app/components/display-theme-switch/stories/DisplayThemeSwitch.stories.ts +0 -154
- package/app/components/glowing-border/GlowingBorder.vue +0 -142
- package/app/components/glowing-border/stories/GlowingBorder.stories.ts +0 -141
- package/app/components/layout-grids/LayoutGridB.vue +0 -134
- package/app/components/test-storybook/TestStorybook.vue +0 -49
- package/app/components/test-storybook/stories/TestStorybook.stories.ts +0 -28
- package/app/components/ui-block-decorated/UiBlockDecorated.vue +0 -167
- package/app/components/view-timeline/WipeAwayVertical.vue +0 -180
- package/app/types/components/carousel-basic.d.ts +0 -19
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div ref="containerGlowWrapper" class="container-glow-wrapper" :class="elementClasses">
|
|
3
|
-
<component
|
|
4
|
-
:is="tag"
|
|
5
|
-
v-for="(_, name) in $slots"
|
|
6
|
-
:key="name"
|
|
7
|
-
ref="containerGlowItem"
|
|
8
|
-
class="container-glow-core"
|
|
9
|
-
>
|
|
10
|
-
<div class="glows"></div>
|
|
11
|
-
<slot :name="name"></slot>
|
|
12
|
-
</component>
|
|
13
|
-
</div>
|
|
14
|
-
</template>
|
|
15
|
-
|
|
16
|
-
<script setup lang="ts">
|
|
17
|
-
interface Config {
|
|
18
|
-
proximity: number;
|
|
19
|
-
spread: number;
|
|
20
|
-
blur: number;
|
|
21
|
-
gap: number;
|
|
22
|
-
vertical: boolean;
|
|
23
|
-
inactiveOpacity: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface Props {
|
|
27
|
-
tag?: string;
|
|
28
|
-
config?: Config;
|
|
29
|
-
styleClassPassthrough?: string | string[];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
33
|
-
tag: "div",
|
|
34
|
-
config: () => ({
|
|
35
|
-
proximity: 40,
|
|
36
|
-
spread: 80,
|
|
37
|
-
blur: 20,
|
|
38
|
-
gap: 32,
|
|
39
|
-
vertical: false,
|
|
40
|
-
inactiveOpacity: 0,
|
|
41
|
-
}),
|
|
42
|
-
styleClassPassthrough: () => [],
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
|
|
46
|
-
|
|
47
|
-
const controller = new AbortController();
|
|
48
|
-
|
|
49
|
-
const containerGlowWrapper = ref<HTMLElement>();
|
|
50
|
-
const containerGlowItem = ref<HTMLElement[]>([]);
|
|
51
|
-
|
|
52
|
-
// Cache frequently used values to avoid repeated access
|
|
53
|
-
const configCache = computed(() => ({
|
|
54
|
-
proximity: props.config.proximity,
|
|
55
|
-
inactiveOpacityStr: String(props.config.inactiveOpacity),
|
|
56
|
-
gapStr: String(props.config.gap),
|
|
57
|
-
blurStr: String(props.config.blur),
|
|
58
|
-
spreadStr: String(props.config.spread),
|
|
59
|
-
direction: props.config.vertical ? "column" : "row",
|
|
60
|
-
}));
|
|
61
|
-
|
|
62
|
-
// Pre-calculate constants to avoid repeated calculations
|
|
63
|
-
const ANGLE_OFFSET = 90;
|
|
64
|
-
const FULL_CIRCLE = 360;
|
|
65
|
-
const RAD_TO_DEG = 180 / Math.PI;
|
|
66
|
-
|
|
67
|
-
// Throttle mechanism using RAF
|
|
68
|
-
let rafId: number | null = null;
|
|
69
|
-
let lastEventData: { x: number; y: number } | null = null;
|
|
70
|
-
|
|
71
|
-
const updateStyles = (event: PointerEvent) => {
|
|
72
|
-
// Early return if event coordinates are not available
|
|
73
|
-
if (typeof event.x !== "number" || typeof event.y !== "number") {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Store event data and schedule update
|
|
78
|
-
lastEventData = { x: event.x, y: event.y };
|
|
79
|
-
|
|
80
|
-
if (rafId !== null) {
|
|
81
|
-
return; // Already scheduled
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
rafId = requestAnimationFrame(() => {
|
|
85
|
-
if (!lastEventData) {
|
|
86
|
-
rafId = null;
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const { x: eventX, y: eventY } = lastEventData;
|
|
91
|
-
const { proximity, inactiveOpacityStr } = configCache.value;
|
|
92
|
-
|
|
93
|
-
// Process all elements
|
|
94
|
-
for (const cardElem of containerGlowItem.value) {
|
|
95
|
-
// Check the card against the proximity and then start updating
|
|
96
|
-
const cardBounds = cardElem.getBoundingClientRect();
|
|
97
|
-
|
|
98
|
-
// Pre-calculate bounds to avoid repeated operations
|
|
99
|
-
const leftBound = cardBounds.left - proximity;
|
|
100
|
-
const rightBound = cardBounds.left + cardBounds.width + proximity;
|
|
101
|
-
const topBound = cardBounds.top - proximity;
|
|
102
|
-
const bottomBound = cardBounds.top + cardBounds.height + proximity;
|
|
103
|
-
|
|
104
|
-
// Check proximity with pre-calculated bounds
|
|
105
|
-
const isInProximity = eventX > leftBound && eventX < rightBound && eventY > topBound && eventY < bottomBound;
|
|
106
|
-
|
|
107
|
-
// Set opacity based on proximity
|
|
108
|
-
cardElem.style.setProperty("--opacity-active", isInProximity ? "1" : inactiveOpacityStr);
|
|
109
|
-
|
|
110
|
-
if (isInProximity) {
|
|
111
|
-
// Only calculate angle when in proximity
|
|
112
|
-
const cardCentreX = cardBounds.left + cardBounds.width * 0.5;
|
|
113
|
-
const cardCentreY = cardBounds.top + cardBounds.height * 0.5;
|
|
114
|
-
|
|
115
|
-
let angle = Math.atan2(eventY - cardCentreY, eventX - cardCentreX) * RAD_TO_DEG;
|
|
116
|
-
angle = angle < 0 ? angle + FULL_CIRCLE : angle;
|
|
117
|
-
|
|
118
|
-
cardElem.style.setProperty("--start", String(angle + ANGLE_OFFSET));
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
rafId = null;
|
|
123
|
-
});
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const applyStyles = () => {
|
|
127
|
-
if (!containerGlowWrapper.value) return;
|
|
128
|
-
|
|
129
|
-
const { gapStr, blurStr, spreadStr, direction } = configCache.value;
|
|
130
|
-
const wrapper = containerGlowWrapper.value;
|
|
131
|
-
|
|
132
|
-
// Batch DOM updates
|
|
133
|
-
wrapper.style.setProperty("--gap", gapStr);
|
|
134
|
-
wrapper.style.setProperty("--blur", blurStr);
|
|
135
|
-
wrapper.style.setProperty("--spread", spreadStr);
|
|
136
|
-
wrapper.style.setProperty("--direction", direction);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// Watch for config changes and reapply styles
|
|
140
|
-
watch(() => props.config, applyStyles, { deep: true });
|
|
141
|
-
|
|
142
|
-
onMounted(() => {
|
|
143
|
-
applyStyles();
|
|
144
|
-
if (containerGlowWrapper.value) {
|
|
145
|
-
document.body.addEventListener("pointermove", updateStyles, {
|
|
146
|
-
signal: controller.signal,
|
|
147
|
-
passive: true, // Improve scroll performance
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
onBeforeUnmount(() => {
|
|
153
|
-
// Clean up RAF if pending
|
|
154
|
-
if (rafId !== null) {
|
|
155
|
-
cancelAnimationFrame(rafId);
|
|
156
|
-
rafId = null;
|
|
157
|
-
}
|
|
158
|
-
lastEventData = null;
|
|
159
|
-
controller.abort();
|
|
160
|
-
});
|
|
161
|
-
</script>
|
|
162
|
-
|
|
163
|
-
<style lang="css">
|
|
164
|
-
@layer components {
|
|
165
|
-
.container-glow-wrapper {
|
|
166
|
-
@property --start {
|
|
167
|
-
syntax: "<number>";
|
|
168
|
-
inherits: true;
|
|
169
|
-
initial-value: 0;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
display: flex;
|
|
173
|
-
gap: 3.2rem;
|
|
174
|
-
|
|
175
|
-
.container-glow-core {
|
|
176
|
-
& *,
|
|
177
|
-
& *:after,
|
|
178
|
-
& *:before {
|
|
179
|
-
box-sizing: border-box;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
--gradient: conic-gradient(
|
|
183
|
-
from 180deg at 50% 70%,
|
|
184
|
-
hsla(0, 0%, 98%, 1) 0deg,
|
|
185
|
-
#eec32d 72.0000010728836deg,
|
|
186
|
-
#ec4b4b 144.0000021457672deg,
|
|
187
|
-
#709ab9 216.00000858306885deg,
|
|
188
|
-
#4dffbf 288.0000042915344deg,
|
|
189
|
-
hsla(0, 0%, 98%, 1) 1turn
|
|
190
|
-
);
|
|
191
|
-
--opacity-active: v-bind("props.config.inactiveOpacity");
|
|
192
|
-
--start: 0;
|
|
193
|
-
|
|
194
|
-
position: relative;
|
|
195
|
-
|
|
196
|
-
height: 100%;
|
|
197
|
-
background: light-dark(white, hsl(246 44% 7%));
|
|
198
|
-
padding: 2rem;
|
|
199
|
-
aspect-ratio: 330 / 400;
|
|
200
|
-
border-radius: 12px;
|
|
201
|
-
min-width: 280px;
|
|
202
|
-
max-width: 280px;
|
|
203
|
-
display: flex;
|
|
204
|
-
flex-direction: column;
|
|
205
|
-
gap: 0.25rem;
|
|
206
|
-
|
|
207
|
-
&:is(:hover, :focus-visible) {
|
|
208
|
-
z-index: 2;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
&::before,
|
|
212
|
-
&::after {
|
|
213
|
-
content: "";
|
|
214
|
-
position: absolute;
|
|
215
|
-
inset: 0;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
&::before {
|
|
219
|
-
pointer-events: none;
|
|
220
|
-
|
|
221
|
-
border: 2px solid transparent;
|
|
222
|
-
border-radius: 12px;
|
|
223
|
-
background: hsl(280 10% 50% / 1);
|
|
224
|
-
background-attachment: fixed;
|
|
225
|
-
border-radius: 12px;
|
|
226
|
-
mask:
|
|
227
|
-
linear-gradient(#0000, #0000),
|
|
228
|
-
conic-gradient(
|
|
229
|
-
from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 1.5)) * 1deg),
|
|
230
|
-
hsl(0 0% 100% / 0.15) 0deg,
|
|
231
|
-
white,
|
|
232
|
-
hsl(0 0% 100% / 0.15) calc(var(--spread) * 2.5deg)
|
|
233
|
-
);
|
|
234
|
-
mask-clip: padding-box, border-box;
|
|
235
|
-
mask-composite: intersect;
|
|
236
|
-
opacity: var(--opacity-active);
|
|
237
|
-
transition: opacity 1s;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
&::after {
|
|
241
|
-
pointer-events: none;
|
|
242
|
-
|
|
243
|
-
background: var(--gradient);
|
|
244
|
-
background-attachment: fixed;
|
|
245
|
-
border-radius: 12px;
|
|
246
|
-
opacity: var(--opacity-active, 0);
|
|
247
|
-
transition: opacity 1s;
|
|
248
|
-
--alpha: 0;
|
|
249
|
-
border: 2px solid transparent;
|
|
250
|
-
mask:
|
|
251
|
-
linear-gradient(#0000, #0000),
|
|
252
|
-
conic-gradient(
|
|
253
|
-
from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 0.5)) * 1deg),
|
|
254
|
-
#0000 0deg,
|
|
255
|
-
#fff,
|
|
256
|
-
#0000 calc(var(--spread) * 0.5deg)
|
|
257
|
-
);
|
|
258
|
-
filter: brightness(1.5);
|
|
259
|
-
mask-clip: padding-box, border-box;
|
|
260
|
-
mask-composite: intersect;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.glows {
|
|
264
|
-
pointer-events: none;
|
|
265
|
-
position: absolute;
|
|
266
|
-
inset: 0;
|
|
267
|
-
filter: blur(calc(var(--blur) * 1px));
|
|
268
|
-
|
|
269
|
-
&::after,
|
|
270
|
-
&::before {
|
|
271
|
-
--alpha: 0;
|
|
272
|
-
content: "";
|
|
273
|
-
background: var(--gradient);
|
|
274
|
-
background-attachment: fixed;
|
|
275
|
-
position: absolute;
|
|
276
|
-
inset: -5px;
|
|
277
|
-
border: 10px solid transparent;
|
|
278
|
-
border-radius: 12px;
|
|
279
|
-
mask:
|
|
280
|
-
linear-gradient(#0000, #0000),
|
|
281
|
-
conic-gradient(
|
|
282
|
-
from calc((var(--start) - (var(--spread) * 0.5)) * 1deg),
|
|
283
|
-
#000 0deg,
|
|
284
|
-
#fff,
|
|
285
|
-
#0000 calc(var(--spread) * 1deg)
|
|
286
|
-
);
|
|
287
|
-
mask-composite: intersect;
|
|
288
|
-
mask-clip: padding-box, border-box;
|
|
289
|
-
opacity: var(--opacity-active);
|
|
290
|
-
transition: opacity 1s;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
</style>
|
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryFn } from "@nuxtjs/storybook";
|
|
2
|
-
import ContainerGlowCoreComponent from "../ContainerGlowCore.vue";
|
|
3
|
-
|
|
4
|
-
// Define the args interface
|
|
5
|
-
interface ContainerGlowCoreArgs {
|
|
6
|
-
itemCount: number;
|
|
7
|
-
tag: string;
|
|
8
|
-
styleClassPassthrough: string[];
|
|
9
|
-
config: {
|
|
10
|
-
proximity: number;
|
|
11
|
-
spread: number;
|
|
12
|
-
blur: number;
|
|
13
|
-
gap: number;
|
|
14
|
-
vertical: boolean;
|
|
15
|
-
inactiveOpacity: number;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
title: "Components/Effects/ContainerGlowCore",
|
|
21
|
-
component: ContainerGlowCoreComponent,
|
|
22
|
-
argTypes: {
|
|
23
|
-
// Core Properties
|
|
24
|
-
itemCount: {
|
|
25
|
-
control: { type: "range", min: 1, max: 6, step: 1 },
|
|
26
|
-
description: "Number of glowing containers to render",
|
|
27
|
-
table: {
|
|
28
|
-
category: "Core",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
tag: {
|
|
32
|
-
control: { type: "text" },
|
|
33
|
-
description: "HTML tag for each container",
|
|
34
|
-
table: {
|
|
35
|
-
category: "Semantic",
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
// Config Object
|
|
39
|
-
config: {
|
|
40
|
-
control: { type: "object" },
|
|
41
|
-
description: "Configuration object for glow effects",
|
|
42
|
-
table: {
|
|
43
|
-
category: "Configuration",
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
// Individual config controls
|
|
47
|
-
"config.proximity": {
|
|
48
|
-
control: { type: "range", min: 10, max: 200, step: 10 },
|
|
49
|
-
description: "Mouse proximity distance to trigger glow effect (px)",
|
|
50
|
-
table: {
|
|
51
|
-
category: "Glow Settings",
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
"config.spread": {
|
|
55
|
-
control: { type: "range", min: 20, max: 180, step: 10 },
|
|
56
|
-
description: "Angular spread of the glow effect (degrees)",
|
|
57
|
-
table: {
|
|
58
|
-
category: "Glow Settings",
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
"config.blur": {
|
|
62
|
-
control: { type: "range", min: 0, max: 50, step: 2 },
|
|
63
|
-
description: "Blur amount for the glow effect (px)",
|
|
64
|
-
table: {
|
|
65
|
-
category: "Glow Settings",
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
"config.gap": {
|
|
69
|
-
control: { type: "range", min: 8, max: 64, step: 4 },
|
|
70
|
-
description: "Gap between containers (px)",
|
|
71
|
-
table: {
|
|
72
|
-
category: "Layout",
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
"config.vertical": {
|
|
76
|
-
control: { type: "boolean" },
|
|
77
|
-
description: "Arrange containers vertically instead of horizontally",
|
|
78
|
-
table: {
|
|
79
|
-
category: "Layout",
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
"config.inactiveOpacity": {
|
|
83
|
-
control: { type: "range", min: 0.05, max: 1, step: 0.05 },
|
|
84
|
-
description: "Opacity of the glow effect when not hovering (inactive state)",
|
|
85
|
-
table: {
|
|
86
|
-
category: "Glow Settings",
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
// Hide complex props
|
|
90
|
-
styleClassPassthrough: {
|
|
91
|
-
table: {
|
|
92
|
-
disable: true,
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
args: {
|
|
97
|
-
itemCount: 3,
|
|
98
|
-
tag: "div",
|
|
99
|
-
styleClassPassthrough: [],
|
|
100
|
-
config: {
|
|
101
|
-
proximity: 40,
|
|
102
|
-
spread: 80,
|
|
103
|
-
blur: 20,
|
|
104
|
-
gap: 32,
|
|
105
|
-
vertical: false,
|
|
106
|
-
inactiveOpacity: 0,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
parameters: {
|
|
110
|
-
docs: {
|
|
111
|
-
description: {
|
|
112
|
-
component:
|
|
113
|
-
"An interactive glow effect component that creates multiple containers with animated gradient borders that respond to mouse movement. Each container glows more intensely when the cursor is nearby, with customizable proximity detection, blur effects, and gradient animations.",
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
} as Meta<ContainerGlowCoreArgs>;
|
|
118
|
-
|
|
119
|
-
const Template: StoryFn<ContainerGlowCoreArgs> = (args) => ({
|
|
120
|
-
components: { ContainerGlowCoreComponent },
|
|
121
|
-
setup() {
|
|
122
|
-
return { args };
|
|
123
|
-
},
|
|
124
|
-
template: `
|
|
125
|
-
<div style="background: radial-gradient(ellipse at center, #0f0f23 0%, #020024 100%); padding: 60px 40px; min-height: 80vh; display: flex; align-items: center; justify-content: center;">
|
|
126
|
-
<div style="text-align: center; width: 100%;">
|
|
127
|
-
<div style="margin-bottom: 40px;">
|
|
128
|
-
<h2 style="color: white; margin: 0 0 16px 0; font-size: 28px; font-weight: 700; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);">
|
|
129
|
-
✨ Interactive Glow Effects
|
|
130
|
-
</h2>
|
|
131
|
-
<p style="color: rgba(255, 255, 255, 0.8); margin: 0 0 8px 0; font-size: 16px;">
|
|
132
|
-
Move your mouse over the containers to see the glow effect
|
|
133
|
-
</p>
|
|
134
|
-
<p style="color: rgba(255, 255, 255, 0.6); margin: 0; font-size: 14px;">
|
|
135
|
-
{{ args.itemCount }} container{{ args.itemCount > 1 ? 's' : '' }} • {{ args.config.vertical ? 'Vertical' : 'Horizontal' }} layout
|
|
136
|
-
</p>
|
|
137
|
-
</div>
|
|
138
|
-
|
|
139
|
-
<ContainerGlowCoreComponent
|
|
140
|
-
:item-count="args.itemCount"
|
|
141
|
-
:tag="args.tag"
|
|
142
|
-
:style-class-passthrough="args.styleClassPassthrough"
|
|
143
|
-
:config="args.config"
|
|
144
|
-
>
|
|
145
|
-
<template v-for="n in args.itemCount" :key="n" v-slot:['container-glow-' + (n - 1)]>
|
|
146
|
-
<div style="height: 100%; display: flex; flex-direction: column;">
|
|
147
|
-
<div style="text-align: center; margin-bottom: 16px;">
|
|
148
|
-
<div style="width: 48px; height: 48px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 50%; margin: 0 auto 12px auto; display: flex; align-items: center; justify-content: center; font-size: 20px; color: white; font-weight: bold;">
|
|
149
|
-
{{ n }}
|
|
150
|
-
</div>
|
|
151
|
-
<h3 style="margin: 0 0 8px 0; color: #374151; font-size: 18px; font-weight: 600;">
|
|
152
|
-
Container {{ n }}
|
|
153
|
-
</h3>
|
|
154
|
-
<p style="margin: 0; color: #6b7280; font-size: 14px;">
|
|
155
|
-
Interactive glow card
|
|
156
|
-
</p>
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
<div style="flex: 1; display: flex; flex-direction: column; justify-content: center; text-align: center; padding: 16px 0;">
|
|
160
|
-
<div style="padding: 16px; background: rgba(0, 0, 0, 0.02); border-radius: 8px; margin-bottom: 16px;">
|
|
161
|
-
<h4 style="margin: 0 0 8px 0; color: #4b5563; font-size: 14px; font-weight: 600;">Effect Settings</h4>
|
|
162
|
-
<div style="font-family: monospace; font-size: 11px; color: #6b7280; line-height: 1.4;">
|
|
163
|
-
<div>Proximity: {{ args.config.proximity }}px</div>
|
|
164
|
-
<div>Spread: {{ args.config.spread }}°</div>
|
|
165
|
-
<div>Blur: {{ args.config.blur }}px</div>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
|
|
169
|
-
<div style="padding: 12px; background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 6px; border-left: 3px solid #3b82f6;">
|
|
170
|
-
<p style="margin: 0; color: #1e40af; font-size: 12px; line-height: 1.4; font-weight: 500;">
|
|
171
|
-
💡 Hover to activate the glow effect with mouse tracking
|
|
172
|
-
</p>
|
|
173
|
-
</div>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
</template>
|
|
177
|
-
</ContainerGlowCoreComponent>
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
`,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
// ===== BASIC STORIES =====
|
|
184
|
-
|
|
185
|
-
export const Default = Template.bind({});
|
|
186
|
-
Default.args = {};
|
|
187
|
-
|
|
188
|
-
// ===== CONTAINER COUNT STORIES =====
|
|
189
|
-
|
|
190
|
-
export const SingleContainer = Template.bind({});
|
|
191
|
-
SingleContainer.args = {
|
|
192
|
-
itemCount: 1,
|
|
193
|
-
};
|
|
194
|
-
SingleContainer.parameters = {
|
|
195
|
-
docs: {
|
|
196
|
-
description: {
|
|
197
|
-
story:
|
|
198
|
-
"Single container with glow effects - perfect for highlighting individual elements or call-to-action cards.",
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export const TwoContainers = Template.bind({});
|
|
204
|
-
TwoContainers.args = {
|
|
205
|
-
itemCount: 2,
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
export const FourContainers = Template.bind({});
|
|
209
|
-
FourContainers.args = {
|
|
210
|
-
itemCount: 4,
|
|
211
|
-
};
|
|
212
|
-
FourContainers.parameters = {
|
|
213
|
-
docs: {
|
|
214
|
-
description: {
|
|
215
|
-
story:
|
|
216
|
-
"Four containers showing how the glow effect scales with multiple elements - ideal for feature grids or product showcases.",
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
// ===== CONFIGURATION STORIES =====
|
|
222
|
-
|
|
223
|
-
export const HighIntensityGlow: StoryFn<ContainerGlowCoreArgs> = (args) => ({
|
|
224
|
-
components: { ContainerGlowCoreComponent },
|
|
225
|
-
setup() {
|
|
226
|
-
return { args };
|
|
227
|
-
},
|
|
228
|
-
template: `
|
|
229
|
-
<div style="background: #000000; padding: 60px 40px; min-height: 80vh; display: flex; align-items: center; justify-content: center;">
|
|
230
|
-
<div style="text-align: center; width: 100%;">
|
|
231
|
-
<div style="margin-bottom: 40px;">
|
|
232
|
-
<h2 style="color: white; margin: 0 0 16px 0; font-size: 28px; font-weight: 700; text-shadow: 0 0 20px rgba(255, 255, 255, 0.5);">
|
|
233
|
-
🔥 High Intensity Glow
|
|
234
|
-
</h2>
|
|
235
|
-
<p style="color: rgba(255, 255, 255, 0.8); margin: 0 0 8px 0; font-size: 16px;">
|
|
236
|
-
Maximum glow settings for dramatic effects
|
|
237
|
-
</p>
|
|
238
|
-
<div style="display: inline-flex; gap: 16px; font-family: monospace; font-size: 12px; color: #10b981;">
|
|
239
|
-
<span>Proximity: {{ args.config.proximity }}px</span>
|
|
240
|
-
<span>Spread: {{ args.config.spread }}°</span>
|
|
241
|
-
<span>Blur: {{ args.config.blur }}px</span>
|
|
242
|
-
<span>Inactive Opacity: {{ args.config.inactiveOpacity }}</span>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
|
|
246
|
-
<ContainerGlowCoreComponent
|
|
247
|
-
:item-count="args.itemCount"
|
|
248
|
-
:tag="args.tag"
|
|
249
|
-
:style-class-passthrough="args.styleClassPassthrough"
|
|
250
|
-
:config="args.config"
|
|
251
|
-
>
|
|
252
|
-
<template v-for="n in args.itemCount" :key="n" v-slot:['container-glow-' + (n - 1)]>
|
|
253
|
-
<div style="height: 100%; display: flex; flex-direction: column; text-align: center;">
|
|
254
|
-
<div style="margin-bottom: 20px;">
|
|
255
|
-
<div style="width: 56px; height: 56px; background: linear-gradient(135deg, #ff6b6b, #ffd93d, #6bcf7f, #4d79ff); border-radius: 16px; margin: 0 auto 16px auto; display: flex; align-items: center; justify-content: center; font-size: 24px; color: white; font-weight: bold; box-shadow: 0 0 20px rgba(255, 107, 107, 0.4);">
|
|
256
|
-
🌟
|
|
257
|
-
</div>
|
|
258
|
-
<h3 style="margin: 0 0 8px 0; color: white; font-size: 18px; font-weight: 700; text-shadow: 0 0 10px rgba(255, 255, 255, 0.3);">
|
|
259
|
-
Intense {{ n }}
|
|
260
|
-
</h3>
|
|
261
|
-
<p style="margin: 0; color: rgba(255, 255, 255, 0.7); font-size: 14px;">
|
|
262
|
-
High-impact glow effect
|
|
263
|
-
</p>
|
|
264
|
-
</div>
|
|
265
|
-
|
|
266
|
-
<div style="flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 16px;">
|
|
267
|
-
<div style="padding: 20px; background: rgba(255, 255, 255, 0.05); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.1);">
|
|
268
|
-
<h4 style="margin: 0 0 12px 0; color: #f59e0b; font-size: 14px; font-weight: 600;">⚡ Power Settings</h4>
|
|
269
|
-
<div style="display: grid; gap: 8px; font-family: monospace; font-size: 10px; color: rgba(255, 255, 255, 0.8);">
|
|
270
|
-
<div style="display: flex; justify-content: space-between;">
|
|
271
|
-
<span>Range:</span>
|
|
272
|
-
<span style="color: #10b981;">{{ args.config.proximity }}px</span>
|
|
273
|
-
</div>
|
|
274
|
-
<div style="display: flex; justify-content: space-between;">
|
|
275
|
-
<span>Intensity:</span>
|
|
276
|
-
<span style="color: #f59e0b;">{{ Math.round(args.config.inactiveOpacity * 100) }}%</span>
|
|
277
|
-
</div>
|
|
278
|
-
<div style="display: flex; justify-content: space-between;">
|
|
279
|
-
<span>Blur:</span>
|
|
280
|
-
<span style="color: #8b5cf6;">{{ args.config.blur }}px</span>
|
|
281
|
-
</div>
|
|
282
|
-
</div>
|
|
283
|
-
</div>
|
|
284
|
-
|
|
285
|
-
<div style="padding: 16px; background: linear-gradient(135deg, rgba(255, 107, 107, 0.1), rgba(139, 92, 246, 0.1)); border-radius: 8px; border: 1px solid rgba(255, 107, 107, 0.2);">
|
|
286
|
-
<p style="margin: 0; color: #ff6b6b; font-size: 11px; line-height: 1.4; font-weight: 500;">
|
|
287
|
-
🎯 Move cursor close for maximum glow intensity
|
|
288
|
-
</p>
|
|
289
|
-
</div>
|
|
290
|
-
</div>
|
|
291
|
-
</div>
|
|
292
|
-
</template>
|
|
293
|
-
</ContainerGlowCoreComponent>
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
`,
|
|
297
|
-
});
|
|
298
|
-
HighIntensityGlow.args = {
|
|
299
|
-
itemCount: 3,
|
|
300
|
-
config: {
|
|
301
|
-
proximity: 100,
|
|
302
|
-
spread: 120,
|
|
303
|
-
blur: 40,
|
|
304
|
-
gap: 48,
|
|
305
|
-
vertical: false,
|
|
306
|
-
inactiveOpacity: 0,
|
|
307
|
-
},
|
|
308
|
-
};
|
|
309
|
-
HighIntensityGlow.parameters = {
|
|
310
|
-
docs: {
|
|
311
|
-
description: {
|
|
312
|
-
story:
|
|
313
|
-
"High-intensity glow configuration with increased proximity range, spread, blur, and opacity for dramatic visual effects.",
|
|
314
|
-
},
|
|
315
|
-
},
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
export const SubtleGlow = Template.bind({});
|
|
319
|
-
SubtleGlow.args = {
|
|
320
|
-
itemCount: 4,
|
|
321
|
-
config: {
|
|
322
|
-
proximity: 30,
|
|
323
|
-
spread: 40,
|
|
324
|
-
blur: 10,
|
|
325
|
-
gap: 20,
|
|
326
|
-
vertical: false,
|
|
327
|
-
inactiveOpacity: 0,
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
SubtleGlow.parameters = {
|
|
331
|
-
docs: {
|
|
332
|
-
description: {
|
|
333
|
-
story:
|
|
334
|
-
"Subtle glow configuration with reduced intensity, tighter proximity, and minimal blur for elegant, understated effects.",
|
|
335
|
-
},
|
|
336
|
-
},
|
|
337
|
-
};
|