mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
• Update build-css.mjs to include the new "styles/task-selector-modal.css" file. • In PomodoroView.ts, replace legacy CSS class names with updated BEM-style names: – Remove redundant or legacy classes (e.g., "pomodoro-no-task", "is-hidden", "is-loading") in favor of new BEM modifiers. – Replace component element classes (e.g., progress circle, timer display, task selector, control sections, etc.) with their BEM counterparts. – Streamline class usage in both element creations and event updates to ensure consistency in naming. • Create a new styles/task-selector-modal.css file that implements a full BEM structure for the TaskSelectorModal component: – Define base styles for suggestions, title, metadata, due date, context tags, and status badges. – Include responsive adjustments, focus states for accessibility, and integration tweaks for dark themes and Obsidian modal containers. These changes improve the modularity, readability, and maintainability of the CSS, ensuring that all UI components adhere to the same naming conventions and design system.
326 lines
No EOL
9.9 KiB
JavaScript
326 lines
No EOL
9.9 KiB
JavaScript
import { readFileSync, writeFileSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
const CSS_FILES = [
|
|
// Core System Files
|
|
'styles/variables.css', // CSS custom properties and design system variables
|
|
'styles/utilities.css', // Scoped utility classes for layout, spacing, typography
|
|
'styles/base.css', // Basic styles, animations, card components, and layout
|
|
|
|
// BEM Component Files
|
|
'styles/task-card-bem.css', // TaskCard component with proper BEM scoping
|
|
'styles/note-card-bem.css', // NoteCard component with proper BEM scoping
|
|
'styles/filter-bar-bem.css', // FilterBar component with proper BEM scoping
|
|
'styles/modal-bem.css', // Modal components with proper BEM scoping
|
|
'styles/task-selector-modal.css', // TaskSelectorModal component with proper BEM scoping
|
|
|
|
// BEM View Files
|
|
'styles/task-list-view.css', // TaskListView component with proper BEM scoping
|
|
'styles/calendar-view.css', // CalendarView component with proper BEM scoping
|
|
'styles/kanban-view.css', // KanbanView component with proper BEM scoping
|
|
'styles/agenda-view.css', // AgendaView component with proper BEM scoping
|
|
'styles/notes-view.css', // NotesView component with proper BEM scoping
|
|
'styles/pomodoro-view.css', // PomodoroView component with proper BEM scoping
|
|
'styles/pomodoro-stats-view.css', // PomodoroStatsView component with proper BEM scoping
|
|
'styles/settings-view.css', // SettingsView component with proper BEM scoping
|
|
|
|
// Legacy Support (minimal)
|
|
'styles/components.css' // Reusable UI components and utilities
|
|
];
|
|
|
|
const MAIN_CSS_TEMPLATE = `/* TaskNotes Plugin Styles */
|
|
|
|
/*
|
|
This file is automatically generated by the build process.
|
|
To modify styles, edit the source files in the styles/ directory.
|
|
|
|
Source files:
|
|
|
|
Core System:
|
|
- styles/variables.css: CSS custom properties and design system variables
|
|
- styles/utilities.css: Scoped utility classes for layout, spacing, typography, and states
|
|
- styles/base.css: Basic styles, animations, card components, and layout
|
|
|
|
BEM Component Files:
|
|
- styles/task-card-bem.css: TaskCard component with proper BEM scoping
|
|
- styles/note-card-bem.css: NoteCard component with proper BEM scoping
|
|
- styles/filter-bar-bem.css: FilterBar component with proper BEM scoping
|
|
- styles/modal-bem.css: Modal components with proper BEM scoping
|
|
|
|
BEM View Files:
|
|
- styles/task-list-view.css: TaskListView component with proper BEM scoping
|
|
- styles/calendar-view.css: CalendarView component with proper BEM scoping
|
|
- styles/kanban-view.css: KanbanView component with proper BEM scoping
|
|
- styles/agenda-view.css: AgendaView component with proper BEM scoping
|
|
- styles/notes-view.css: NotesView component with proper BEM scoping
|
|
- styles/pomodoro-view.css: PomodoroView component with proper BEM scoping
|
|
- styles/pomodoro-stats-view.css: PomodoroStatsView component with proper BEM scoping
|
|
- styles/settings-view.css: SettingsView component with proper BEM scoping
|
|
|
|
Legacy Support:
|
|
- styles/components.css: Reusable UI components, utilities, and modals
|
|
|
|
Run 'npm run build-css' to regenerate this file.
|
|
*/
|
|
|
|
`;
|
|
|
|
const REMAINING_STYLES = `
|
|
/* Task Creation Modal */
|
|
.task-creation-modal .input-with-counter {
|
|
position: relative;
|
|
}
|
|
|
|
.task-creation-modal .character-counter {
|
|
position: absolute;
|
|
top: -1.2rem;
|
|
right: 0;
|
|
font-size: var(--cs-text-xs);
|
|
color: var(--text-muted);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.task-creation-modal .character-counter.warning {
|
|
color: var(--text-error);
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-container {
|
|
position: relative;
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-input {
|
|
width: 100%;
|
|
padding: 0.5rem;
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: var(--cs-radius-sm);
|
|
background: var(--background-primary);
|
|
color: var(--text-normal);
|
|
font-size: var(--cs-text-base);
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-suggestions {
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
right: 0;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-top: none;
|
|
border-radius: 0 0 var(--cs-radius-sm) var(--cs-radius-sm);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
z-index: 1000;
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-suggestion {
|
|
padding: 0.5rem;
|
|
cursor: pointer;
|
|
border-bottom: 1px solid var(--background-modifier-border-hover);
|
|
font-size: var(--cs-text-sm);
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-suggestion:hover,
|
|
.task-creation-modal .autocomplete-suggestion.selected {
|
|
background: var(--background-modifier-hover);
|
|
}
|
|
|
|
.task-creation-modal .autocomplete-suggestion:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.task-creation-modal .form-group {
|
|
margin-bottom: 1rem;
|
|
position: relative;
|
|
}
|
|
|
|
.task-creation-modal .form-group label {
|
|
display: block;
|
|
margin-bottom: 0.25rem;
|
|
font-weight: 500;
|
|
color: var(--text-normal);
|
|
font-size: var(--cs-text-sm);
|
|
}
|
|
|
|
.task-creation-modal input,
|
|
.task-creation-modal select,
|
|
.task-creation-modal textarea {
|
|
width: 100%;
|
|
padding: 0.5rem;
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: var(--cs-radius-sm);
|
|
background: var(--background-primary);
|
|
color: var(--text-normal);
|
|
font-size: var(--cs-text-base);
|
|
transition: border-color var(--cs-transition-fast);
|
|
}
|
|
|
|
.task-creation-modal input:focus,
|
|
.task-creation-modal select:focus,
|
|
.task-creation-modal textarea:focus {
|
|
outline: none;
|
|
border-color: var(--interactive-accent);
|
|
box-shadow: 0 0 0 2px rgba(var(--interactive-accent-rgb), 0.2);
|
|
}
|
|
|
|
.task-creation-modal .button-container {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
justify-content: flex-end;
|
|
margin-top: 1.5rem;
|
|
padding-top: 1rem;
|
|
border-top: 1px solid var(--background-modifier-border);
|
|
}
|
|
|
|
.task-creation-modal .create-button {
|
|
background: var(--interactive-accent);
|
|
color: var(--text-on-accent);
|
|
border: none;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: var(--cs-radius-sm);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background-color var(--cs-transition-fast);
|
|
}
|
|
|
|
.task-creation-modal .create-button:hover {
|
|
background: var(--interactive-accent-hover);
|
|
}
|
|
|
|
.task-creation-modal .recurrence-helper-text {
|
|
font-size: var(--cs-text-xs);
|
|
color: var(--text-muted);
|
|
margin-top: 0.25rem;
|
|
font-style: italic;
|
|
}
|
|
|
|
.task-creation-modal .days-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.25rem;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.task-creation-modal .day-checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
cursor: pointer;
|
|
font-size: var(--cs-text-sm);
|
|
}
|
|
|
|
.task-creation-modal .day-checkbox {
|
|
width: auto !important;
|
|
margin: 0;
|
|
}
|
|
|
|
.task-creation-modal .time-estimate-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.task-creation-modal .time-estimate-container input {
|
|
width: 80px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.task-creation-modal .time-unit-label {
|
|
font-size: var(--cs-text-sm);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
/* Recurrence options styling */
|
|
.task-creation-modal .recurrence-pattern-group {
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: var(--cs-radius-sm);
|
|
padding: var(--cs-spacing-sm);
|
|
background: var(--background-secondary);
|
|
}
|
|
|
|
/* Days of week selection */
|
|
.task-creation-modal .days-of-week-container {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
gap: var(--cs-spacing-xs);
|
|
margin-top: var(--cs-spacing-sm);
|
|
}
|
|
|
|
.task-creation-modal .day-button {
|
|
padding: var(--cs-spacing-xs) var(--cs-spacing-sm);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: var(--cs-radius-sm);
|
|
background: var(--background-primary);
|
|
color: var(--text-normal);
|
|
cursor: pointer;
|
|
font-size: var(--cs-text-xs);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
transition: all var(--cs-transition-fast);
|
|
text-align: center;
|
|
min-height: var(--cs-touch-target);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.task-creation-modal .day-button:hover {
|
|
background: var(--background-modifier-hover);
|
|
border-color: var(--interactive-accent);
|
|
}
|
|
|
|
.task-creation-modal .day-button.selected {
|
|
background: var(--interactive-accent);
|
|
color: var(--text-on-accent);
|
|
border-color: var(--interactive-accent);
|
|
}
|
|
|
|
.task-creation-modal .day-button:focus {
|
|
outline: 2px solid var(--interactive-accent);
|
|
outline-offset: 2px;
|
|
}`;
|
|
|
|
function buildCSS() {
|
|
console.log('Building CSS...');
|
|
|
|
let combinedCSS = MAIN_CSS_TEMPLATE;
|
|
|
|
// Read and concatenate each CSS file
|
|
for (const cssFile of CSS_FILES) {
|
|
try {
|
|
const content = readFileSync(cssFile, 'utf8');
|
|
|
|
// Add a section header comment
|
|
const filename = cssFile.split('/').pop();
|
|
combinedCSS += `\n/* ===== ${filename.toUpperCase()} ===== */\n`;
|
|
combinedCSS += content;
|
|
combinedCSS += '\n';
|
|
|
|
console.log(`✓ Included ${cssFile}`);
|
|
} catch (error) {
|
|
console.error(`✗ Error reading ${cssFile}:`, error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Add the remaining modal styles
|
|
combinedCSS += REMAINING_STYLES;
|
|
|
|
// Write the combined CSS to styles.css
|
|
try {
|
|
writeFileSync('styles.css', combinedCSS);
|
|
console.log('✓ Built styles.css successfully');
|
|
|
|
// Count lines for reference
|
|
const lineCount = combinedCSS.split('\n').length;
|
|
console.log(`✓ Generated ${lineCount} lines of CSS`);
|
|
|
|
} catch (error) {
|
|
console.error('✗ Error writing styles.css:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Run the build
|
|
buildCSS(); |