Restructure layout components architecture
- Move layout components from layouts/ directory to components/layout/ - Reorganize divider component from data-display to layout category - Add comprehensive layout component collection including aspect-ratio, bento-grid, box, breakpoint-container, center, column, dashboard-shell, feed-layout, flex, grid-container, hstack, list-detail-layout, scroll-container, section, sidebar-layout, stack, supporting-pane-layout, tabs-container, and vstack - Update all demo components to match new layout structure - Refactor routing and index exports to reflect reorganized component architecture 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
@use '../../../../../ui-design-system/src/styles/semantic/index' as *;
|
||||
|
||||
.demo-container {
|
||||
padding: $semantic-spacing-component-lg;
|
||||
background: $semantic-color-surface;
|
||||
min-height: 100vh;
|
||||
|
||||
h2 {
|
||||
font-family: map-get($semantic-typography-heading-h2, font-family);
|
||||
font-size: map-get($semantic-typography-heading-h2, font-size);
|
||||
font-weight: map-get($semantic-typography-heading-h2, font-weight);
|
||||
line-height: map-get($semantic-typography-heading-h2, line-height);
|
||||
color: $semantic-color-text-primary;
|
||||
margin-bottom: $semantic-spacing-content-heading;
|
||||
border-bottom: $semantic-border-width-1 solid $semantic-color-border-secondary;
|
||||
padding-bottom: $semantic-spacing-component-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-section {
|
||||
margin-bottom: $semantic-spacing-layout-section-lg;
|
||||
|
||||
h3 {
|
||||
font-family: map-get($semantic-typography-heading-h3, font-family);
|
||||
font-size: map-get($semantic-typography-heading-h3, font-size);
|
||||
font-weight: map-get($semantic-typography-heading-h3, font-weight);
|
||||
line-height: map-get($semantic-typography-heading-h3, line-height);
|
||||
color: $semantic-color-text-primary;
|
||||
margin-bottom: $semantic-spacing-component-md;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: $semantic-spacing-grid-gap-md;
|
||||
margin-bottom: $semantic-spacing-component-lg;
|
||||
}
|
||||
|
||||
.demo-card {
|
||||
border: $semantic-border-width-1 solid $semantic-color-border-secondary;
|
||||
border-radius: $semantic-border-card-radius;
|
||||
background: $semantic-color-surface-secondary;
|
||||
padding: $semantic-spacing-component-md;
|
||||
|
||||
h4 {
|
||||
font-family: map-get($semantic-typography-heading-h4, font-family);
|
||||
font-size: map-get($semantic-typography-heading-h4, font-size);
|
||||
font-weight: map-get($semantic-typography-heading-h4, font-weight);
|
||||
line-height: map-get($semantic-typography-heading-h4, line-height);
|
||||
color: $semantic-color-text-primary;
|
||||
margin-bottom: $semantic-spacing-component-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-demo-container {
|
||||
height: 300px;
|
||||
border: $semantic-border-width-1 solid $semantic-color-border-subtle;
|
||||
border-radius: $semantic-border-radius-sm;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&--interactive {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.demo-content {
|
||||
padding: $semantic-spacing-component-md;
|
||||
color: $semantic-color-text-primary;
|
||||
|
||||
h4, h5 {
|
||||
font-family: map-get($semantic-typography-heading-h4, font-family);
|
||||
font-size: map-get($semantic-typography-heading-h4, font-size);
|
||||
font-weight: map-get($semantic-typography-heading-h4, font-weight);
|
||||
line-height: map-get($semantic-typography-heading-h4, line-height);
|
||||
margin-bottom: $semantic-spacing-component-xs;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: map-get($semantic-typography-body-medium, font-family);
|
||||
font-size: map-get($semantic-typography-body-medium, font-size);
|
||||
font-weight: map-get($semantic-typography-body-medium, font-weight);
|
||||
line-height: map-get($semantic-typography-body-medium, line-height);
|
||||
color: $semantic-color-text-secondary;
|
||||
margin-bottom: $semantic-spacing-content-paragraph;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
padding: $semantic-spacing-content-line-tight;
|
||||
color: $semantic-color-text-secondary;
|
||||
border-bottom: $semantic-border-width-1 solid $semantic-color-border-subtle;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar content styling
|
||||
[slot="sidebar"] {
|
||||
color: $semantic-color-text-primary;
|
||||
|
||||
h5 {
|
||||
font-family: map-get($semantic-typography-heading-h5, font-family);
|
||||
font-size: map-get($semantic-typography-heading-h5, font-size);
|
||||
font-weight: map-get($semantic-typography-heading-h5, font-weight);
|
||||
line-height: map-get($semantic-typography-heading-h5, line-height);
|
||||
margin-bottom: $semantic-spacing-component-sm;
|
||||
color: $semantic-color-text-primary;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
padding: $semantic-spacing-component-xs;
|
||||
margin-bottom: $semantic-spacing-component-xs;
|
||||
border-radius: $semantic-border-radius-sm;
|
||||
color: $semantic-color-text-secondary;
|
||||
cursor: pointer;
|
||||
transition: all $semantic-motion-duration-fast $semantic-motion-easing-ease;
|
||||
|
||||
&:hover {
|
||||
background: $semantic-color-surface-elevated;
|
||||
color: $semantic-color-text-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav ul li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $semantic-spacing-component-xs;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $semantic-spacing-component-md;
|
||||
margin-bottom: $semantic-spacing-component-lg;
|
||||
padding: $semantic-spacing-component-md;
|
||||
background: $semantic-color-surface-elevated;
|
||||
border-radius: $semantic-border-radius-md;
|
||||
border: $semantic-border-width-1 solid $semantic-color-border-secondary;
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $semantic-spacing-component-xs;
|
||||
font-family: map-get($semantic-typography-label, font-family);
|
||||
font-size: map-get($semantic-typography-label, font-size);
|
||||
font-weight: map-get($semantic-typography-label, font-weight);
|
||||
line-height: map-get($semantic-typography-label, line-height);
|
||||
color: $semantic-color-text-primary;
|
||||
|
||||
select, input {
|
||||
padding: $semantic-spacing-interactive-input-padding-y $semantic-spacing-interactive-input-padding-x;
|
||||
border: $semantic-border-width-1 solid $semantic-color-border-primary;
|
||||
border-radius: $semantic-border-input-radius;
|
||||
background: $semantic-color-surface;
|
||||
color: $semantic-color-text-primary;
|
||||
font-family: map-get($semantic-typography-input, font-family);
|
||||
font-size: map-get($semantic-typography-input, font-size);
|
||||
transition: border-color $semantic-motion-duration-fast $semantic-motion-easing-ease;
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid $semantic-color-focus;
|
||||
outline-offset: 2px;
|
||||
border-color: $semantic-color-border-focus;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
width: auto;
|
||||
margin-right: $semantic-spacing-component-xs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.demo-button {
|
||||
padding: $semantic-spacing-interactive-button-padding-y $semantic-spacing-interactive-button-padding-x;
|
||||
background: $semantic-color-primary;
|
||||
color: $semantic-color-on-primary;
|
||||
border: none;
|
||||
border-radius: $semantic-border-button-radius;
|
||||
font-family: map-get($semantic-typography-button-medium, font-family);
|
||||
font-size: map-get($semantic-typography-button-medium, font-size);
|
||||
font-weight: map-get($semantic-typography-button-medium, font-weight);
|
||||
line-height: map-get($semantic-typography-button-medium, line-height);
|
||||
cursor: pointer;
|
||||
transition: all $semantic-motion-duration-fast $semantic-motion-easing-ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: $semantic-shadow-button-hover;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid $semantic-color-focus;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: $semantic-shadow-button-rest;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive design
|
||||
@media (max-width: 768px) {
|
||||
.demo-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.demo-controls {
|
||||
flex-direction: column;
|
||||
|
||||
label {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: $semantic-spacing-component-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-demo-container {
|
||||
height: 250px;
|
||||
|
||||
&--interactive {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { SidebarLayoutComponent } from '../../../../../ui-essentials/src/lib/components/layout/sidebar-layout/sidebar-layout.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-sidebar-layout-demo',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, SidebarLayoutComponent],
|
||||
template: `
|
||||
<div class="demo-container">
|
||||
<h2>Sidebar Layout Demo</h2>
|
||||
|
||||
<!-- Position Variants -->
|
||||
<section class="demo-section">
|
||||
<h3>Position Variants</h3>
|
||||
<div class="demo-row">
|
||||
<div class="demo-card">
|
||||
<h4>Left Sidebar (Default)</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout position="left" sidebarWidth="sm">
|
||||
<div slot="sidebar">
|
||||
<h5>Left Navigation</h5>
|
||||
<ul>
|
||||
<li>Dashboard</li>
|
||||
<li>Analytics</li>
|
||||
<li>Settings</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Main Content Area</h4>
|
||||
<p>This is the main content area with left sidebar navigation.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-card">
|
||||
<h4>Right Sidebar</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout position="right" sidebarWidth="sm">
|
||||
<div slot="sidebar">
|
||||
<h5>Right Panel</h5>
|
||||
<ul>
|
||||
<li>Quick Actions</li>
|
||||
<li>Recent Items</li>
|
||||
<li>Help</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Main Content Area</h4>
|
||||
<p>This is the main content area with right sidebar panel.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Width Variants -->
|
||||
<section class="demo-section">
|
||||
<h3>Sidebar Widths</h3>
|
||||
<div class="demo-row">
|
||||
@for (width of widths; track width) {
|
||||
<div class="demo-card">
|
||||
<h4>{{ width.toUpperCase() }} Width</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout [sidebarWidth]="width">
|
||||
<div slot="sidebar">
|
||||
<h5>{{ width.toUpperCase() }} Sidebar</h5>
|
||||
<p>Width: {{ width }}</p>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Content</h4>
|
||||
<p>Main content with {{ width }} sidebar.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Visual Variants -->
|
||||
<section class="demo-section">
|
||||
<h3>Visual Variants</h3>
|
||||
<div class="demo-row">
|
||||
@for (variant of variants; track variant) {
|
||||
<div class="demo-card">
|
||||
<h4>{{ variant | titlecase }}</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout [variant]="variant" sidebarWidth="sm">
|
||||
<div slot="sidebar">
|
||||
<h5>{{ variant | titlecase }} Style</h5>
|
||||
<ul>
|
||||
<li>Item One</li>
|
||||
<li>Item Two</li>
|
||||
<li>Item Three</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Content</h4>
|
||||
<p>Content area with {{ variant }} sidebar variant.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Collapse States -->
|
||||
<section class="demo-section">
|
||||
<h3>Collapse States</h3>
|
||||
<div class="demo-row">
|
||||
<div class="demo-card">
|
||||
<h4>Collapsed Sidebar</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout [collapsed]="true" collapseMode="collapsed">
|
||||
<div slot="sidebar">
|
||||
<h5>Nav</h5>
|
||||
<ul>
|
||||
<li>🏠</li>
|
||||
<li>📊</li>
|
||||
<li>⚙️</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Collapsed Mode</h4>
|
||||
<p>Sidebar is collapsed showing minimal width.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-card">
|
||||
<h4>Hidden Sidebar</h4>
|
||||
<div class="sidebar-demo-container">
|
||||
<ui-sidebar-layout [collapsed]="true" collapseMode="hidden">
|
||||
<div slot="sidebar">
|
||||
<h5>Hidden Sidebar</h5>
|
||||
<p>This sidebar is hidden when collapsed.</p>
|
||||
</div>
|
||||
<div class="demo-content">
|
||||
<h4>Hidden Mode</h4>
|
||||
<p>Sidebar is completely hidden, content takes full width.</p>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Interactive Example -->
|
||||
<section class="demo-section">
|
||||
<h3>Interactive Controls</h3>
|
||||
<div class="demo-controls">
|
||||
<label>
|
||||
Position:
|
||||
<select [(ngModel)]="interactivePosition">
|
||||
<option value="left">Left</option>
|
||||
<option value="right">Right</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Width:
|
||||
<select [(ngModel)]="interactiveWidth">
|
||||
<option value="sm">Small</option>
|
||||
<option value="md">Medium</option>
|
||||
<option value="lg">Large</option>
|
||||
<option value="xl">Extra Large</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Variant:
|
||||
<select [(ngModel)]="interactiveVariant">
|
||||
<option value="default">Default</option>
|
||||
<option value="bordered">Bordered</option>
|
||||
<option value="elevated">Elevated</option>
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<input type="checkbox" [(ngModel)]="interactiveCollapsed">
|
||||
Collapsed
|
||||
</label>
|
||||
|
||||
<label>
|
||||
Collapse Mode:
|
||||
<select [(ngModel)]="interactiveCollapseMode">
|
||||
<option value="collapsed">Collapsed</option>
|
||||
<option value="hidden">Hidden</option>
|
||||
<option value="overlay">Overlay</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-demo-container sidebar-demo-container--interactive">
|
||||
<ui-sidebar-layout
|
||||
[position]="interactivePosition"
|
||||
[sidebarWidth]="interactiveWidth"
|
||||
[variant]="interactiveVariant"
|
||||
[collapsed]="interactiveCollapsed"
|
||||
[collapseMode]="interactiveCollapseMode">
|
||||
|
||||
<div slot="sidebar">
|
||||
<h5>Interactive Sidebar</h5>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>📱 Dashboard</li>
|
||||
<li>📊 Analytics</li>
|
||||
<li>👥 Users</li>
|
||||
<li>⚙️ Settings</li>
|
||||
<li>❓ Help</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="demo-content">
|
||||
<h4>Interactive Demo</h4>
|
||||
<p>Use the controls above to test different sidebar configurations:</p>
|
||||
<ul>
|
||||
<li><strong>Position:</strong> {{ interactivePosition }}</li>
|
||||
<li><strong>Width:</strong> {{ interactiveWidth }}</li>
|
||||
<li><strong>Variant:</strong> {{ interactiveVariant }}</li>
|
||||
<li><strong>Collapsed:</strong> {{ interactiveCollapsed }}</li>
|
||||
<li><strong>Collapse Mode:</strong> {{ interactiveCollapseMode }}</li>
|
||||
</ul>
|
||||
|
||||
<button
|
||||
(click)="toggleCollapse()"
|
||||
class="demo-button">
|
||||
{{ interactiveCollapsed ? 'Expand' : 'Collapse' }} Sidebar
|
||||
</button>
|
||||
</div>
|
||||
</ui-sidebar-layout>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
`,
|
||||
styleUrl: './sidebar-layout-demo.component.scss'
|
||||
})
|
||||
export class SidebarLayoutDemoComponent {
|
||||
widths = ['sm', 'md', 'lg', 'xl'] as const;
|
||||
variants = ['default', 'bordered', 'elevated'] as const;
|
||||
|
||||
// Interactive demo properties
|
||||
interactivePosition: 'left' | 'right' = 'left';
|
||||
interactiveWidth: 'sm' | 'md' | 'lg' | 'xl' = 'md';
|
||||
interactiveVariant: 'default' | 'bordered' | 'elevated' = 'default';
|
||||
interactiveCollapsed = false;
|
||||
interactiveCollapseMode: 'hidden' | 'collapsed' | 'overlay' = 'collapsed';
|
||||
|
||||
toggleCollapse(): void {
|
||||
this.interactiveCollapsed = !this.interactiveCollapsed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user