Skip to content

Commit 286ae80

Browse files
committed
✨ feat: implement interactive theme selection for Hyva tokens command
1 parent 563e4a8 commit 286ae80

1 file changed

Lines changed: 142 additions & 55 deletions

File tree

src/Console/Command/Hyva/TokensCommand.php

Lines changed: 142 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -56,83 +56,171 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
5656
{
5757
$themeCode = $input->getArgument('themeCode');
5858

59-
// If no theme code provided, show interactive prompt for Hyva themes only
59+
// If no theme code provided, select interactively
6060
if (empty($themeCode)) {
61-
$hyvaThemes = $this->getHyvaThemes();
62-
63-
if (empty($hyvaThemes)) {
64-
$this->io->error('No Hyvä themes found in this installation.');
61+
$themeCode = $this->selectThemeInteractively($output);
62+
if ($themeCode === null) {
6563
return Command::FAILURE;
6664
}
65+
}
6766

68-
// Check if we're in an interactive terminal environment
69-
if (!$this->isInteractiveTerminal($output)) {
70-
$this->io->info('Available Hyvä themes:');
71-
foreach ($hyvaThemes as $theme) {
72-
$this->io->writeln(' - ' . $theme->getCode());
73-
}
74-
$this->io->newLine();
75-
$this->io->info('Usage: bin/magento mageforge:hyva:tokens <theme-code>');
76-
return Command::SUCCESS;
77-
}
67+
// Validate theme
68+
$themePath = $this->validateTheme($themeCode);
69+
if ($themePath === null) {
70+
return Command::FAILURE;
71+
}
7872

79-
$options = [];
80-
foreach ($hyvaThemes as $theme) {
81-
$options[] = $theme->getCode();
82-
}
73+
// Process tokens and return result
74+
return $this->processTokens($themeCode, $themePath);
75+
}
8376

84-
$themeCodePrompt = new SelectPrompt(
85-
label: 'Select Hyvä theme to generate tokens for',
86-
options: $options,
87-
hint: 'Arrow keys to navigate, Enter to confirm'
88-
);
77+
/**
78+
* Select theme interactively
79+
*
80+
* @param OutputInterface $output
81+
* @return string|null
82+
*/
83+
private function selectThemeInteractively(OutputInterface $output): ?string
84+
{
85+
$hyvaThemes = $this->getHyvaThemes();
8986

90-
try {
91-
$themeCode = $themeCodePrompt->prompt();
92-
} catch (\Exception $e) {
93-
$this->io->error('Interactive mode failed: ' . $e->getMessage());
94-
return Command::FAILURE;
95-
} finally {
96-
\Laravel\Prompts\Prompt::terminal()->restoreTty();
97-
}
87+
if (empty($hyvaThemes)) {
88+
$this->io->error('No Hyvä themes found in this installation.');
89+
return null;
90+
}
91+
92+
// Check if we're in an interactive terminal environment
93+
if (!$this->isInteractiveTerminal($output)) {
94+
$this->displayAvailableThemes($hyvaThemes);
95+
return null;
96+
}
97+
98+
return $this->promptForTheme($hyvaThemes);
99+
}
100+
101+
/**
102+
* Display available themes for non-interactive environments
103+
*
104+
* @param array $hyvaThemes
105+
* @return void
106+
*/
107+
private function displayAvailableThemes(array $hyvaThemes): void
108+
{
109+
$this->io->info('Available Hyvä themes:');
110+
foreach ($hyvaThemes as $theme) {
111+
$this->io->writeln(' - ' . $theme->getCode());
112+
}
113+
$this->io->newLine();
114+
$this->io->info('Usage: bin/magento mageforge:hyva:tokens <theme-code>');
115+
}
116+
117+
/**
118+
* Prompt user to select a theme
119+
*
120+
* @param array $hyvaThemes
121+
* @return string|null
122+
*/
123+
private function promptForTheme(array $hyvaThemes): ?string
124+
{
125+
$options = [];
126+
foreach ($hyvaThemes as $theme) {
127+
$options[] = $theme->getCode();
98128
}
99129

130+
$themeCodePrompt = new SelectPrompt(
131+
label: 'Select Hyvä theme to generate tokens for',
132+
options: $options,
133+
hint: 'Arrow keys to navigate, Enter to confirm'
134+
);
135+
136+
try {
137+
return $themeCodePrompt->prompt();
138+
} catch (\Exception $e) {
139+
$this->io->error('Interactive mode failed: ' . $e->getMessage());
140+
return null;
141+
} finally {
142+
\Laravel\Prompts\Prompt::terminal()->restoreTty();
143+
}
144+
}
145+
146+
/**
147+
* Validate theme exists and is a Hyva theme
148+
*
149+
* @param string $themeCode
150+
* @return string|null
151+
*/
152+
private function validateTheme(string $themeCode): ?string
153+
{
100154
// Get theme path
101155
$themePath = $this->themePath->getPath($themeCode);
102156
if ($themePath === null) {
103157
$this->io->error("Theme $themeCode is not installed.");
104-
return Command::FAILURE;
158+
return null;
105159
}
106160

107161
// Verify this is a Hyva theme
108162
if (!$this->hyvaBuilder->detect($themePath)) {
109163
$this->io->error("Theme $themeCode is not a Hyvä theme. This command only works with Hyvä themes.");
110-
return Command::FAILURE;
164+
return null;
111165
}
112166

113-
// Process tokens
167+
return $themePath;
168+
}
169+
170+
/**
171+
* Process tokens and display results
172+
*
173+
* @param string $themeCode
174+
* @param string $themePath
175+
* @return int
176+
*/
177+
private function processTokens(string $themeCode, string $themePath): int
178+
{
114179
$this->io->text("Processing design tokens for theme: <fg=cyan>$themeCode</>");
115180
$result = $this->tokenProcessor->process($themePath);
116181

117182
if ($result['success']) {
118-
$this->io->newLine();
119-
$this->io->success($result['message']);
120-
$this->io->writeln("Output file: <fg=green>{$result['outputPath']}</>");
121-
$this->io->newLine();
122-
$this->io->text('ℹ️ Make sure to import this file in your Tailwind CSS configuration.');
123-
return Command::SUCCESS;
124-
} else {
125-
$this->io->error($result['message']);
126-
$this->io->newLine();
127-
$this->io->text('ℹ️ To use this command, you need one of the following:');
128-
$this->io->listing([
129-
'A design.tokens.json file in the theme\'s web/tailwind directory',
130-
'A custom token file specified in hyva.config.json',
131-
'Inline token values in hyva.config.json',
132-
]);
133-
$this->io->newLine();
134-
$this->io->text('Example hyva.config.json with inline tokens:');
135-
$this->io->text(<<<JSON
183+
return $this->handleSuccess($result);
184+
}
185+
186+
return $this->handleFailure($result);
187+
}
188+
189+
/**
190+
* Handle successful token processing
191+
*
192+
* @param array $result
193+
* @return int
194+
*/
195+
private function handleSuccess(array $result): int
196+
{
197+
$this->io->newLine();
198+
$this->io->success($result['message']);
199+
$this->io->writeln("Output file: <fg=green>{$result['outputPath']}</>");
200+
$this->io->newLine();
201+
$this->io->text('ℹ️ Make sure to import this file in your Tailwind CSS configuration.');
202+
return Command::SUCCESS;
203+
}
204+
205+
/**
206+
* Handle token processing failure
207+
*
208+
* @param array $result
209+
* @return int
210+
*/
211+
private function handleFailure(array $result): int
212+
{
213+
$this->io->error($result['message']);
214+
$this->io->newLine();
215+
$this->io->text('ℹ️ To use this command, you need one of the following:');
216+
$this->io->listing([
217+
'A design.tokens.json file in the theme\'s web/tailwind directory',
218+
'A custom token file specified in hyva.config.json',
219+
'Inline token values in hyva.config.json',
220+
]);
221+
$this->io->newLine();
222+
$this->io->text('Example hyva.config.json with inline tokens:');
223+
$this->io->text(<<<JSON
136224
{
137225
"tokens": {
138226
"values": {
@@ -147,8 +235,7 @@ protected function executeCommand(InputInterface $input, OutputInterface $output
147235
}
148236
}
149237
JSON);
150-
return Command::FAILURE;
151-
}
238+
return Command::FAILURE;
152239
}
153240

154241
/**

0 commit comments

Comments
 (0)