TUI Renderer, Element Types, and Page Updates

This commit is contained in:
2025-11-30 18:26:56 -05:00
parent f09c198f17
commit 1167c686e2
31 changed files with 1642 additions and 809 deletions

View File

@@ -28,19 +28,19 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'TEXT FORMATTING', id: 'text-formatting' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Colors(&)' },
{ type: 'output', content: '(&red)red(&) (&green)green(&) (&yellow)yellow(&) (&blue)blue(&) (&magenta)magenta(&) (&cyan)cyan(&) (&orange)orange(&) (&pink)pink(&)' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Semantic Colors(&)' },
{ type: 'output', content: '(&primary)primary(&) (&accent)accent(&) (&muted)muted(&) (&error)error(&) (&success)success(&) (&warning)warning(&) (&info)info(&)' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Text Styles(&)' },
{ type: 'output', content: '(&bold)bold(&) (&dim)dim(&) (&italic)italic(&) (&underline)underline(&) (&strikethrough)strikethrough(&)' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Combined Styles(&)' },
{ type: 'output', content: '(&bold,red)bold red(&) (&italic,cyan)italic cyan(&) (&bold,underline,yellow)bold underline yellow(&)' },
{ type: 'blank', content: '' },
@@ -58,7 +58,7 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'LINE TYPES' },
{ type: 'blank', content: '' },
{ type: 'command', content: 'echo "This is a command line"' },
{ type: 'output', content: 'This is an output line' },
{ type: 'info', content: 'This is an info line' },
@@ -72,39 +72,39 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'BUTTONS', id: 'buttons' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Button Styles(&)' },
{
type: 'button',
content: 'Primary Button',
{
type: 'button',
content: 'Primary Button',
icon: 'mdi:check',
style: 'primary',
action: () => console.log('Primary clicked')
},
{
type: 'button',
content: 'Secondary Button',
{
type: 'button',
content: 'Secondary Button',
icon: 'mdi:information',
style: 'secondary',
action: () => console.log('Secondary clicked')
},
{
type: 'button',
content: 'Accent Button',
{
type: 'button',
content: 'Accent Button',
icon: 'mdi:star',
style: 'accent',
action: () => console.log('Accent clicked')
},
{
type: 'button',
content: 'Warning Button',
{
type: 'button',
content: 'Warning Button',
icon: 'mdi:alert',
style: 'warning',
action: () => console.log('Warning clicked')
},
{
type: 'button',
content: 'Error Button',
{
type: 'button',
content: 'Error Button',
icon: 'mdi:close-circle',
style: 'error',
action: () => console.log('Error clicked')
@@ -112,17 +112,17 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Link Buttons(&)' },
{
type: 'button',
content: 'External Link (GitHub)',
{
type: 'button',
content: 'External Link (GitHub)',
icon: 'mdi:github',
style: 'primary',
href: 'https://github.com',
external: true
},
{
type: 'button',
content: 'Internal Link (Home)',
{
type: 'button',
content: 'Internal Link (Home)',
icon: 'mdi:home',
style: 'accent',
href: '/'
@@ -134,17 +134,17 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'LINKS' },
{ type: 'blank', content: '' },
{
type: 'link',
content: 'Click here to visit GitHub',
{
type: 'link',
content: 'Click here to visit GitHub',
href: 'https://github.com',
icon: 'mdi:github',
external: true
},
{
type: 'link',
content: 'Go to portfolio page',
{
type: 'link',
content: 'Go to portfolio page',
href: '/portfolio',
icon: 'mdi:folder'
},
@@ -155,28 +155,28 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'PROGRESS BARS' },
{ type: 'blank', content: '' },
{
type: 'progress',
content: 'Loading...',
{
type: 'progress',
content: 'Loading...',
progress: 25,
progressLabel: 'Installing packages'
},
{
type: 'progress',
content: '',
{
type: 'progress',
content: '',
progress: 50,
progressLabel: 'Building project'
},
{
type: 'progress',
content: '',
{
type: 'progress',
content: '',
progress: 75,
progressLabel: 'Running tests'
},
{
type: 'progress',
content: '',
{
type: 'progress',
content: '',
progress: 100,
progressLabel: 'Complete!'
},
@@ -187,9 +187,9 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'GROUPS' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Horizontal Group (Row)(&)' },
{
{
type: 'group',
content: '',
groupDirection: 'row',
@@ -204,7 +204,7 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Vertical Group (Column)(&)' },
{
{
type: 'group',
content: '',
groupDirection: 'column',
@@ -220,7 +220,7 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Group with Links(&)' },
{
{
type: 'group',
content: '',
groupAlign: 'start',
@@ -235,51 +235,141 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Nested Groups(&)' },
{
{
type: 'group',
content: '',
groupDirection: 'column',
groupGap: '0.5rem',
children: [
{ type: 'header', content: '(&cyan,bold)Settings Panel(&)' },
{
{
type: 'group',
content: '',
groupDirection: 'row',
groupGap: '1rem',
children: [
{ type: 'output', content: '(&muted)Theme:(&)', inline: true },
{ type: 'button', content: 'Dark', icon: 'mdi:weather-night', style: 'primary', inline: true, action: () => {} },
{ type: 'button', content: 'Light', icon: 'mdi:weather-sunny', style: 'accent', inline: true, action: () => {} }
{ type: 'button', content: 'Dark', icon: 'mdi:weather-night', style: 'primary', inline: true, action: () => { } },
{ type: 'button', content: 'Light', icon: 'mdi:weather-sunny', style: 'accent', inline: true, action: () => { } }
]
},
{
{
type: 'group',
content: '',
groupDirection: 'row',
groupGap: '1rem',
children: [
{ type: 'output', content: '(&muted)Speed:(&)', inline: true },
{ type: 'button', content: 'Slow', style: 'secondary', inline: true, action: () => {} },
{ type: 'button', content: 'Normal', style: 'primary', inline: true, action: () => {} },
{ type: 'button', content: 'Fast', style: 'accent', inline: true, action: () => {} }
{ type: 'button', content: 'Slow', style: 'secondary', inline: true, action: () => { } },
{ type: 'button', content: 'Normal', style: 'primary', inline: true, action: () => { } },
{ type: 'button', content: 'Fast', style: 'accent', inline: true, action: () => { } }
]
}
]
},
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// INLINE COMPONENTS
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'INLINE COMPONENTS' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Inline Cards(&)' },
{ type: 'output', content: '(&muted)Cards can be displayed inline for compact layouts:(&)' },
{
type: 'group',
content: '',
groupDirection: 'row',
groupAlign: 'start',
groupGap: '1rem',
children: [
{
type: 'card',
content: 'Small card 1',
cardTitle: 'Card A',
inline: true
},
{
type: 'card',
content: 'Small card 2',
cardTitle: 'Card B',
style: 'accent',
inline: true
},
{
type: 'card',
content: 'Small card 3',
cardTitle: 'Card C',
style: 'warning',
inline: true
}
]
},
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Inline Tables(&)' },
{ type: 'output', content: '(&muted)Tables can also be inline:(&)' },
{
type: 'group',
content: '',
groupDirection: 'row',
groupAlign: 'start',
groupGap: '1rem',
children: [
{
type: 'table',
content: 'Server 1',
tableHeaders: ['Metric', 'Value'],
tableRows: [['CPU', '45%'], ['RAM', '2.4GB']],
inline: true
},
{
type: 'table',
content: 'Server 2',
tableHeaders: ['Metric', 'Value'],
tableRows: [['CPU', '12%'], ['RAM', '1.1GB']],
inline: true
}
]
},
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Inline Accordions(&)' },
{
type: 'group',
content: '',
groupDirection: 'row',
groupAlign: 'start',
groupGap: '1rem',
children: [
{
type: 'accordion',
content: 'Details A',
accordionItems: [{ title: 'More Info', content: 'Hidden details here.' }],
inline: true
},
{
type: 'accordion',
content: 'Details B',
accordionItems: [{ title: 'More Info', content: 'Hidden details here.' }],
inline: true
}
]
},
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// IMAGES
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'IMAGES' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Image with Caption(&)' },
{
type: 'image',
content: 'User Avatar',
image: user.avatar,
{
type: 'image',
content: 'User Avatar',
image: user.avatar,
imageAlt: 'Profile picture',
imageWidth: 100
},
@@ -290,23 +380,43 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'CARDS' },
{ type: 'blank', content: '' },
{
type: 'card',
{
type: 'card',
content: 'This is card content. Cards can contain formatted text and are great for highlighting information.',
cardTitle: 'Card Title',
cardFooter: 'Card Footer'
},
{ type: 'blank', content: '' },
{
type: 'card',
content: 'Cards can now include images and icons directly.',
cardTitle: 'Rich Card',
cardFooter: 'Updated Feature',
icon: 'mdi:star',
image: 'https://placehold.co/600x200/1e1e2e/cdd6f4?text=Card+Image',
imageAlt: 'Placeholder image',
children: [
{
type: 'button',
content: 'View on GitHub',
href: 'https://github.com/adithyakrishnan2004',
icon: 'mdi:github',
style: 'primary'
}
],
display: 'flex'
},
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// TABLES
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'TABLES' },
{ type: 'blank', content: '' },
{
type: 'table',
{
type: 'table',
content: '',
tableHeaders: sampleTableHeaders,
tableRows: sampleTableRows
@@ -318,9 +428,9 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'ACCORDIONS' },
{ type: 'blank', content: '' },
{
type: 'accordion',
{
type: 'accordion',
content: '',
accordionItems: sampleAccordionItems,
accordionOpen: false
@@ -332,9 +442,9 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'TOOLTIPS' },
{ type: 'blank', content: '' },
{
type: 'tooltip',
{
type: 'tooltip',
content: 'Hover over me for more info!',
tooltipText: 'This is tooltip content that appears on hover.',
tooltipPosition: 'top'
@@ -346,7 +456,7 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'DIVIDER STYLES' },
{ type: 'blank', content: '' },
{ type: 'output', content: '(&muted)Dividers are simple horizontal separators with optional text:(&)' },
{ type: 'divider', content: 'SECTION A' },
{ type: 'output', content: '(&muted)Content for section A...(&)' },
@@ -363,39 +473,39 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Text Input(&)' },
{
type: 'input',
{
type: 'input',
content: 'Username:',
icon: 'mdi:account',
inputPlaceholder: 'Enter your username',
style: 'primary'
},
{
type: 'input',
{
type: 'input',
content: 'Email:',
icon: 'mdi:email',
inputPlaceholder: 'you@example.com',
inputType: 'email',
style: 'accent'
},
{
type: 'input',
{
type: 'input',
content: 'With prefix/suffix:',
inputPlaceholder: '100',
inputPrefix: '$',
inputSuffix: '.00',
inputType: 'number'
},
{
type: 'input',
{
type: 'input',
content: 'Error state:',
inputPlaceholder: 'Invalid input',
inputError: true,
inputErrorMessage: 'This field is required',
style: 'error'
},
{
type: 'input',
{
type: 'input',
content: 'Disabled:',
inputPlaceholder: 'Cannot edit',
inputDisabled: true
@@ -409,16 +519,16 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Multi-line Text Area(&)' },
{
type: 'textarea',
{
type: 'textarea',
content: 'Message:',
icon: 'mdi:message-text',
inputPlaceholder: 'Type your message here...',
textareaRows: 4,
style: 'primary'
},
{
type: 'textarea',
{
type: 'textarea',
content: 'With character limit:',
inputPlaceholder: 'Limited to 100 characters',
textareaRows: 3,
@@ -426,6 +536,16 @@ export const lines: TerminalLine[] = [
style: 'accent'
},
{ type: 'blank', content: '' },
{
type: 'textarea',
content: 'Error state:',
inputPlaceholder: 'Invalid input...',
textareaRows: 2,
style: 'error',
inputError: true,
inputErrorMessage: 'Message is too short'
},
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// CHECKBOX
@@ -434,25 +554,25 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Checkbox Options(&)' },
{
type: 'checkbox',
{
type: 'checkbox',
content: 'Enable notifications',
icon: 'mdi:bell',
style: 'primary'
},
{
type: 'checkbox',
{
type: 'checkbox',
content: 'Accept terms and conditions',
style: 'accent'
},
{
type: 'checkbox',
{
type: 'checkbox',
content: 'Indeterminate state',
checkboxIndeterminate: true,
style: 'warning'
},
{
type: 'checkbox',
{
type: 'checkbox',
content: 'Disabled checkbox',
inputDisabled: true
},
@@ -465,8 +585,8 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Radio Group (Vertical)(&)' },
{
type: 'radio',
{
type: 'radio',
content: 'Select theme:',
icon: 'mdi:palette',
style: 'primary',
@@ -479,8 +599,8 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Radio Group (Horizontal)(&)' },
{
type: 'radio',
{
type: 'radio',
content: 'Size:',
style: 'accent',
radioHorizontal: true,
@@ -500,8 +620,8 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Basic Select(&)' },
{
type: 'select',
{
type: 'select',
content: 'Country:',
icon: 'mdi:earth',
inputPlaceholder: 'Select a country...',
@@ -517,8 +637,8 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Searchable Select(&)' },
{
type: 'select',
{
type: 'select',
content: 'Programming Language:',
icon: 'mdi:code-braces',
inputPlaceholder: 'Search languages...',
@@ -535,6 +655,18 @@ export const lines: TerminalLine[] = [
]
},
{ type: 'blank', content: '' },
{
type: 'select',
content: 'Error state:',
inputPlaceholder: 'Select something...',
style: 'error',
inputError: true,
inputErrorMessage: 'Selection required',
selectOptions: [
{ value: '1', label: 'Option 1' }
]
},
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// TOGGLE SWITCH
@@ -543,36 +675,36 @@ export const lines: TerminalLine[] = [
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Toggle Options(&)' },
{
type: 'toggle',
{
type: 'toggle',
content: 'Dark Mode',
icon: 'mdi:theme-light-dark',
style: 'primary'
},
{
type: 'toggle',
{
type: 'toggle',
content: 'Airplane Mode',
icon: 'mdi:airplane',
style: 'accent',
toggleOnLabel: 'ON',
toggleOffLabel: 'OFF'
},
{
type: 'toggle',
{
type: 'toggle',
content: 'Custom Labels',
icon: 'mdi:toggle-switch',
style: 'warning',
toggleOnLabel: 'YES',
toggleOffLabel: 'NO'
},
{
type: 'toggle',
{
type: 'toggle',
content: 'No Labels',
toggleShowLabels: false,
style: 'accent'
},
{
type: 'toggle',
{
type: 'toggle',
content: 'Disabled Toggle',
inputDisabled: true
},
@@ -583,7 +715,7 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'USAGE' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Code Example(&)' },
{ type: 'output', content: "(&muted)// Text formatting(&)" },
{ type: 'output', content: "{ type: 'output', content: '(&green)colored text(&)' }" },
@@ -609,38 +741,38 @@ export const lines: TerminalLine[] = [
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'TERMINAL API', id: 'terminal-api' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Reactive Terminal Control(&)' },
{ type: 'output', content: 'The (&cyan)TerminalAPI(&) allows programmatic control of terminal content.' },
{ type: 'output', content: 'Use (&primary)bind:terminal(&) to access the API from your component.' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Writing Lines(&)' },
{ type: 'output', content: "(&muted)terminal.write({ type: 'output', content: 'Hello!' })(&) (&dim)// Append line(&)" },
{ type: 'output', content: "(&muted)terminal.writeLines([...lines])(&) (&dim)// Append multiple(&)" },
{ type: 'output', content: "(&muted)terminal.clear()(&) (&dim)// Clear all(&)" },
{ type: 'output', content: "(&muted)terminal.setLines([...lines])(&) (&dim)// Replace all(&)" },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Updating Lines(&)' },
{ type: 'output', content: "(&muted)terminal.update(0, { content: 'New text' })(&) (&dim)// Update by index(&)" },
{ type: 'output', content: "(&muted)terminal.updateContent(0, 'New text')(&) (&dim)// Update content only(&)" },
{ type: 'output', content: "(&muted)terminal.updateById('my-id', { content: 'New' })(&) (&dim)// Update by ID(&)" },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Removing Lines(&)' },
{ type: 'output', content: "(&muted)terminal.remove(0)(&) (&dim)// Remove by index(&)" },
{ type: 'output', content: "(&muted)terminal.removeRange(0, 3)(&) (&dim)// Remove range(&)" },
{ type: 'output', content: "(&muted)terminal.removeById('my-id')(&) (&dim)// Remove by ID(&)" },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Navigation & Control(&)' },
{ type: 'output', content: "(&muted)terminal.scrollToBottom()(&) (&dim)// Scroll to end(&)" },
{ type: 'output', content: "(&muted)terminal.scrollToLine(5)(&) (&dim)// Scroll to line(&)" },
{ type: 'output', content: "(&muted)terminal.skip()(&) (&dim)// Skip animation(&)" },
{ type: 'output', content: "(&muted)terminal.restart()(&) (&dim)// Restart animation(&)" },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Reading State(&)' },
{ type: 'output', content: "(&muted)terminal.getLine(0)(&) (&dim)// Get line by index(&)" },
{ type: 'output', content: "(&muted)terminal.getLines()(&) (&dim)// Get all lines(&)" },
@@ -648,7 +780,7 @@ export const lines: TerminalLine[] = [
{ type: 'output', content: "(&muted)terminal.findById('my-id')(&) (&dim)// Find index by ID(&)" },
{ type: 'output', content: "(&muted)terminal.isAnimating()(&) (&dim)// Check if typing(&)" },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Usage Example(&)' },
{ type: 'output', content: "(&dim)// In your Svelte component:(&)" },
{ type: 'output', content: "(&cyan)import(&) TerminalTUI (&cyan)from(&) '(&green)$lib/components/TerminalTUI.svelte(&)';" },
@@ -664,6 +796,63 @@ export const lines: TerminalLine[] = [
{ type: 'output', content: "terminal?.write({ type: '(&green)success(&)', content: '(&green)Done!(&)' });" },
{ type: 'blank', content: '' },
// ═══════════════════════════════════════════════════════════════
// DISPLAY & NESTING
// ═══════════════════════════════════════════════════════════════
{ type: 'divider', content: 'DISPLAY & NESTING' },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Inline Grouping Logic(&)' },
{ type: 'output', content: '(&muted)Consecutive inline elements are grouped. Non-consecutive are separated.(&)' },
{ type: 'output', content: '(&muted)1(&)', inline: true },
{ type: 'output', content: '(&muted)2(&)', inline: true },
{ type: 'blank', content: '' },
{ type: 'output', content: '(&muted)3(&)', inline: true },
{ type: 'output', content: '(&muted)4(&)', inline: true },
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Card with Nested Children (Grid)(&)' },
{
type: 'card',
content: 'This card contains other cards in a grid layout.',
cardTitle: 'Parent Card (Grid)',
display: 'grid',
children: [
{ type: 'card', content: 'Child 1', cardTitle: 'C1' },
{ type: 'card', content: 'Child 2', cardTitle: 'C2' },
{ type: 'card', content: 'Child 3', cardTitle: 'C3' },
{ type: 'card', content: 'Child 4', cardTitle: 'C4' }
]
},
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Accordion with Nested Children (Flex)(&)' },
{
type: 'accordion',
content: 'Open to see nested items',
display: 'flex',
children: [
{ type: 'button', content: 'Action 1', style: 'primary', icon: 'mdi:check' },
{ type: 'button', content: 'Action 2', style: 'secondary', icon: 'mdi:close' },
{ type: 'button', content: 'Action 3', style: 'accent', icon: 'mdi:star' }
]
},
{ type: 'blank', content: '' },
{ type: 'info', content: '(&blue,bold)Group with Grid Layout(&)' },
{
type: 'group',
content: '',
display: 'grid',
groupGap: '1rem',
children: [
{ type: 'card', content: 'Grid Item 1', cardTitle: 'G1' },
{ type: 'card', content: 'Grid Item 2', cardTitle: 'G2' },
{ type: 'card', content: 'Grid Item 3', cardTitle: 'G3' }
]
},
{ type: 'blank', content: '' },
// End
{ type: 'success', content: '(&success)Component showcase complete!(&)' }
];

View File

@@ -13,7 +13,7 @@ export const lines: TerminalLine[] = [
{ type: 'output', content: '(&dim,red)███(&)(&dim,orange)███(&)(&dim,yellow)███(&)(&dim,green)███(&)(&dim,cyan)███(&)(&dim,blue)███(&)(&dim,magenta)███(&)(&dim,pink)███(&)', inline: true },
{ type: 'blank', content: '' },
{ type: 'header', content: `HI, I'm ${user.displayname}` },
{ type: 'header', content: `HI, I'm ${user.displayname}` },
{ type: 'image', content: '', image: user.avatar, imageAlt: user.name, imageWidth: 120, inline: true },
{ type: 'group', content: '', inline: true, groupDirection: 'column', children: [

View File

@@ -2,7 +2,7 @@
import type { TerminalLine } from '$lib/components/tui/types';
import { user, skills, projects } from '$lib/config';
export const lines: TerminalLine[] = [
export const lines: TerminalLine[] = [
// Header command
{ type: 'command', content: 'cat ~/about.md' },
{ type: 'blank', content: '' },
@@ -24,9 +24,10 @@ export const lines: TerminalLine[] = [
{ type: 'output', content: `(&muted)${user.bio}(&)` },
]
},
{ type: 'blank', content: '' },
{ type: 'group', content: '', groupAlign: 'start', groupGap: '1rem',
{
type: 'group', content: '', groupAlign: 'start', groupGap: '1rem',
children: [
{ type: 'output', content: `(&primary, bold)Links >(&)`, inline: true },
{ type: 'link', href: "/portfolio#contact", content: `(&bg-blue,black)Contact(&)`, inline: true },
@@ -44,9 +45,9 @@ export const lines: TerminalLine[] = [
href: social.link,
inline: true
})),
{ type: 'divider', content: 'SKILLS', id: 'skills' },
// Skills as TUI sections
// Languages
@@ -81,54 +82,54 @@ export const lines: TerminalLine[] = [
// Interests
{ type: 'info', content: '(&accent,bold)▸ Interests(&)' },
{ type: 'output', content: ' ' + skills.interests.map(s => `(&muted)${s}(&)`).join(' (&muted)•(&) ') },
{ type: 'output', content: ' ' + skills.interests.map(s => `(&muted)${s}(&)`).join(' (&muted)•(&) ') },
{ type: 'divider', content: 'PROJECTS', id: 'projects' },
// Featured projects with buttons
...projects.filter(p => p.featured).flatMap(project => [
{ type: 'header' as const, content: `(&bold)${project.name}(&)` },
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
{ type: 'info' as const, content: `(&info)TechStack: (&primary)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
{ type: 'info' as const, content: `(&info)TechStack:(&) (&magenta)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
icon: 'mdi:github',
style: 'accent' as const,
href: project.github
}] : []),
...(project.live ? [{
type: 'button' as const,
content: 'View Live Demo',
...(project.live ? [{
type: 'button' as const,
content: 'View Live Demo',
icon: 'mdi:open-in-new',
style: 'accent' as const,
href: project.live
}] : []),
{ type: 'blank' as const, content: '' }
]),
// Other projects
...projects.filter(p => !p.featured).flatMap(project => [
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
{ type: 'info' as const, content: `(&info)TechStack:(&) (&primary)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
{ type: 'info' as const, content: `(&info)TechStack:(&) (&magenta)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
icon: 'mdi:github',
style: 'accent' as const,
href: project.github
}] : []),
...(project.live ? [{
type: 'button' as const,
content: 'View Live',
...(project.live ? [{
type: 'button' as const,
content: 'View Live',
icon: 'mdi:open-in-new',
style: 'accent' as const,
href: project.live
}] : []),
{ type: 'blank' as const, content: '' }
]),
// End
{ type: 'success', content: `(&success)Portfolio loaded successfully!(&)` }
];

View File

@@ -7,22 +7,22 @@ const featuredCount = sortedCards.filter(c => c.featured).length;
// Build the terminal lines with card grid
export const lines: TerminalLine[] = [
{ type: 'command', content: 'ls ~/projects --grid' },
{ type: 'command', content: 'ls ~/projects' },
{ type: 'divider', content: 'PROJECTS' },
...projects.filter(p => p.featured).flatMap(project => [
{ type: 'header' as const, content: `(&bold)${project.name}(&)` },
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
{ type: 'info' as const, content: `(&info)Tech: (&primary)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
{ type: 'info' as const, content: `(&info)TechStack:(&) (&magenta)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
icon: 'mdi:github',
style: 'accent' as const,
href: project.github
}] : []),
...(project.live ? [{
type: 'button' as const,
content: 'View Live Demo',
...(project.live ? [{
type: 'button' as const,
content: 'View Live Demo',
icon: 'mdi:open-in-new',
style: 'accent' as const,
href: project.live
@@ -32,17 +32,17 @@ export const lines: TerminalLine[] = [
...projects.filter(p => !p.featured).flatMap(project => [
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
{ type: 'info' as const, content: `(&info)Tech:(&) (&primary)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
{ type: 'info' as const, content: `(&info)TechStack:(&) (&magenta)${project.tech.join(', ')}(&)` },
...(project.github ? [{
type: 'button' as const,
content: 'View on GitHub',
icon: 'mdi:github',
style: 'accent' as const,
href: project.github
}] : []),
...(project.live ? [{
type: 'button' as const,
content: 'View Live',
...(project.live ? [{
type: 'button' as const,
content: 'View Live',
icon: 'mdi:open-in-new',
style: 'accent' as const,
href: project.live