srcdev-nuxt-components 9.4.5 → 9.4.7

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.
Files changed (104) hide show
  1. package/.claude/commands/migrate-component.md +74 -5
  2. package/.claude/component-ledger/audit.json +1 -1
  3. package/.claude/component-ledger/build.mjs +27 -0
  4. package/.claude/component-ledger/output.html +8 -3
  5. package/.claude/component-ledger/template.html +7 -2
  6. package/.claude/skills/components/breadcrumb.md +1 -0
  7. package/.claude/skills/components/column-flow-grid.md +93 -0
  8. package/.claude/skills/components/content-docs.md +2 -0
  9. package/.claude/skills/components/display-tooltip-defined.md +3 -0
  10. package/.claude/skills/components/display-tooltip.md +1 -0
  11. package/.claude/skills/components/entry-animation.md +88 -0
  12. package/.claude/skills/components/input-copy.md +2 -0
  13. package/.claude/skills/components/input-text-core.md +186 -0
  14. package/.claude/skills/components/marquee-scroller.md +130 -0
  15. package/.claude/skills/components/masonry-grid.md +153 -0
  16. package/.claude/skills/components/navigation-items.md +1 -0
  17. package/.claude/skills/components/pop-over.md +100 -0
  18. package/.claude/skills/components/responsive-header.md +3 -0
  19. package/.claude/skills/components/site-header.md +4 -0
  20. package/.claude/skills/components/site-navigation.md +1 -0
  21. package/.claude/skills/components/tab-navigation.md +1 -0
  22. package/.claude/skills/index.md +7 -1
  23. package/.vscode/srcdev-component-breadcrumb.code-snippets +13 -0
  24. package/.vscode/srcdev-component-column-flow-grid.code-snippets +39 -0
  25. package/.vscode/srcdev-component-content-docs.code-snippets +18 -0
  26. package/.vscode/srcdev-component-display-tooltip-defined.code-snippets +15 -0
  27. package/.vscode/srcdev-component-display-tooltip.code-snippets +11 -0
  28. package/.vscode/srcdev-component-entry-animation.code-snippets +29 -0
  29. package/.vscode/srcdev-component-input-text.code-snippets +107 -0
  30. package/.vscode/srcdev-component-marquee-scroller.code-snippets +93 -0
  31. package/.vscode/srcdev-component-masonry-grid.code-snippets +51 -0
  32. package/.vscode/srcdev-component-pop-over.code-snippets +44 -0
  33. package/.vscode/srcdev-component-responsive-header.code-snippets +12 -0
  34. package/.vscode/srcdev-component-site-header.code-snippets +17 -0
  35. package/.vscode/srcdev-component-site-navigation.code-snippets +30 -0
  36. package/.vscode/srcdev-component-slider-gallery.code-snippets +38 -0
  37. package/.vscode/srcdev-component-tab-navigation.code-snippets +30 -0
  38. package/app/components/01.atoms/animations/entry/EntryAnimation.vue +7 -1
  39. package/app/components/01.atoms/animations/entry/stories/EntryAnimation.stories.ts +47 -0
  40. package/app/components/01.atoms/animations/entry/tests/EntryAnimation.spec.ts +57 -0
  41. package/app/components/01.atoms/animations/marquee-scroller/CONSUMER-STYLING.md +94 -0
  42. package/app/components/01.atoms/animations/marquee-scroller/MarqueeScroller.vue +331 -0
  43. package/app/components/01.atoms/animations/marquee-scroller/stories/MarqueeScroller.stories.ts +151 -0
  44. package/app/components/01.atoms/animations/marquee-scroller/tests/MarqueeScroller.spec.ts +315 -0
  45. package/app/components/01.atoms/animations/marquee-scroller/tests/__snapshots__/MarqueeScroller.spec.ts.snap +28 -0
  46. package/app/components/01.atoms/canvas-switcher/stories/CanvasSwitcher.stories.ts +9 -10
  47. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +8 -2
  48. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +12 -13
  49. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +4 -1
  50. package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +33 -0
  51. package/app/components/01.atoms/grids/column-flow-grid/ColumnFlowGrid.vue +55 -0
  52. package/app/components/01.atoms/grids/column-flow-grid/stories/ColumnFlowGrid.stories.ts +178 -0
  53. package/app/components/01.atoms/grids/column-flow-grid/tests/ColumnFlowGrid.spec.ts +75 -0
  54. package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +35 -0
  55. package/app/components/01.atoms/grids/masonry-grid/MasonryGrid.vue +178 -0
  56. package/app/components/01.atoms/grids/masonry-grid/stories/MasonryGrid.stories.ts +199 -0
  57. package/app/components/01.atoms/grids/masonry-grid/tests/MasonryGrid.spec.ts +158 -0
  58. package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +4 -1
  59. package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +54 -0
  60. package/app/components/01.atoms/pop-over/PopOver.vue +201 -0
  61. package/app/components/01.atoms/pop-over/stories/PopOver.stories.ts +141 -0
  62. package/app/components/01.atoms/pop-over/tests/PopOver.spec.ts +195 -0
  63. package/app/components/01.atoms/pop-over/tests/__snapshots__/PopOver.spec.ts.snap +11 -0
  64. package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +8 -2
  65. package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +16 -3
  66. package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +1 -1
  67. package/app/components/02.molecules/input-copy/InputCopy.vue +14 -0
  68. package/app/components/02.molecules/input-copy/stories/InputCopy.stories.ts +15 -0
  69. package/app/components/02.molecules/input-copy/tests/InputCopy.spec.ts +41 -0
  70. package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +4 -1
  71. package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +4 -1
  72. package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +16 -4
  73. package/app/components/03.organisms/responsive-header/NavigationItems.vue +4 -1
  74. package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +16 -3
  75. package/app/components/03.organisms/site-header/SiteHeader.vue +16 -1
  76. package/app/components/03.organisms/site-header/tests/__snapshots__/SiteHeader.spec.ts.snap +1 -1
  77. package/app/components/05.forms/input-select/InputSelectCore.vue +1 -1
  78. package/app/components/05.forms/input-text/InputTextCore.vue +6 -0
  79. package/app/components/05.forms/input-text/stories/InputPasswordWithLabel.stories.ts +49 -20
  80. package/app/components/05.forms/input-text/stories/InputTextAsNumberWithLabel.stories.ts +41 -22
  81. package/app/components/05.forms/input-text/stories/InputTextCore.stories.ts +48 -22
  82. package/app/components/05.forms/input-text/stories/InputTextWithLabel.stories.ts +43 -17
  83. package/app/components/05.forms/input-text/tests/InputPasswordWithLabel.spec.ts +56 -0
  84. package/app/components/05.forms/input-text/tests/InputTextAsNumberWithLabel.spec.ts +61 -0
  85. package/app/components/05.forms/input-text/tests/InputTextCore.spec.ts +60 -0
  86. package/app/components/05.forms/input-text/tests/InputTextWithLabel.spec.ts +46 -0
  87. package/app/components/05.forms/input-text/variants/InputPasswordWithLabel.vue +7 -1
  88. package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +8 -2
  89. package/app/components/05.forms/input-text/variants/InputTextWithLabel.vue +6 -0
  90. package/app/components/05.forms/input-textarea/stories/InputTextareaCore.stories.ts +20 -20
  91. package/app/components/05.forms/input-textarea/stories/InputTextareaWithLabel.stories.ts +32 -26
  92. package/app/types/components/index.ts +1 -0
  93. package/app/types/components/marquee-scroller.d.ts +10 -0
  94. package/app/types/forms/types.forms.d.ts +1 -1
  95. package/package.json +1 -1
  96. package/app/components/marquee-scroller/MarqueeScroller.vue +0 -289
  97. package/app/components/masonry-grid/MasonryGrid.vue +0 -68
  98. package/app/components/masonry-grid-ordered/MasonryGridOrdered.vue +0 -163
  99. package/app/components/masonry-grid-ordered/MasonryGridOrderedGridExperiment.vue +0 -259
  100. package/app/components/masonry-grid-ordered/stories/MasonryGridOrdered.stories.ts +0 -354
  101. package/app/components/masonry-grid-sorted/MasonryGridSorted.vue +0 -120
  102. package/app/components/pop-over/PopOver.vue +0 -90
  103. package/app/layouts/default.vue +0 -308
  104. package/app/layouts/site-navigation-demo.vue +0 -188
