srcdev-nuxt-components 9.0.15 → 9.0.16

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 (107) hide show
  1. package/.claude/settings.json +25 -0
  2. package/.claude/skills/component-aria-landmark.md +68 -0
  3. package/.claude/skills/component-dynamic-slots.md +150 -0
  4. package/.claude/skills/component-local-style-override.md +126 -0
  5. package/.claude/skills/component-prop-driven-container-layout.md +42 -0
  6. package/.claude/skills/components/accordian-core.md +159 -0
  7. package/.claude/skills/components/contact-section.md +101 -0
  8. package/.claude/skills/components/expanding-panel.md +156 -0
  9. package/.claude/skills/components/eyebrow-text.md +25 -0
  10. package/.claude/skills/components/hero-text.md +25 -0
  11. package/.claude/skills/components/layout-grid-by-cols.md +147 -0
  12. package/.claude/skills/components/layout-row.md +35 -0
  13. package/.claude/skills/components/link-text.md +33 -0
  14. package/.claude/skills/components/page-hero-highlights.md +224 -0
  15. package/.claude/skills/components/services-card.md +28 -0
  16. package/.claude/skills/components/services-section.md +25 -0
  17. package/.claude/skills/components/stepper-list.md +227 -0
  18. package/.claude/skills/css-grid-max-width-gutters.md +67 -0
  19. package/.claude/skills/index.md +14 -3
  20. package/.claude/skills/storybook-add-story.md +60 -0
  21. package/.claude/skills/testing-add-unit-test.md +56 -0
  22. package/app/assets/styles/setup/01.config/index.css +0 -1
  23. package/app/assets/styles/setup/03.theming/default/_dark.css +2 -2
  24. package/app/assets/styles/setup/04.elements/forms/02.typography.css +1 -0
  25. package/app/assets/styles/setup/05.typography/02.utility-classes/_font-classes-page-link.css +14 -14
  26. package/app/assets/styles/setup/index.css +0 -1
  27. package/app/components/01.atoms/card/CardCore.vue +92 -0
  28. package/app/components/01.atoms/card/stories/CardCore.stories.ts +132 -0
  29. package/app/components/01.atoms/card/tests/CardCore.spec.ts +207 -0
  30. package/app/components/01.atoms/card/tests/__snapshots__/CardCore.spec.ts.snap +43 -0
  31. package/app/components/01.atoms/content-wrappers/content-columns-2/ContentColumns2.vue +51 -0
  32. package/app/components/01.atoms/content-wrappers/content-columns-2/stories/ContentColumns2.stories.ts +110 -0
  33. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/ContentColumns2.spec.ts +105 -0
  34. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/__snapshots__/ContentColumns2.spec.ts.snap +14 -0
  35. package/app/components/01.atoms/content-wrappers/content-width/ContentWidth.vue +88 -0
  36. package/app/components/01.atoms/content-wrappers/content-width/stories/ContentWidth.stories.ts +362 -0
  37. package/app/components/01.atoms/content-wrappers/content-width/tests/ContentWidth.spec.ts +132 -0
  38. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +71 -0
  39. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +219 -0
  40. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +174 -0
  41. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  42. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  43. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue +70 -0
  44. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/stories/LayoutGridByWidth.stories.ts +220 -0
  45. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/LayoutGridByWidth.spec.ts +174 -0
  46. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  47. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  48. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByWidth.spec.ts.snap +36 -0
  49. package/app/components/01.atoms/text-blocks/eyebrow-text/stories/EyebrowText.stories.ts +1 -1
  50. package/app/components/01.atoms/text-blocks/hero-text/stories/HeroText.stories.ts +1 -1
  51. package/app/components/01.atoms/text-blocks/link-text/stories/LinkText.stories.ts +1 -1
  52. package/app/components/02.molecules/contact-section/stories/ContactSection.stories.ts +5 -0
  53. package/app/components/02.molecules/contact-section/tests/ContactSection.spec.ts +15 -0
  54. package/app/components/02.molecules/contact-section/tests/ContactSection.vue +25 -17
  55. package/app/components/{accordian → 02.molecules/expandable/accordian}/stories/AccordianCore.stories.ts +1 -1
  56. package/app/components/02.molecules/expandable/expanding-panel/stories/ExpandingPanel.stories.ts +245 -0
  57. package/app/components/02.molecules/expandable/expanding-panel/tests/ExpandingPanel.spec.ts +351 -0
  58. package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +38 -0
  59. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontal.vue +139 -0
  60. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontalAdvanced.vue +172 -0
  61. package/app/components/02.molecules/profile-section/ProfileSection.vue +2 -3
  62. package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +2 -2
  63. package/app/components/02.molecules/stepper-list/StepperList.vue +131 -92
  64. package/app/components/02.molecules/stepper-list/stories/StepperList.stories.ts +31 -0
  65. package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +24 -0
  66. package/app/components/02.molecules/stepper-list/tests/__snapshots__/StepperList.spec.ts.snap +22 -9
  67. package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +782 -0
  68. package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +233 -0
  69. package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +226 -0
  70. package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +69 -0
  71. package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +1 -1
  72. package/app/components/03.organisms/services/services-grids/ServicesSectionGrid.vue +1 -1
  73. package/app/components/03.organisms/services/services-section/ServicesSection.vue +2 -3
  74. package/app/components/04.templates/page-hero-highlights/PageHeroHighlights.vue +239 -0
  75. package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlights.stories.ts +404 -0
  76. package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +198 -0
  77. package/app/components/04.templates/page-hero-highlights/tests/__snapshots__/PageHeroHighlights.spec.ts.snap +19 -0
  78. package/app/components/container-glow/ContainerGlowCore.vue +20 -27
  79. package/app/components/forms/input-button/InputButtonCore.vue +105 -104
  80. package/app/components/glowing-border/stories/GlowingBorder.stories.ts +21 -21
  81. package/app/composables/useAriaLabelledById.ts +13 -0
  82. package/app/layouts/default.vue +8 -3
  83. package/app/pages/forms/examples/buttons/index.vue +6 -6
  84. package/app/pages/forms/examples/material/checkbox-radio-panels.vue +3 -3
  85. package/app/pages/forms/examples/material/text-fields.vue +607 -610
  86. package/app/pages/page-hero-highlights.vue +81 -0
  87. package/app/pages/ui/{display-card.vue → card-core.vue} +15 -15
  88. package/app/pages/ui/contact-section.vue +1 -1
  89. package/app/pages/ui/container-glow.vue +1 -1
  90. package/app/pages/ui/content-width.vue +126 -0
  91. package/app/pages/ui/glowing-border.vue +9 -9
  92. package/app/pages/ui/navigation/navigation-horizontal.vue +493 -0
  93. package/app/pages/ui/services/services-section/[slug].vue +3 -1
  94. package/package.json +2 -2
  95. package/app/assets/styles/setup/01.config/_basic-resets.css +0 -9
  96. package/app/components/content-columns/TwoColumns.vue +0 -59
  97. package/app/components/content-columns/stories/TwoColumns.stories.ts +0 -561
  98. package/app/components/content-containers/ContentContainer.vue +0 -89
  99. package/app/components/content-containers/stories/ContentContainer.stories.ts +0 -465
  100. package/app/components/content-grid/ContentGrid.vue +0 -85
  101. package/app/components/display-card/DisplayCard.vue +0 -122
  102. package/app/components/image-galleries/SliderGallery.vue +0 -786
  103. package/app/pages/ui/content-container.vue +0 -112
  104. /package/app/components/{accordian → 02.molecules/expandable/accordian}/AccordianCore.vue +0 -0
  105. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/AccordianCore.spec.ts +0 -0
  106. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/__snapshots__/AccordianCore.spec.ts.snap +0 -0
  107. /package/app/components/{expanding-panel → 02.molecules/expandable/expanding-panel}/ExpandingPanel.vue +0 -0
