Skip to content

Commit dbbf94f

Browse files
committed
[Toolkit] Refactor ToolkitKit enum to ToolkitKitId, leverage description/uxIcon/installation steps in Kit VO
1 parent 43e95a3 commit dbbf94f

File tree

23 files changed

+236
-251
lines changed

23 files changed

+236
-251
lines changed

src/Toolkit/kits/shadcn/INSTALL.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Getting started
2+
3+
This kit provides ready-to-use and fully-customizable UI Twig components based on [Shadcn UI](https://ui.shadcn.com/) components's **design**.
4+
5+
Please note that not every Shadcn UI component is available in this kit, but we are working on it!
6+
7+
## Requirements
8+
9+
This kit requires TailwindCSS to work:
10+
- If you use Symfony AssetMapper, you can install TailwindCSS with the [TailwindBundle](https://symfony.com/bundles/TailwindBundle/current/index.html),
11+
- If you use Webpack Encore, you can follow the [TailwindCSS installation guide for Symfony](https://tailwindcss.com/docs/installation/framework-guides/symfony)
12+
13+
## Installation
14+
15+
In your `assets/styles/app.css`, after the TailwindCSS imports, add the following code:
16+
17+
```css
18+
@custom-variant dark (&:is(.dark *));
19+
20+
:root {
21+
--radius: 0.625rem;
22+
--background: oklch(1 0 0);
23+
--foreground: oklch(0.145 0 0);
24+
--card: oklch(1 0 0);
25+
--card-foreground: oklch(0.145 0 0);
26+
--popover: oklch(1 0 0);
27+
--popover-foreground: oklch(0.145 0 0);
28+
--primary: oklch(0.205 0 0);
29+
--primary-foreground: oklch(0.985 0 0);
30+
--secondary: oklch(0.97 0 0);
31+
--secondary-foreground: oklch(0.205 0 0);
32+
--muted: oklch(0.97 0 0);
33+
--muted-foreground: oklch(0.556 0 0);
34+
--accent: oklch(0.97 0 0);
35+
--accent-foreground: oklch(0.205 0 0);
36+
--destructive: oklch(0.577 0.245 27.325);
37+
--border: oklch(0.922 0 0);
38+
--input: oklch(0.922 0 0);
39+
--ring: oklch(0.708 0 0);
40+
--chart-1: oklch(0.646 0.222 41.116);
41+
--chart-2: oklch(0.6 0.118 184.704);
42+
--chart-3: oklch(0.398 0.07 227.392);
43+
--chart-4: oklch(0.828 0.189 84.429);
44+
--chart-5: oklch(0.769 0.188 70.08);
45+
--sidebar: oklch(0.985 0 0);
46+
--sidebar-foreground: oklch(0.145 0 0);
47+
--sidebar-primary: oklch(0.205 0 0);
48+
--sidebar-primary-foreground: oklch(0.985 0 0);
49+
--sidebar-accent: oklch(0.97 0 0);
50+
--sidebar-accent-foreground: oklch(0.205 0 0);
51+
--sidebar-border: oklch(0.922 0 0);
52+
--sidebar-ring: oklch(0.708 0 0);
53+
}
54+
55+
.dark {
56+
--background: oklch(0.145 0 0);
57+
--foreground: oklch(0.985 0 0);
58+
--card: oklch(0.205 0 0);
59+
--card-foreground: oklch(0.985 0 0);
60+
--popover: oklch(0.269 0 0);
61+
--popover-foreground: oklch(0.985 0 0);
62+
--primary: oklch(0.922 0 0);
63+
--primary-foreground: oklch(0.205 0 0);
64+
--secondary: oklch(0.269 0 0);
65+
--secondary-foreground: oklch(0.985 0 0);
66+
--muted: oklch(0.269 0 0);
67+
--muted-foreground: oklch(0.708 0 0);
68+
--accent: oklch(0.371 0 0);
69+
--accent-foreground: oklch(0.985 0 0);
70+
--destructive: oklch(0.704 0.191 22.216);
71+
--border: oklch(1 0 0 / 10%);
72+
--input: oklch(1 0 0 / 15%);
73+
--ring: oklch(0.556 0 0);
74+
--chart-1: oklch(0.488 0.243 264.376);
75+
--chart-2: oklch(0.696 0.17 162.48);
76+
--chart-3: oklch(0.769 0.188 70.08);
77+
--chart-4: oklch(0.627 0.265 303.9);
78+
--chart-5: oklch(0.645 0.246 16.439);
79+
--sidebar: oklch(0.205 0 0);
80+
--sidebar-foreground: oklch(0.985 0 0);
81+
--sidebar-primary: oklch(0.488 0.243 264.376);
82+
--sidebar-primary-foreground: oklch(0.985 0 0);
83+
--sidebar-accent: oklch(0.269 0 0);
84+
--sidebar-accent-foreground: oklch(0.985 0 0);
85+
--sidebar-border: oklch(1 0 0 / 10%);
86+
--sidebar-ring: oklch(0.439 0 0);
87+
}
88+
89+
@layer base {
90+
* {
91+
border-color: var(--border);
92+
outline-color: var(--ring);
93+
}
94+
95+
body {
96+
background-color: var(--background);
97+
color: var(--foreground);
98+
}
99+
}
100+
```
101+
102+
And voilà! You are now ready to use Shadcn components in your Symfony project.

src/Toolkit/kits/shadcn/manifest.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
2-
"name": "Shadcn",
2+
"name": "Shadcn UI",
3+
"description": "Component based on the Shadcn UI library, one of the most popular design systems in JavaScript world.",
34
"license": "MIT",
45
"homepage": "https://ux.symfony.com/components",
5-
"authors": ["Shadcn", "Symfony Community"]
6+
"authors": ["Shadcn", "Symfony Community"],
7+
"ux-icon": "simple-icons:shadcnui"
68
}

src/Toolkit/src/Assert.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*/
2323
public static function kitName(string $name): void
2424
{
25-
if (1 !== preg_match('/^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/', $name)) {
25+
if (1 !== preg_match('/^[a-zA-Z0-9](?:[a-zA-Z0-9-_ ]{0,61}[a-zA-Z0-9])?$/', $name)) {
2626
throw new \InvalidArgumentException(\sprintf('Invalid kit name "%s".', $name));
2727
}
2828
}

src/Toolkit/src/Kit/Kit.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public function __construct(
3636
public readonly string $homepage,
3737
public readonly array $authors,
3838
public readonly string $license,
39+
public readonly ?string $description = null,
40+
public readonly ?string $uxIcon = null,
41+
public ?string $installAsMarkdown = null,
3942
private array $components = [],
4043
) {
4144
Assert::kitName($this->name);

src/Toolkit/src/Kit/KitFactory.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@ public function createKitFromAbsolutePath(string $absolutePath): Kit
5454
$manifest = json_decode($this->filesystem->readFile($manifestPath), true, flags: \JSON_THROW_ON_ERROR);
5555

5656
$kit = new Kit(
57-
$absolutePath,
58-
$manifest['name'] ?? throw new \InvalidArgumentException('Manifest file is missing "name" key.'),
59-
$manifest['homepage'] ?? throw new \InvalidArgumentException('Manifest file is missing "homepage" key.'),
60-
$manifest['authors'] ?? throw new \InvalidArgumentException('Manifest file is missing "authors" key.'),
61-
$manifest['license'] ?? throw new \InvalidArgumentException('Manifest file is missing "license" key.'),
57+
path: $absolutePath,
58+
name: $manifest['name'] ?? throw new \InvalidArgumentException('Manifest file is missing "name" key.'),
59+
homepage: $manifest['homepage'] ?? throw new \InvalidArgumentException('Manifest file is missing "homepage" key.'),
60+
authors: $manifest['authors'] ?? throw new \InvalidArgumentException('Manifest file is missing "authors" key.'),
61+
license: $manifest['license'] ?? throw new \InvalidArgumentException('Manifest file is missing "license" key.'),
62+
description: $manifest['description'] ?? null,
63+
uxIcon: $manifest['ux-icon'] ?? null,
6264
);
6365

6466
$this->synchronizeKit($kit);
@@ -69,6 +71,7 @@ public function createKitFromAbsolutePath(string $absolutePath): Kit
6971
private function synchronizeKit(Kit $kit): void
7072
{
7173
$this->synchronizeKitComponents($kit);
74+
$this->synchronizeKitDocumentation($kit);
7275
}
7376

7477
private function synchronizeKitComponents(Kit $kit): void
@@ -86,15 +89,13 @@ private function synchronizeKitComponents(Kit $kit): void
8689
$relativePathNameToKit = $file->getRelativePathname();
8790
$relativePathName = str_replace($componentsPath.\DIRECTORY_SEPARATOR, '', $relativePathNameToKit);
8891
$componentName = $this->extractComponentName($relativePathName);
89-
$docPath = Path::join($kit->path, 'docs', 'components', $componentName.'.md');
9092
$component = new Component(
9193
name: $componentName,
9294
files: [new File(
9395
type: FileType::Twig,
9496
relativePathNameToKit: $relativePathNameToKit,
9597
relativePathName: $relativePathName,
9698
)],
97-
doc: $this->filesystem->exists($docPath) ? new Doc($this->filesystem->readFile($docPath)) : null,
9899
);
99100

100101
$kit->addComponent($component);
@@ -107,4 +108,21 @@ private static function extractComponentName(string $pathnameRelativeToKit): str
107108
{
108109
return str_replace(['.html.twig', '/'], ['', ':'], $pathnameRelativeToKit);
109110
}
111+
112+
private function synchronizeKitDocumentation(Kit $kit): void
113+
{
114+
// Read INSTALL.md if exists
115+
$fileInstall = Path::join($kit->path, 'INSTALL.md');
116+
if ($this->filesystem->exists($fileInstall)) {
117+
$kit->installAsMarkdown = $this->filesystem->readFile($fileInstall);
118+
}
119+
120+
// Iterate over Component and find their documentation
121+
foreach ($kit->getComponents() as $component) {
122+
$docPath = Path::join($kit->path, 'docs', 'components', $component->name.'.md');
123+
if ($this->filesystem->exists($docPath)) {
124+
$component->doc = new Doc($this->filesystem->readFile($docPath));
125+
}
126+
}
127+
}
110128
}

src/Toolkit/tests/AssertTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ public static function provideValidKitNames(): \Generator
3333
yield ['1-my-kit'];
3434
yield ['my-kit-1'];
3535
yield ['my-kit-1-with-dashes'];
36-
yield ['Shadcn-UI'];
37-
yield ['Shadcn-UI-1'];
36+
yield ['Shadcn UI'];
37+
yield ['Shadcn UI-1'];
3838
// Single character
3939
yield ['a'];
4040
yield ['1'];
@@ -47,6 +47,7 @@ public static function provideValidKitNames(): \Generator
4747
yield ['a-b-c'];
4848
yield ['a1-b2-c3'];
4949
yield ['A1-B2-C3'];
50+
yield ['my_kit'];
5051
}
5152

5253
/**
@@ -71,7 +72,6 @@ public static function provideInvalidKitNames(): \Generator
7172
// Ending with hyphen
7273
yield ['my-kit-'];
7374
// Invalid characters
74-
yield ['my_kit'];
7575
yield ['my.kit'];
7676
yield ['my@kit'];
7777
// Too long (64 chars)

src/Toolkit/tests/Command/LintKitCommandTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function testShouldBeAbleToLint(): void
2424
$this->consoleCommand('ux:toolkit:lint-kit shadcn')
2525
->execute()
2626
->assertSuccessful()
27-
->assertOutputContains('The kit "Shadcn" is valid, it has 46 components')
27+
->assertOutputContains('The kit "Shadcn UI" is valid, it has 46 components')
2828
;
2929
}
3030
}

src/Toolkit/tests/Kit/KitFactoryTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1515
use Symfony\UX\Toolkit\Dependency\ComponentDependency;
1616
use Symfony\UX\Toolkit\Dependency\PhpPackageDependency;
17-
use Symfony\UX\Toolkit\Dependency\Version;
1817
use Symfony\UX\Toolkit\Kit\KitFactory;
1918

2019
final class KitFactoryTest extends KernelTestCase

src/Toolkit/tests/Registry/GitHubRegistryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function testCanGetKitFromGithub(): void
6464
$kit = $githubRegistry->getKit('github.com/user/repo');
6565

6666
$this->assertTrue($isHttpClientCalled);
67-
$this->assertSame('Shadcn', $kit->name);
67+
$this->assertSame('Shadcn UI', $kit->name);
6868
$this->assertNotEmpty($kit->getComponents());
6969
$this->assertFileExists($kit->path);
7070
$this->assertFileExists(Path::join($kit->path, 'templates/components/Button.html.twig'));

src/Toolkit/tests/Registry/LocalRegistryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ public function testCanGetKit(): void
2828
$kit = $localRegistry->getKit('shadcn');
2929

3030
$this->assertInstanceOf(Kit::class, $kit);
31-
$this->assertSame('Shadcn', $kit->name);
31+
$this->assertSame('Shadcn UI', $kit->name);
3232
}
3333
}

0 commit comments

Comments
 (0)