@@ -1,259 +0,0 @@
1
- <template>
2
- <div class="masonry-grid-ordered" :class="[elementClasses]">
3
- <div
4
- ref="gridWrapper"
5
- class="masonry-grid-ordered-wrapper"
6
- :class="[{ 'multiple-cols': !isSingleColumn, 'setup-complete': isSetupComplete }]"
7
- >
8
- <div v-for="item in props.gridData" :key="item.id" ref="gridItemsRefs" class="masonry-grid-ordered-item">
9
- <div ref="gridContentRefs" class="masonry-grid-ordered-content">
10
- <slot :name="item.id"></slot>
11
- </div>
12
- </div>
13
- </div>
14
- </div>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import { useElementSize, useResizeObserver } from "@vueuse/core";
19
-
20
- const props = defineProps({
21
- gridData: {
22
- type: Array as PropType<{ id: string }[]>,
23
- default: () => [],
24
- },
25
- minTileWidth: {
26
- type: Number,
27
- default: 312,
28
- },
29
- gap: {
30
- type: Number,
31
- default: 12,
32
- },
33
- styleClassPassthrough: {
34
- type: [String, Array] as PropType<string | string[]>,
35
- default: () => [],
36
- },
37
- fixedWidth: {
38
- type: Boolean,
39
- default: false,
40
- },
41
- justify: {
42
- type: String as PropType<"left" | "center" | "right">,
43
- default: "left",
44
- validator: (val: string) => ["left", "center", "right"].includes(val),
45
- },
46
- });
47
-
48
- const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
49
-
50
- const gridWrapper = ref<null | HTMLDivElement>(null);
51
- const gridItemsRefs = ref<HTMLDivElement[]>([]);
52
- const gridContentRefs = ref<HTMLDivElement[]>([]);
53
- const { width } = useElementSize(gridWrapper);
54
-
55
- // Track item properties for masonry positioning
56
- interface ItemData {
57
- height: number;
58
- column: number;
59
- row: number;
60
- top: number;
61
- bottom: number;
62
- translateY: number;
63
- }
64
- const itemDataArray = ref<ItemData[]>([]);
65
- const isSetupComplete = ref(false);
66
-
67
- const columnCount = computed(() => {
68
- if (width.value === 0) return 1;
69
- // Match the CSS container query breakpoint (636px hard-coded for now)
70
- // if (width.value < 636) return 1
71
- return Math.max(1, Math.floor(width.value / (props.minTileWidth + props.gap)));
72
- });
73
-
74
- const isSingleColumn = computed(() => columnCount.value === 1);
75
-
76
- const gapStr = computed(() => `${props.gap}px`);
77
-
78
- const minTileWidthStr = computed(() => `${props.minTileWidth}px`);
79
-
80
- const updateGrid = () => {
81
- if (gridWrapper.value !== null && columnCount.value > 1) {
82
- // Initialize or reset the item data array
83
- itemDataArray.value = Array(props.gridData.length)
84
- .fill(null)
85
- .map(() => ({ height: 0, column: 0, row: 0, top: 0, bottom: 0, translateY: 0 }));
86
-
87
- // Step 1: Hide items for measurement
88
- gridItemsRefs.value.forEach((itemEl) => {
89
- if (itemEl) {
90
- itemEl.style.setProperty("--_opacity", "0");
91
- }
92
- });
93
-
94
- // Force a reflow to get accurate measurements in grid layout
95
- void gridWrapper.value.offsetHeight;
96
-
97
- // Step 2: Measure heights and store in array
98
- gridContentRefs.value.forEach((contentEl, index) => {
99
- if (!contentEl || !gridItemsRefs.value[index] || !itemDataArray.value[index]) return;
100
-
101
- const itemEl = gridItemsRefs.value[index];
102
- const contentHeight = contentEl.offsetHeight;
103
-
104
- // Calculate which column this item would be in based on CSS Grid's auto-fit
105
- const column = index % columnCount.value;
106
-
107
- // Calculate which row this item would be in based on CSS Grid's auto-fit
108
- const row = Math.floor(index / columnCount.value);
109
-
110
- let top: number;
111
- let bottom: number;
112
- let translateY: number;
113
-
114
- // Always get the actual measured position first
115
- const wrapperRect = gridWrapper.value!.getBoundingClientRect();
116
- const itemRect = itemEl.getBoundingClientRect();
117
- const actualTop = itemRect.top - wrapperRect.top;
118
-
119
- if (row === 0) {
120
- // First row: use natural CSS Grid position
121
- top = actualTop;
122
- bottom = top + contentHeight;
123
- translateY = 0; // No transform needed for first row
124
- } else {
125
- // Subsequent rows: position based on item above in same column
126
- const itemAboveIndex = index - columnCount.value;
127
- const itemAbove = itemDataArray.value[itemAboveIndex];
128
-
129
- if (itemAbove) {
130
- top = itemAbove.bottom + props.gap;
131
- bottom = top + contentHeight;
132
- // Calculate the transform needed to move from actual position to desired position
133
- translateY = top - actualTop;
134
- } else {
135
- // Fallback to natural position if no item above found
136
- top = actualTop;
137
- bottom = top + contentHeight;
138
- translateY = 0;
139
- }
140
- }
141
-
142
- // Store the data in our tracking array
143
- itemDataArray.value[index].height = contentHeight;
144
- itemDataArray.value[index].column = column;
145
- itemDataArray.value[index].row = row;
146
- itemDataArray.value[index].top = top;
147
- itemDataArray.value[index].bottom = bottom;
148
- itemDataArray.value[index].translateY = translateY;
149
-
150
- // Set the CSS custom properties
151
- itemEl.style.setProperty("--_item-height", `${contentHeight}px`);
152
- itemEl.style.setProperty("--_translate-y", `${translateY}px`);
153
- itemEl.style.setProperty("--_opacity", "1");
154
- });
155
-
156
- // Log the complete item data array when calculations are complete
157
- // console.log("📊 Item data array:", itemDataArray.value)
158
-
159
- // Mark setup as complete
160
- isSetupComplete.value = true;
161
- } else {
162
- // Reset setup state for single column
163
- isSetupComplete.value = false;
164
-
165
- // Reset item data array
166
- itemDataArray.value = [];
167
-
168
- // Single column: reset to normal flow
169
- gridItemsRefs.value.forEach((itemEl) => {
170
- if (itemEl) {
171
- itemEl.style.removeProperty("--_opacity");
172
- itemEl.style.removeProperty("--_item-height");
173
- itemEl.style.removeProperty("--_translate-y");
174
- }
175
- });
176
- gridWrapper.value?.style.removeProperty("--_wrapper-height");
177
- }
178
- };
179
-
180
- useResizeObserver(gridWrapper, async () => {
181
- // console.log("useResizeObserver triggered")
182
- // itemDataArray.value = [] // Clear previous data
183
- // await useSleep(100)
184
- // console.log("useResizeObserver after sleep")
185
- nextTick(() => updateGrid());
186
-
187
- // requestAnimationFrame(() => {
188
- // updateGrid()
189
- // nextTick(() => updateGrid())
190
- // })
191
-
192
- // Add a small delay to ensure DOM is fully rendered and measured
193
- // setTimeout(() => {
194
- // nextTick(() => updateGrid())
195
- // }, 100)
196
- });
197
-
198
- onMounted(() => {
199
- // Add a small delay to ensure DOM is fully rendered and measured
200
- setTimeout(() => {
201
- nextTick(() => updateGrid());
202
- }, 100);
203
- });
204
-
205
- watch(
206
- () => props.fixedWidth,
207
- () => {
208
- updateGrid();
209
- }
210
- );
211
-
212
- watch(
213
- () => props.gridData,
214
- () => {
215
- // nextTick(() => updateGrid())
216
- }
217
- );
218
-
219
- watch(
220
- () => width.value,
221
- (newWidth) => {
222
- if (newWidth > 0) {
223
- // nextTick(() => updateGrid())
224
- }
225
- }
226
- );
227
-
228
- watch(
229
- () => props.styleClassPassthrough,
230
- () => {
231
- resetElementClasses(props.styleClassPassthrough);
232
- }
233
- );
234
- </script>
235
-
236
- <style lang="css">
237
- @layer components {
238
- .masonry-grid-ordered {
239
- --_transition-duration: 0.3s;
240
-
241
- .masonry-grid-ordered-wrapper {
242
- display: grid;
243
- gap: v-bind(gapStr);
244
- grid-template-columns: repeat(auto-fit, minmax(v-bind(minTileWidthStr), 1fr));
245
-
246
- height: var(--_wrapper-height, auto);
247
-
248
- &.multiple-cols {
249
- .masonry-grid-ordered-item {
250
- height: var(--_item-height, auto);
251
- opacity: var(--_opacity, 1);
252
- transform: translateY(var(--_translate-y, 0px));
253
- transition: transform var(--_transition-duration) ease;
254
- }
255
- }
256
- }
257
- }
258
- }
259
- </style>
@@ -1,354 +0,0 @@
1
- import type { Meta, StoryFn } from "@nuxtjs/storybook";
2
- import StorybookComponent from "../MasonryGridOrdered.vue";
3
- import type { IQuote } from "~/types/types.quotes";
4
-
5
- // Custom interface for story args
6
- interface MasonryGridOrderedStoryArgs {
7
- gridData: IQuote[];
8
- gap: number;
9
- minTileWidth: number;
10
- fixedWidth: boolean;
11
- styleClassPassthrough: string[];
12
- // Display options for stories
13
- showBorders: boolean;
14
- showNumbers: boolean;
15
- itemVariant: "simple" | "card" | "detailed";
16
- }
17
-
18
- // Sample data for stories
19
- const sampleQuotes: IQuote[] = [
20
- {
21
- id: 1,
22
- quote: "The only way to do great work is to love what you do.",
23
- author: "Steve Jobs",
24
- },
25
- {
26
- id: 2,
27
- quote: "Life is what happens to you while you're busy making other plans.",
28
- author: "John Lennon",
29
- },
30
- {
31
- id: 3,
32
- quote: "The future belongs to those who believe in the beauty of their dreams.",
33
- author: "Eleanor Roosevelt",
34
- },
35
- {
36
- id: 4,
37
- quote: "It is during our darkest moments that we must focus to see the light.",
38
- author: "Aristotle",
39
- },
40
- {
41
- id: 5,
42
- quote: "The way to get started is to quit talking and begin doing.",
43
- author: "Walt Disney",
44
- },
45
- {
46
- id: 6,
47
- quote: "Don't let yesterday take up too much of today.",
48
- author: "Will Rogers",
49
- },
50
- {
51
- id: 7,
52
- quote: "You learn more from failure than from success. Don't let it stop you. Failure builds character.",
53
- author: "Unknown",
54
- },
55
- {
56
- id: 8,
57
- quote: "It's not whether you get knocked down, it's whether you get up.",
58
- author: "Vince Lombardi",
59
- },
60
- {
61
- id: 9,
62
- quote:
63
- "If you are working on something that you really care about, you don't have to be pushed. The vision pulls you.",
64
- author: "Steve Jobs",
65
- },
66
- {
67
- id: 10,
68
- quote: "People who are crazy enough to think they can change the world, are the ones who do.",
69
- author: "Rob Siltanen",
70
- },
71
- {
72
- id: 11,
73
- quote: "We don't make mistakes, just happy little accidents.",
74
- author: "Bob Ross",
75
- },
76
- {
77
- id: 12,
78
- quote: "In the middle of every difficulty lies opportunity.",
79
- author: "Albert Einstein",
80
- },
81
- ];
82
-
83
- export default {
84
- title: "Components/UI/MasonryGridOrdered",
85
- component: StorybookComponent,
86
- argTypes: {
87
- // Layout Configuration
88
- gap: {
89
- control: { type: "range", min: 0, max: 50, step: 2 },
90
- description: "Gap between grid items in pixels",
91
- table: {
92
- category: "Layout",
93
- },
94
- },
95
- minTileWidth: {
96
- control: { type: "range", min: 200, max: 500, step: 10 },
97
- description: "Minimum width for each grid tile",
98
- table: {
99
- category: "Layout",
100
- },
101
- },
102
- fixedWidth: {
103
- control: { type: "boolean" },
104
- description: "Whether to use fixed width for tiles",
105
- table: {
106
- category: "Layout",
107
- },
108
- },
109
- styleClassPassthrough: {
110
- control: { type: "object" },
111
- description: "Additional CSS classes to pass through",
112
- table: {
113
- category: "Layout",
114
- },
115
- },
116
- // Data Configuration
117
- gridData: {
118
- control: { type: "object" },
119
- description: "Array of quote objects to display in the grid",
120
- table: {
121
- category: "Data",
122
- },
123
- },
124
- // Display Options (for stories only)
125
- showBorders: {
126
- control: { type: "boolean" },
127
- description: "Show borders around grid items",
128
- table: {
129
- category: "Display Options",
130
- },
131
- },
132
- showNumbers: {
133
- control: { type: "boolean" },
134
- description: "Show index numbers on grid items",
135
- table: {
136
- category: "Display Options",
137
- },
138
- },
139
- itemVariant: {
140
- control: { type: "select" },
141
- options: ["simple", "card", "detailed"],
142
- description: "Style variant for grid items",
143
- table: {
144
- category: "Display Options",
145
- },
146
- },
147
- },
148
- args: {
149
- gridData: sampleQuotes.slice(0, 8),
150
- gap: 12,
151
- minTileWidth: 300,
152
- fixedWidth: true,
153
- styleClassPassthrough: ["mi-auto"],
154
- showBorders: true,
155
- showNumbers: true,
156
- itemVariant: "card",
157
- },
158
- } as Meta<MasonryGridOrderedStoryArgs>;
159
-
160
- const Template: StoryFn<MasonryGridOrderedStoryArgs> = (args) => ({
161
- components: {
162
- StorybookComponent,
163
- },
164
- setup() {
165
- const getItemClasses = (variant: string, showBorders: boolean) => {
166
- const baseClasses = ["p-10"];
167
-
168
- if (showBorders) {
169
- baseClasses.push("border", "border-1", "border-grey-dark");
170
-
171
- if (variant === "card") {
172
- baseClasses.push("border-r-4");
173
- }
174
- }
175
-
176
- if (variant === "detailed") {
177
- baseClasses.push("bg-gray-1", "rounded-4");
178
- }
179
-
180
- return baseClasses.join(" ");
181
- };
182
-
183
- return { args, getItemClasses };
184
- },
185
- template: `
186
- <div style="padding: 20px; max-width: 1200px; margin: 0 auto;">
187
- <div style="margin-bottom: 20px;">
188
- <h3 style="margin-bottom: 10px;">MasonryGridOrdered Component</h3>
189
- <p style="color: #666; margin-bottom: 20px;">
190
- Displaying {{ args.gridData.length }} items with {{ args.gap }}px gap and {{ args.minTileWidth }}px minimum width
191
- </p>
192
- </div>
193
-
194
- <StorybookComponent
195
- :gridData="args.gridData"
196
- :gap="args.gap"
197
- :min-tile-width="args.minTileWidth"
198
- :fixed-width="args.fixedWidth"
199
- :styleClassPassthrough="args.styleClassPassthrough"
200
- >
201
- <template v-for="(item, index) in args.gridData" v-slot:[item.id]>
202
- <div :class="getItemClasses(args.itemVariant, args.showBorders)">
203
- <p v-if="args.showNumbers" class="text-normal wght-700" style="margin-bottom: 8px;">
204
- {{ index + 1 }}: {{ item.author }}
205
- </p>
206
- <p v-else class="text-normal wght-700" style="margin-bottom: 8px;">
207
- {{ item.author }}
208
- </p>
209
- <p class="text-normal">{{ item.quote }}</p>
210
- </div>
211
- </template>
212
- </StorybookComponent>
213
- </div>
214
- `,
215
- });
216
-
217
- export const Default = Template.bind({});
218
-
219
- export const SmallGap = Template.bind({});
220
- SmallGap.args = {
221
- gap: 4,
222
- minTileWidth: 250,
223
- fixedWidth: false,
224
- itemVariant: "simple",
225
- showBorders: false,
226
- showNumbers: false,
227
- };
228
-
229
- export const LargeGap = Template.bind({});
230
- LargeGap.args = {
231
- gap: 24,
232
- minTileWidth: 320,
233
- fixedWidth: true,
234
- itemVariant: "card",
235
- showBorders: true,
236
- showNumbers: true,
237
- };
238
-
239
- export const WideItems = Template.bind({});
240
- WideItems.args = {
241
- gap: 16,
242
- minTileWidth: 400,
243
- fixedWidth: false,
244
- itemVariant: "detailed",
245
- showBorders: true,
246
- showNumbers: false,
247
- };
248
-
249
- export const NarrowItems = Template.bind({});
250
- NarrowItems.args = {
251
- gap: 8,
252
- minTileWidth: 200,
253
- fixedWidth: true,
254
- itemVariant: "simple",
255
- showBorders: true,
256
- showNumbers: true,
257
- };
258
-
259
- export const ManyItems = Template.bind({});
260
- ManyItems.args = {
261
- gridData: sampleQuotes, // All 12 items
262
- gap: 12,
263
- minTileWidth: 280,
264
- fixedWidth: true,
265
- itemVariant: "card",
266
- showBorders: true,
267
- showNumbers: true,
268
- };
269
-
270
- export const FewItems = Template.bind({});
271
- FewItems.args = {
272
- gridData: sampleQuotes.slice(0, 4),
273
- gap: 20,
274
- minTileWidth: 350,
275
- fixedWidth: false,
276
- itemVariant: "detailed",
277
- showBorders: true,
278
- showNumbers: false,
279
- };
280
-
281
- export const MinimalStyle = Template.bind({});
282
- MinimalStyle.args = {
283
- gap: 16,
284
- minTileWidth: 300,
285
- fixedWidth: false,
286
- styleClassPassthrough: [],
287
- itemVariant: "simple",
288
- showBorders: false,
289
- showNumbers: false,
290
- };
291
-
292
- export const CustomStyles = Template.bind({});
293
- CustomStyles.args = {
294
- gap: 12,
295
- minTileWidth: 320,
296
- fixedWidth: true,
297
- styleClassPassthrough: ["mi-auto", "mb-20"],
298
- itemVariant: "detailed",
299
- showBorders: true,
300
- showNumbers: true,
301
- };
302
-
303
- // Example with different content structure
304
- const Template2: StoryFn<MasonryGridOrderedStoryArgs> = (args) => ({
305
- components: {
306
- StorybookComponent,
307
- },
308
- setup() {
309
- return { args };
310
- },
311
- template: `
312
- <div style="padding: 20px; max-width: 1200px; margin: 0 auto;">
313
- <div style="margin-bottom: 20px;">
314
- <h3 style="margin-bottom: 10px;">Custom Content Example</h3>
315
- <p style="color: #666; margin-bottom: 20px;">
316
- Showing how different content can be displayed in the masonry grid
317
- </p>
318
- </div>
319
-
320
- <StorybookComponent
321
- :gridData="args.gridData"
322
- :gap="args.gap"
323
- :min-tile-width="args.minTileWidth"
324
- :fixed-width="args.fixedWidth"
325
- :styleClassPassthrough="args.styleClassPassthrough"
326
- >
327
- <template v-for="(item, index) in args.gridData" v-slot:[item.id]>
328
- <div class="p-16 bg-gray-1 rounded-8 border border-1 border-gray-6">
329
- <div style="display: flex; align-items: center; margin-bottom: 12px;">
330
- <div
331
- style="width: 32px; height: 32px; border-radius: 50%; background: linear-gradient(45deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; margin-right: 12px; font-size: 14px;"
332
- >
333
- {{ index + 1 }}
334
- </div>
335
- <h4 class="text-normal wght-700" style="margin: 0;">{{ item.author }}</h4>
336
- </div>
337
- <blockquote class="text-normal" style="font-style: italic; border-left: 3px solid #667eea; padding-left: 12px; margin: 0;">
338
- "{{ item.quote }}"
339
- </blockquote>
340
- </div>
341
- </template>
342
- </StorybookComponent>
343
- </div>
344
- `,
345
- });
346
-
347
- export const RichContent = Template2.bind({});
348
- RichContent.args = {
349
- gridData: sampleQuotes.slice(0, 6),
350
- gap: 16,
351
- minTileWidth: 320,
352
- fixedWidth: false,
353
- styleClassPassthrough: ["mi-auto"],
354
- };