@@ -1,561 +0,0 @@
1
- import type { Meta, StoryFn } from "@nuxtjs/storybook";
2
- import TwoColumnsComponent from "../TwoColumns.vue";
3
-
4
- // Define the args interface
5
- interface TwoColumnsArgs {
6
- dataTestid: string;
7
- tag: string;
8
- styleClassPassthrough: string[];
9
- }
10
-
11
- export default {
12
- title: "Components/Layouts/TwoColumns",
13
- component: TwoColumnsComponent,
14
- argTypes: {
15
- // Semantic
16
- tag: {
17
- control: { type: "select" },
18
- options: ["div", "section", "article", "aside", "header", "footer", "main", "nav"],
19
- description: "HTML tag to render as",
20
- table: {
21
- category: "Semantic",
22
- },
23
- },
24
- // Content
25
- dataTestid: {
26
- control: { type: "text" },
27
- description: "Test ID for the component",
28
- table: {
29
- category: "Testing",
30
- },
31
- },
32
- // Hide complex props
33
- styleClassPassthrough: {
34
- table: {
35
- disable: true,
36
- },
37
- },
38
- },
39
- args: {
40
- tag: "div",
41
- dataTestid: "two-column-layout",
42
- styleClassPassthrough: [],
43
- },
44
- parameters: {
45
- docs: {
46
- description: {
47
- component:
48
- "A responsive two-column layout component that uses CSS Container Queries. Displays content in a single column on smaller containers (< 1064px) and switches to a two-column grid layout on larger containers (≥ 1064px).",
49
- },
50
- },
51
- },
52
- } as Meta<TwoColumnsArgs>;
53
-
54
- const Template: StoryFn<TwoColumnsArgs> = (args) => ({
55
- components: { TwoColumnsComponent },
56
- setup() {
57
- return { args };
58
- },
59
- template: `
60
- <div style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); padding: 40px 20px; min-height: 60vh;">
61
- <TwoColumnsComponent
62
- :data-testid="args.dataTestid"
63
- :tag="args.tag"
64
- :style-class-passthrough="args.styleClassPassthrough"
65
- >
66
- <template #col1>
67
- <div style="padding: 24px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); height: 100%;">
68
- <h3 style="margin: 0 0 16px 0; color: #1e40af; font-size: 20px; font-weight: 600;">
69
- 🏠 Left Column
70
- </h3>
71
- <p style="margin: 0 0 16px 0; color: #374151; line-height: 1.6;">
72
- This is the first column content. On smaller containers (< 1064px), this will appear above the second column in a single-column layout.
73
- </p>
74
- <div style="padding: 16px; background: #dbeafe; border-radius: 8px; border-left: 4px solid #3b82f6;">
75
- <p style="margin: 0; color: #1e40af; font-size: 14px; font-weight: 500;">
76
- 💡 Container Query: This layout responds to the container width, not the viewport width.
77
- </p>
78
- </div>
79
- </div>
80
- </template>
81
- <template #col2>
82
- <div style="padding: 24px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); height: 100%;">
83
- <h3 style="margin: 0 0 16px 0; color: #dc2626; font-size: 20px; font-weight: 600;">
84
- 🎯 Right Column
85
- </h3>
86
- <p style="margin: 0 0 16px 0; color: #374151; line-height: 1.6;">
87
- This is the second column content. When the container reaches 1064px or wider, both columns will display side by side with equal widths.
88
- </p>
89
- <div style="padding: 16px; background: #fecaca; border-radius: 8px; border-left: 4px solid #ef4444;">
90
- <p style="margin: 0; color: #dc2626; font-size: 14px; font-weight: 500;">
91
- 🚀 Responsive: Automatic mobile-first responsive behavior without media queries.
92
- </p>
93
- </div>
94
- </div>
95
- </template>
96
- </TwoColumnsComponent>
97
- </div>
98
- `,
99
- });
100
-
101
- // ===== BASIC STORIES =====
102
-
103
- export const Default = Template.bind({});
104
- Default.args = {};
105
-
106
- // ===== SEMANTIC TAG STORIES =====
107
-
108
- const SemanticTemplate: StoryFn<TwoColumnsArgs> = (args) => ({
109
- components: { TwoColumnsComponent },
110
- setup() {
111
- const getTagInfo = (tag: string) => {
112
- const tagInfo = {
113
- div: { description: "Generic container", use: "Default wrapper for general content" },
114
- section: { description: "Thematic grouping", use: "Related content sections" },
115
- article: { description: "Self-contained content", use: "Blog posts, news articles" },
116
- aside: { description: "Tangentially related", use: "Sidebars, supplementary content" },
117
- header: { description: "Introductory content", use: "Page headers, section headers" },
118
- footer: { description: "Footer information", use: "Page footers, credits" },
119
- main: { description: "Main content", use: "Primary page content" },
120
- nav: { description: "Navigation links", use: "Navigation menus, site structure" },
121
- };
122
- return tagInfo[tag as keyof typeof tagInfo] || { description: "Generic container", use: "Default usage" };
123
- };
124
-
125
- return { args, getTagInfo };
126
- },
127
- template: `
128
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 40px 20px;">
129
- <TwoColumnsComponent
130
- :data-testid="args.dataTestid"
131
- :tag="args.tag"
132
- :style-class-passthrough="args.styleClassPassthrough"
133
- >
134
- <template #col1>
135
- <div style="padding: 30px; background: white; border-radius: 12px; text-align: center;">
136
- <div style="display: inline-block; padding: 8px 16px; background: #667eea; color: white; border-radius: 6px; font-family: monospace; font-size: 16px; margin-bottom: 20px;">
137
- &lt;{{ args.tag }}&gt;
138
- </div>
139
- <h3 style="margin: 0 0 12px 0; color: #374151; font-size: 20px;">
140
- {{ getTagInfo(args.tag).description }}
141
- </h3>
142
- <p style="margin: 0; color: #6b7280; line-height: 1.5;">
143
- {{ getTagInfo(args.tag).use }}
144
- </p>
145
- </div>
146
- </template>
147
- <template #col2>
148
- <div style="padding: 30px; background: rgba(255, 255, 255, 0.95); border-radius: 12px;">
149
- <h4 style="margin: 0 0 16px 0; color: #374151; font-size: 18px;">Semantic Benefits</h4>
150
- <ul style="margin: 0; color: #6b7280; line-height: 1.6; padding-left: 20px;">
151
- <li>Better accessibility for screen readers</li>
152
- <li>Improved SEO and document structure</li>
153
- <li>Clearer code intent and maintainability</li>
154
- <li>Enhanced landmark navigation</li>
155
- </ul>
156
- <div style="padding: 16px; background: #f0f9ff; border-radius: 8px; margin-top: 16px;">
157
- <p style="margin: 0; color: #3730a3; font-size: 14px; font-weight: 500;">
158
- Choose semantic tags that match your content's purpose and structure.
159
- </p>
160
- </div>
161
- </div>
162
- </template>
163
- </TwoColumnsComponent>
164
- </div>
165
- `,
166
- });
167
-
168
- export const SemanticSection = SemanticTemplate.bind({});
169
- SemanticSection.args = {
170
- tag: "section",
171
- };
172
-
173
- export const SemanticArticle = SemanticTemplate.bind({});
174
- SemanticArticle.args = {
175
- tag: "article",
176
- };
177
-
178
- export const SemanticAside = SemanticTemplate.bind({});
179
- SemanticAside.args = {
180
- tag: "aside",
181
- };
182
-
183
- // ===== CONTENT EXAMPLES =====
184
-
185
- const ContentExampleTemplate: StoryFn<TwoColumnsArgs> = (args) => ({
186
- components: { TwoColumnsComponent },
187
- setup() {
188
- return { args };
189
- },
190
- template: `
191
- <div style="background: #f9fafb; padding: 20px;">
192
- <TwoColumnsComponent
193
- :data-testid="args.dataTestid"
194
- :tag="args.tag"
195
- :style-class-passthrough="args.styleClassPassthrough"
196
- >
197
- <template #col1>
198
- <article style="padding: 32px; background: white; border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);">
199
- <h2 style="margin: 0 0 24px 0; color: #1f2937; font-size: 28px; font-weight: 700;">
200
- Understanding Container Queries
201
- </h2>
202
- <p style="margin: 0 0 20px 0; color: #374151; line-height: 1.7; font-size: 16px;">
203
- Container queries allow components to respond to their own size rather than the viewport size.
204
- This two-column layout demonstrates this concept perfectly.
205
- </p>
206
- <p style="margin: 0 0 20px 0; color: #374151; line-height: 1.7;">
207
- When the container is narrower than 1064px, content flows in a single column. Once it reaches
208
- that threshold, it switches to the two-column grid layout automatically.
209
- </p>
210
- <div style="padding: 20px; background: #f0f9ff; border-radius: 8px; border-left: 4px solid #3b82f6;">
211
- <h3 style="margin: 0 0 12px 0; color: #1e40af; font-size: 16px;">Key Advantages</h3>
212
- <ul style="margin: 0; color: #1e40af; line-height: 1.6;">
213
- <li>Component-based responsive design</li>
214
- <li>No dependency on viewport size</li>
215
- <li>Truly reusable across contexts</li>
216
- </ul>
217
- </div>
218
- </article>
219
- </template>
220
- <template #col2>
221
- <div style="padding: 32px; background: white; border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); height: fit-content;">
222
- <h3 style="margin: 0 0 20px 0; color: #1f2937; font-size: 22px; font-weight: 600;">
223
- Technical Implementation
224
- </h3>
225
-
226
- <div style="margin-bottom: 24px;">
227
- <h4 style="margin: 0 0 8px 0; color: #059669; font-size: 16px; font-weight: 600;">Container Setup</h4>
228
- <pre style="background: #1f2937; color: #e5e7eb; padding: 16px; border-radius: 6px; font-size: 12px; overflow-x: auto; margin: 0;"><code>container-type: inline-size;
229
- container-name: two-column-layout;</code></pre>
230
- </div>
231
-
232
- <div style="margin-bottom: 24px;">
233
- <h4 style="margin: 0 0 8px 0; color: #7c3aed; font-size: 16px; font-weight: 600;">Responsive Grid</h4>
234
- <pre style="background: #1f2937; color: #e5e7eb; padding: 16px; border-radius: 6px; font-size: 12px; overflow-x: auto; margin: 0;"><code>@container two-column-layout (width >= 1064px) {
235
- grid-template-columns: repeat(2, 1fr);
236
- }</code></pre>
237
- </div>
238
-
239
- <div style="padding: 16px; background: #f3f4f6; border-radius: 8px; border-left: 4px solid #6b7280;">
240
- <p style="margin: 0; color: #374151; font-size: 14px; line-height: 1.5;">
241
- This approach ensures consistent behavior regardless of where the component is placed
242
- in your application layout.
243
- </p>
244
- </div>
245
- </div>
246
- </template>
247
- </TwoColumnsComponent>
248
- </div>
249
- `,
250
- });
251
-
252
- export const TechnicalArticle = ContentExampleTemplate.bind({});
253
- TechnicalArticle.args = {
254
- tag: "article",
255
- };
256
- TechnicalArticle.parameters = {
257
- docs: {
258
- description: {
259
- story:
260
- "Example of a technical article layout showing how content flows between the two columns with detailed implementation information.",
261
- },
262
- },
263
- };
264
-
265
- // ===== FEATURE SHOWCASE STORIES =====
266
-
267
- const FeatureTemplate: StoryFn<TwoColumnsArgs> = (args) => ({
268
- components: { TwoColumnsComponent },
269
- setup() {
270
- return { args };
271
- },
272
- template: `
273
- <div style="background: linear-gradient(135deg, #fef3c7 0%, #fcd34d 100%); padding: 40px 20px;">
274
- <TwoColumnsComponent
275
- :data-testid="args.dataTestid"
276
- :tag="args.tag"
277
- :style-class-passthrough="args.styleClassPassthrough"
278
- >
279
- <template #col1>
280
- <div style="padding: 32px; background: white; border-radius: 16px; box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);">
281
- <div style="text-align: center; margin-bottom: 24px;">
282
- <div style="width: 80px; height: 80px; background: linear-gradient(135deg, #3b82f6, #1d4ed8); border-radius: 50%; margin: 0 auto 16px auto; display: flex; align-items: center; justify-content: center; font-size: 32px;">
283
-
284
- </div>
285
- <h3 style="margin: 0 0 8px 0; color: #1f2937; font-size: 24px; font-weight: 700;">
286
- Premium Features
287
- </h3>
288
- <p style="margin: 0; color: #6b7280; font-size: 16px;">
289
- Everything you need to succeed
290
- </p>
291
- </div>
292
-
293
- <div style="space-y: 16px;">
294
- <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 16px;">
295
- <div style="width: 24px; height: 24px; background: #10b981; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px;">
296
- <span style="color: white; font-size: 12px; font-weight: bold;">✓</span>
297
- </div>
298
- <div>
299
- <h4 style="margin: 0 0 4px 0; color: #374151; font-size: 16px; font-weight: 600;">Container Query Responsive</h4>
300
- <p style="margin: 0; color: #6b7280; font-size: 14px; line-height: 1.5;">Adapts to container size, not viewport</p>
301
- </div>
302
- </div>
303
-
304
- <div style="display: flex; align-items: start; gap: 12px; margin-bottom: 16px;">
305
- <div style="width: 24px; height: 24px; background: #10b981; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px;">
306
- <span style="color: white; font-size: 12px; font-weight: bold;">✓</span>
307
- </div>
308
- <div>
309
- <h4 style="margin: 0 0 4px 0; color: #374151; font-size: 16px; font-weight: 600;">Semantic HTML Support</h4>
310
- <p style="margin: 0; color: #6b7280; font-size: 14px; line-height: 1.5;">Choose from 8 semantic HTML tags</p>
311
- </div>
312
- </div>
313
-
314
- <div style="display: flex; align-items: start; gap: 12px;">
315
- <div style="width: 24px; height: 24px; background: #10b981; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 2px;">
316
- <span style="color: white; font-size: 12px; font-weight: bold;">✓</span>
317
- </div>
318
- <div>
319
- <h4 style="margin: 0 0 4px 0; color: #374151; font-size: 16px; font-weight: 600;">Flexible Content Slots</h4>
320
- <p style="margin: 0; color: #6b7280; font-size: 14px; line-height: 1.5;">Named slots for organized content</p>
321
- </div>
322
- </div>
323
- </div>
324
- </div>
325
- </template>
326
- <template #col2>
327
- <div style="padding: 32px; background: white; border-radius: 16px; box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);">
328
- <h3 style="margin: 0 0 20px 0; color: #1f2937; font-size: 22px; font-weight: 600;">
329
- 💡 How It Works
330
- </h3>
331
-
332
- <div style="margin-bottom: 24px; padding: 20px; background: #f8fafc; border-radius: 12px; border: 2px solid #e2e8f0;">
333
- <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
334
- <div style="width: 32px; height: 32px; background: #3b82f6; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">1</div>
335
- <h4 style="margin: 0; color: #374151; font-size: 16px; font-weight: 600;">Mobile First</h4>
336
- </div>
337
- <p style="margin: 0; color: #64748b; font-size: 14px; line-height: 1.5;">
338
- Content stacks vertically in a single column layout on smaller containers
339
- </p>
340
- </div>
341
-
342
- <div style="margin-bottom: 24px; padding: 20px; background: #f0fdf4; border-radius: 12px; border: 2px solid #bbf7d0;">
343
- <div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
344
- <div style="width: 32px; height: 32px; background: #10b981; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">2</div>
345
- <h4 style="margin: 0; color: #374151; font-size: 16px; font-weight: 600;">Desktop Responsive</h4>
346
- </div>
347
- <p style="margin: 0; color: #059669; font-size: 14px; line-height: 1.5;">
348
- Automatically switches to two-column grid when container reaches 1064px
349
- </p>
350
- </div>
351
-
352
- <div style="padding: 16px; background: #fffbeb; border-radius: 8px; border-left: 4px solid #f59e0b;">
353
- <p style="margin: 0; color: #92400e; font-size: 14px; line-height: 1.5; font-weight: 500;">
354
- 🎯 Perfect for dashboards, content layouts, and component libraries where context matters more than screen size.
355
- </p>
356
- </div>
357
- </div>
358
- </template>
359
- </TwoColumnsComponent>
360
- </div>
361
- `,
362
- });
363
-
364
- export const FeatureShowcase = FeatureTemplate.bind({});
365
- FeatureShowcase.args = {};
366
- FeatureShowcase.parameters = {
367
- docs: {
368
- description: {
369
- story:
370
- "Feature showcase demonstrating the key capabilities and benefits of the TwoColumns component with visual examples.",
371
- },
372
- },
373
- };
374
-
375
- // ===== SINGLE COLUMN DEMONSTRATION =====
376
-
377
- const SingleColumnTemplate: StoryFn<TwoColumnsArgs> = (args) => ({
378
- components: { TwoColumnsComponent },
379
- setup() {
380
- return { args };
381
- },
382
- template: `
383
- <div style="background: #f3f4f6; padding: 20px;">
384
- <div style="margin-bottom: 24px; text-align: center;">
385
- <h2 style="margin: 0 0 8px 0; color: #374151; font-size: 24px;">Single Column Content</h2>
386
- <p style="margin: 0; color: #6b7280;">Only one slot provided - layout adapts accordingly</p>
387
- </div>
388
-
389
- <TwoColumnsComponent
390
- :data-testid="args.dataTestid"
391
- :tag="args.tag"
392
- :style-class-passthrough="args.styleClassPassthrough"
393
- >
394
- <template #col1>
395
- <div style="padding: 32px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);">
396
- <h3 style="margin: 0 0 16px 0; color: #7c3aed; font-size: 22px; font-weight: 600;">
397
- 🎨 Creative Content Block
398
- </h3>
399
- <p style="margin: 0 0 20px 0; color: #374151; line-height: 1.7; font-size: 16px;">
400
- When only one column is provided, the component gracefully handles the single-column layout.
401
- This demonstrates the component's flexibility in handling partial content scenarios.
402
- </p>
403
-
404
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin: 20px 0;">
405
- <div style="padding: 16px; background: #fef3c7; border-radius: 8px; text-align: center;">
406
- <div style="font-size: 24px; margin-bottom: 8px;">📱</div>
407
- <h4 style="margin: 0 0 4px 0; color: #92400e; font-size: 14px; font-weight: 600;">Mobile</h4>
408
- <p style="margin: 0; color: #b45309; font-size: 12px;">Single column</p>
409
- </div>
410
- <div style="padding: 16px; background: #dbeafe; border-radius: 8px; text-align: center;">
411
- <div style="font-size: 24px; margin-bottom: 8px;">💻</div>
412
- <h4 style="margin: 0 0 4px 0; color: #1e40af; font-size: 14px; font-weight: 600;">Desktop</h4>
413
- <p style="margin: 0; color: #1e40af; font-size: 12px;">Still single column</p>
414
- </div>
415
- </div>
416
-
417
- <div style="padding: 20px; background: #f0fdf4; border-radius: 10px; border-left: 4px solid #10b981;">
418
- <h4 style="margin: 0 0 8px 0; color: #059669; font-size: 16px;">Flexible Architecture</h4>
419
- <p style="margin: 0; color: #065f46; line-height: 1.5;">
420
- The component only renders columns that have content, making it perfect for dynamic
421
- content scenarios where you might not always have content for both columns.
422
- </p>
423
- </div>
424
- </div>
425
- </template>
426
- <!-- col2 intentionally left empty -->
427
- </TwoColumnsComponent>
428
- </div>
429
- `,
430
- });
431
-
432
- export const SingleColumn = SingleColumnTemplate.bind({});
433
- SingleColumn.args = {};
434
- SingleColumn.parameters = {
435
- docs: {
436
- description: {
437
- story:
438
- "Demonstrates the component's behavior when only one column has content - shows the graceful handling of partial content scenarios.",
439
- },
440
- },
441
- };
442
-
443
- // ===== RESPONSIVE DEMONSTRATION =====
444
-
445
- const ResponsiveTemplate: StoryFn = () => ({
446
- components: { TwoColumnsComponent },
447
- template: `
448
- <div style="background: #f8fafc; padding: 20px;">
449
- <div style="margin-bottom: 40px; text-align: center;">
450
- <h2 style="margin: 0 0 16px 0; color: #374151; font-size: 28px;">
451
- 🔄 Responsive Behavior Demo
452
- </h2>
453
- <p style="margin: 0 0 32px 0; color: #6b7280; max-width: 600px; margin-left: auto; margin-right: auto; line-height: 1.6;">
454
- Resize your browser to see how the layout responds to container width changes.
455
- The breakpoint is at 1064px container width, not viewport width.
456
- </p>
457
- </div>
458
-
459
- <!-- Small container demonstration -->
460
- <div style="margin-bottom: 40px;">
461
- <h3 style="margin: 0 0 16px 0; color: #374151;">📱 Narrow Container (< 1064px)</h3>
462
- <div style="max-width: 800px; border: 2px dashed #cbd5e1; padding: 20px; margin-bottom: 20px;">
463
- <TwoColumnsComponent tag="div">
464
- <template #col1>
465
- <div style="padding: 20px; background: #fef3c7; border-radius: 8px; margin-bottom: 16px;">
466
- <h4 style="margin: 0 0 8px 0; color: #92400e; font-size: 16px;">Column 1</h4>
467
- <p style="margin: 0; color: #b45309; font-size: 14px;">Stacked vertically</p>
468
- </div>
469
- </template>
470
- <template #col2>
471
- <div style="padding: 20px; background: #fecaca; border-radius: 8px;">
472
- <h4 style="margin: 0 0 8px 0; color: #dc2626; font-size: 16px;">Column 2</h4>
473
- <p style="margin: 0; color: #b91c1c; font-size: 14px;">Appears below Column 1</p>
474
- </div>
475
- </template>
476
- </TwoColumnsComponent>
477
- </div>
478
- </div>
479
-
480
- <!-- Large container demonstration -->
481
- <div style="margin-bottom: 40px;">
482
- <h3 style="margin: 0 0 16px 0; color: #374151;">🖥️ Wide Container (≥ 1064px)</h3>
483
- <div style="border: 2px dashed #cbd5e1; padding: 20px;">
484
- <TwoColumnsComponent tag="div">
485
- <template #col1>
486
- <div style="padding: 20px; background: #dcfce7; border-radius: 8px;">
487
- <h4 style="margin: 0 0 8px 0; color: #166534; font-size: 16px;">Column 1</h4>
488
- <p style="margin: 0; color: #15803d; font-size: 14px;">Side-by-side layout</p>
489
- </div>
490
- </template>
491
- <template #col2>
492
- <div style="padding: 20px; background: #ddd6fe; border-radius: 8px;">
493
- <h4 style="margin: 0 0 8px 0; color: #7c3aed; font-size: 16px;">Column 2</h4>
494
- <p style="margin: 0; color: #6d28d9; font-size: 14px;">Equal width columns with 32px gap</p>
495
- </div>
496
- </template>
497
- </TwoColumnsComponent>
498
- </div>
499
- </div>
500
-
501
- <!-- Technical explanation -->
502
- <TwoColumnsComponent tag="section">
503
- <template #col1>
504
- <div style="padding: 24px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);">
505
- <h3 style="margin: 0 0 16px 0; color: #374151; font-size: 20px; font-weight: 600;">⚙️ How It Works</h3>
506
- <div style="space-y: 16px;">
507
- <div style="padding: 16px; background: #f1f5f9; border-radius: 8px; border-left: 4px solid #3b82f6; margin-bottom: 16px;">
508
- <h4 style="margin: 0 0 8px 0; color: #1e40af; font-size: 14px; font-weight: 600;">Container Queries</h4>
509
- <p style="margin: 0; color: #475569; font-size: 14px; line-height: 1.5;">
510
- Uses <code>@container</code> to respond to the component's width, not the browser viewport.
511
- </p>
512
- </div>
513
-
514
- <div style="padding: 16px; background: #f0fdf4; border-radius: 8px; border-left: 4px solid #22c55e; margin-bottom: 16px;">
515
- <h4 style="margin: 0 0 8px 0; color: #15803d; font-size: 14px; font-weight: 600;">CSS Grid Layout</h4>
516
- <p style="margin: 0; color: #166534; font-size: 14px; line-height: 1.5;">
517
- Switches from <code>grid-auto-flow: row</code> to <code>grid-template-columns: repeat(2, 1fr)</code>
518
- </p>
519
- </div>
520
-
521
- <div style="padding: 16px; background: #fefce8; border-radius: 8px; border-left: 4px solid #eab308;">
522
- <h4 style="margin: 0 0 8px 0; color: #a16207; font-size: 14px; font-weight: 600;">1064px Breakpoint</h4>
523
- <p style="margin: 0; color: #92400e; font-size: 14px; line-height: 1.5;">
524
- Optimal width for two-column layouts with comfortable reading experience.
525
- </p>
526
- </div>
527
- </div>
528
- </div>
529
- </template>
530
- <template #col2>
531
- <div style="padding: 24px; background: white; border-radius: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);">
532
- <h3 style="margin: 0 0 16px 0; color: #374151; font-size: 20px; font-weight: 600;">📊 Benefits</h3>
533
- <ul style="margin: 0; color: #374151; line-height: 1.7; padding-left: 20px;">
534
- <li><strong>Component Reusability:</strong> Works in any container context</li>
535
- <li><strong>Performance:</strong> No JavaScript required for responsive behavior</li>
536
- <li><strong>Maintainability:</strong> Self-contained responsive logic</li>
537
- <li><strong>User Experience:</strong> Smooth, predictable layout transitions</li>
538
- </ul>
539
-
540
- <div style="padding: 20px; background: #fef7ff; border-radius: 10px; margin-top: 20px; border-left: 4px solid #a855f7;">
541
- <p style="margin: 0; color: #7c3aed; font-size: 14px; line-height: 1.6; font-weight: 500;">
542
- 💡 <strong>Pro Tip:</strong> Container queries make this component truly modular - it behaves
543
- consistently whether it's in a sidebar, main content area, or modal dialog.
544
- </p>
545
- </div>
546
- </div>
547
- </template>
548
- </TwoColumnsComponent>
549
- </div>
550
- `,
551
- });
552
-
553
- export const ResponsiveBehavior = ResponsiveTemplate.bind({});
554
- ResponsiveBehavior.parameters = {
555
- docs: {
556
- description: {
557
- story:
558
- "Interactive demonstration showing how the TwoColumns component responds to different container widths using CSS Container Queries. The layout switches from single-column to two-column at 1064px container width.",
559
- },
560
- },
561
- };
@@ -1,89 +0,0 @@
1
- <template>
2
- <component
3
- :is="tag"
4
- :id
5
- class="content-container-wrapper"
6
- :class="elementClasses"
7
- :tab-index="isLandmark ? 0 : null"
8
- :aria-label="isLandmark ? 'Content Container Landmark' : undefined"
9
- >
10
- <div class="content-container">
11
- <div class="content-container-inner" :data-testid="dataTestid">
12
- <slot name="default"></slot>
13
- </div>
14
- </div>
15
- </component>
16
- </template>
17
-
18
- <script setup lang="ts">
19
- const props = defineProps({
20
- dataTestid: {
21
- type: String,
22
- default: "content-container",
23
- },
24
- tag: {
25
- type: String,
26
- default: "div",
27
- validator(value: string) {
28
- return ["div", "section", "article", "aside", "header", "footer", "main", "nav", "ul", "ol"].includes(value);
29
- },
30
- },
31
- id: {
32
- type: String,
33
- default: null,
34
- },
35
- styleClassPassthrough: {
36
- type: [String, Array] as PropType<string | string[]>,
37
- default: () => [],
38
- },
39
- isLandmark: {
40
- type: Boolean,
41
- default: false,
42
- },
43
- });
44
-
45
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
46
- </script>
47
-
48
- <style lang="css">
49
- @layer components {
50
- .content-container-wrapper {
51
- container-type: inline-size;
52
- container-name: content-container;
53
-
54
- .content-container {
55
- --gutter: 16px;
56
- --content-max-width: auto;
57
- --justify-content: initial;
58
-
59
- display: grid;
60
-
61
- grid-template-columns:
62
- [gutter-start]
63
- var(--gutter)
64
- [content-start]
65
- var(--content-max-width)
66
- [content-end]
67
- var(--gutter)
68
- [gutter-end];
69
-
70
- justify-content: var(--justify-content);
71
- box-sizing: border-box;
72
-
73
- @container content-container (width >= 1092px) {
74
- --gutter: 0;
75
- --content-max-width: 1064px;
76
- --justify-content: center;
77
- }
78
-
79
- .content-container-inner {
80
- grid-column: content;
81
-
82
- @container content-container (width >= 1092px) {
83
- grid-column: gutter;
84
- }
85
- }
86
- }
87
- }
88
- }
89
- </style>