Skip to content

Commit 2bbd623

Browse files
authored
Merge pull request #2024 from hydephp/refactor-hydefront-styles-to-tailwind
[2.x] Refactor HydeFront styles to TailwindCSS
2 parents 9598933 + 7e65fd6 commit 2bbd623

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+325
-1083
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -109,41 +109,6 @@ jobs:
109109
run: php monorepo/scripts/tests/${{ matrix.script }}.php
110110

111111

112-
build-hydefront-assets:
113-
114-
runs-on: ubuntu-latest
115-
needs: run-smoke-tests
116-
117-
steps:
118-
- uses: actions/checkout@v4
119-
120-
- name: Setup Node.js
121-
uses: actions/setup-node@v4
122-
with:
123-
cache: 'npm'
124-
125-
- name: Install Node.js dependencies
126-
working-directory: 'packages/hydefront'
127-
run: npm ci
128-
129-
- name: Build assets for production
130-
working-directory: 'packages/hydefront'
131-
run: npm run build
132-
133-
- name: Upload artifacts
134-
uses: actions/upload-artifact@v4
135-
with:
136-
name: 'hydefront'
137-
path: 'packages/hydefront/dist'
138-
139-
- name: Commit changes
140-
uses: EndBug/add-and-commit@v9
141-
with:
142-
add: 'packages/hydefront/dist'
143-
message: 'Compile HydeFront assets for production'
144-
new_branch: compile-hydefront
145-
146-
147112
build-tailwindcss:
148113

149114
runs-on: ubuntu-latest

RELEASE_NOTES.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ This serves two purposes:
9898
- The realtime compiler now only serves assets from the media source directory (`_media`), and no longer checks the site output directory (`_site/media`) in https://github.com/hydephp/develop/pull/2012
9999
- **Breaking:** Replaced `--run-dev` and `--run-prod` build command flags with a single `--run-vite` flag that uses Vite to build assets in https://github.com/hydephp/develop/pull/2013
100100
- Moved the Vite build step to run before the site build to prevent duplicate media asset transfers in https://github.com/hydephp/develop/pull/2013
101+
- Ported the HydeSearch plugin used for the documentation search to be an Alpine.js implementation in https://github.com/hydephp/develop/pull/2029
102+
- Renamed Blade component `hyde::components.docs.search-widget` to `hyde::components.docs.search-modal` in https://github.com/hydephp/develop/pull/2029
103+
- Added support for customizing the search implementation by creating a `resources/js/HydeSearch.js` file in https://github.com/hydephp/develop/pull/2031
104+
- Normalized default Tailwind Typography Prose code block styles to match Torchlight's theme, ensuring consistent styling across Markdown and Torchlight code blocks in https://github.com/hydephp/develop/pull/2036.
105+
- Extracted CSS component partials in HydeFront in https://github.com/hydephp/develop/pull/2038
106+
- Replaced HydeFront styles with Tailwind in https://github.com/hydephp/develop/pull/2024
101107

102108
### Deprecated
103109

@@ -121,6 +127,10 @@ This serves two purposes:
121127
- Removed `Hyde::siteMediaPath()` method replaced by `MediaFile::outputPath()` in https://github.com/hydephp/develop/pull/1911
122128
- Removed Laravel Mix as a dependency in https://github.com/hydephp/develop/pull/2010 (replaced with Vite)
123129
- **Breaking:** Removed `npm run prod` command (replaced with `npm run build`)
130+
- Removed CDN include for the HydeSearch plugin replaced by Alpine.js implementation in https://github.com/hydephp/develop/pull/2029
131+
- This also removes the `<x-hyde::docs.search-input />` and `<x-hyde::docs.search-scripts />` Blade components, replaced by the new `<x-hyde::docs.hyde-search />` component.
132+
- Removed the `.torchlight-enabled` CSS class in https://github.com/hydephp/develop/pull/2036.
133+
- Removed The `hyde.css` file from HydeFront in https://github.com/hydephp/develop/pull/2037 as all styles were refactored to Tailwind in https://github.com/hydephp/develop/pull/2024.
124134

125135
### Fixed
126136

@@ -138,6 +148,12 @@ This serves two purposes:
138148
- Simplified the asset file locator to only serve files from the media source directory in https://github.com/hydephp/develop/pull/2012
139149
- Added Vite HMR support in https://github.com/hydephp/develop/pull/2016
140150

151+
#### HydeFront
152+
153+
- Removed all Sass styles after porting everything to Tailwind in https://github.com/hydephp/develop/pull/2024
154+
- Removed the `hyde.css` file in https://github.com/hydephp/develop/pull/2037 as all its styles were refactored to Tailwind in https://github.com/hydephp/develop/pull/2024
155+
- Extracted CSS component partials in https://github.com/hydephp/develop/pull/2038
156+
141157
### Upgrade Guide
142158

143159
Please see the "Breaking changes & upgrade guide" section below for more information.

_media/app.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/creating-content/documentation-pages.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,13 @@ If you set this to false, Hyde will match the directory structure of the source
351351

352352
### Introduction
353353

354-
The HydeSearch plugin adds a search feature to documentation pages. It consists of two parts, a search index generator that runs during the build command, and a frontend JavaScript plugin that adds the actual search widget.
354+
Hyde includes a built-in search feature for documentation pages powered by Alpine.js. It consists of two parts:
355+
1. A search index generator that runs during the build command
356+
2. An Alpine.js powered frontend that provides the search interface
355357

356-
>info Tip: The HydeSearch plugin is what powers the search feature on this site! Why not [try it out](search)?
358+
>info Tip: The search feature is what powers the search on this site! Why not [try it out](search)?
357359

358-
The search feature is enabled by default. You can disable it by removing the `DocumentationSearch` option from the Hyde `Features` config array.
360+
The search feature is enabled by default. You can disable it by removing the `DocumentationSearch` option from the Hyde `Features` config array:
359361

360362
```php
361363
// filepath: config/hyde.php
@@ -366,17 +368,27 @@ The search feature is enabled by default. You can disable it by removing the `Do
366368

367369
### Using the Search
368370

369-
The search works by generating a JSON search index which the JavaScript plugin loads asynchronously.
371+
The search works by generating a JSON search index which Alpine.js loads asynchronously. There are two ways to access the search:
370372

371-
Two ways to access the search are added, one is a full page search screen that will be saved to `docs/search.html`.
372-
373-
The second method is a button added to the documentation pages, similar to how Algolia DocSearch works. Opening it will open a modal with an integrated search screen. You can also open the dialog using the keyboard shortcut `/`.
373+
1. A full-page search screen at `docs/search.html`
374+
2. A modal dialog accessible via a button in the documentation pages (similar to Algolia DocSearch). You can also open this dialog using the keyboard shortcut `/`
374375

375376
>info The full page can be disabled by setting `create_search_page` to `false` in the `docs` config.
376377

378+
### Search Features
379+
380+
The search implementation includes:
381+
- Real-time search results as you type
382+
- Context highlighting of search terms
383+
- Match counting and search timing statistics
384+
- Dark mode support
385+
- Loading state indicators
386+
- Keyboard navigation support
387+
- Mobile-responsive design
388+
377389
### Hiding Pages from Indexing
378390

379-
If you have a large page on your documentation site, like a changelog, you may want to hide it from the search index. You can do this by adding the page identifier to the `exclude_from_search` array in the `docs` config, similar to how navigation menu items are hidden. The page will still be accessible as normal but will not be added to the search index JSON file.
391+
For large pages like changelogs, you may want to exclude them from the search index. Add the page identifier to the `exclude_from_search` array in the docs config:
380392

381393
```php
382394
// filepath: config/docs.php
@@ -385,9 +397,11 @@ If you have a large page on your documentation site, like a changelog, you may w
385397
]
386398
```
387399

400+
The page will remain accessible but won't appear in search results.
401+
388402
### Live Search with the Realtime Compiler
389403

390-
The Realtime Compiler that powers the `php hyde serve` command will automatically generate a fresh search index each time the browser requests it.
404+
When using `php hyde serve`, the Realtime Compiler automatically generates a fresh search index each time it's requested, ensuring your search results stay current during development.
391405

392406
## Automatic "Edit Page" Button
393407

docs/creating-content/managing-assets.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ With Hyde, **you don't have to do it**, in fact, you can skip this entire page i
1313
But as always with Hyde, you can customize everything if you want to.
1414

1515
Hyde ships with a complete frontend using Blade views, TailwindCSS styles, and Alpine.js interactions.
16-
Some extra custom styles are made in the HydeFront package, which is pre-installed and bundled in the pre-configured Tailwind and Vite setup.
16+
Some extra component styles are organized into modular files in the HydeFront package, which is pre-installed and bundled in the pre-configured Tailwind and Vite setup.
1717

1818
To get you started quickly, all the styles are already compiled and minified into `_media/app.css`,
1919
which will be copied to the `_site/media/app.css` directory when you run `php hyde build`.
@@ -26,7 +26,7 @@ No, it is optional. All the compiled styles that you need are already installed,
2626

2727
### When Should Assets be Compiled?
2828

29-
The `_media/app.css` file that comes with Hyde contains TailwindCSS for all classes that are used in the default Blade views, as well as the HydeFront custom styles.
29+
The `_media/app.css` file that comes with Hyde contains TailwindCSS for all classes that are used in the default Blade views, as well as the HydeFront component styles.
3030
If you want to customize the Tailwind settings or add custom styles, you will need to recompile the styles yourself.
3131

3232
For example, if you customize the Blade views and add new classes or add new classes in Blade-based pages, you may need to compile the assets yourself to get the new styles.
@@ -66,6 +66,12 @@ When running the `npm run dev/prod` command, Vite will compile the `resources/as
6666

6767
The compiled assets will then be automatically copied to `_site/media` when you run `php hyde build`.
6868

69+
### Customizing HydeFront Components
70+
71+
HydeFront components are modular and can be easily customized to fit your needs.
72+
73+
You can either remove the import of the component you want to customize and replace it with your own styles, or keep the import and add overriding styles after it (since CSS cascade order matters).
74+
6975
## Telling Hyde where to find assets
7076

7177
### Customizing the Blade templates

monorepo/docs/hydefront.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Internal HydeFront documentation
22

3-
## Building and creating a new HydeFront version
3+
## Creating a new HydeFront version
44

55
### Prerequisites
66

@@ -28,15 +28,14 @@ cd ../../
2828
npm link hydefront
2929
```
3030

31-
### Build and setup
31+
### Setup
3232

3333
```bash
3434
cd packages/hydefront
3535
git pull origin master
36-
npm run build
3736
```
3837

39-
### Build, version, and publish
38+
### Version and publish
4039

4140
Head back to the monorepo root and run the following command to bump the version of the HydeFront package:
4241

package-lock.json

Lines changed: 8 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
function initHydeSearch(searchIndexUrl) {
2+
return {
3+
searchIndex: [],
4+
searchTerm: '',
5+
results: [],
6+
isLoading: true,
7+
statusMessage: '',
8+
9+
async init() {
10+
const response = await fetch(searchIndexUrl);
11+
if (!response.ok) {
12+
console.error('Could not load search index');
13+
return;
14+
}
15+
this.searchIndex = await response.json();
16+
this.isLoading = false;
17+
},
18+
19+
search() {
20+
const startTime = performance.now();
21+
this.results = [];
22+
23+
if (!this.searchTerm) {
24+
this.statusMessage = '';
25+
window.dispatchEvent(new CustomEvent('search-results-updated', { detail: { hasResults: false } }));
26+
return;
27+
}
28+
29+
const searchResults = this.searchIndex.filter(entry =>
30+
entry.title.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
31+
entry.content.toLowerCase().includes(this.searchTerm.toLowerCase())
32+
);
33+
34+
if (searchResults.length === 0) {
35+
this.statusMessage = 'No results found.';
36+
window.dispatchEvent(new CustomEvent('search-results-updated', { detail: { hasResults: false } }));
37+
return;
38+
}
39+
40+
const totalMatches = searchResults.reduce((acc, result) => {
41+
return acc + (result.content.match(new RegExp(this.searchTerm, 'gi')) || []).length;
42+
}, 0);
43+
44+
searchResults.sort((a, b) => {
45+
return (b.content.match(new RegExp(this.searchTerm, 'gi')) || []).length
46+
- (a.content.match(new RegExp(this.searchTerm, 'gi')) || []).length;
47+
});
48+
49+
this.results = searchResults.map(result => {
50+
const matches = (result.content.match(new RegExp(this.searchTerm, 'gi')) || []).length;
51+
const context = this.getSearchContext(result.content);
52+
return { ...result, matches, context };
53+
});
54+
55+
const timeMs = Math.round((performance.now() - startTime) * 100) / 100;
56+
this.statusMessage = `Found ${totalMatches} result${totalMatches !== 1 ? 's' : ''} in ${searchResults.length} pages. ~${timeMs}ms`;
57+
58+
window.dispatchEvent(new CustomEvent('search-results-updated', { detail: { hasResults: true } }));
59+
},
60+
61+
getSearchContext(content) {
62+
const searchTermPos = content.toLowerCase().indexOf(this.searchTerm.toLowerCase());
63+
const sentenceStart = content.lastIndexOf('.', searchTermPos) + 1;
64+
const sentenceEnd = content.indexOf('.', searchTermPos) + 1;
65+
const sentence = content.substring(sentenceStart, sentenceEnd).trim();
66+
const template = document.getElementById('search-highlight-template');
67+
68+
return sentence.replace(
69+
new RegExp(this.searchTerm, 'gi'),
70+
match => {
71+
const mark = template.content.querySelector('mark').cloneNode();
72+
mark.textContent = match;
73+
return mark.outerHTML;
74+
}
75+
);
76+
}
77+
};
78+
}

packages/framework/resources/views/components/docs/documentation-article.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<article id="document" itemscope itemtype="https://schema.org/Article" @class([
66
'mx-auto lg:ml-8 max-w-3xl p-12 md:px-16 max-w-[1000px] min-h-[calc(100vh_-_4rem)]',
77
config('markdown.prose_classes', 'prose dark:prose-invert'),
8-
'torchlight-enabled' => $article && $article->hasTorchlight()])>
8+
])>
99
@yield('content')
1010

1111
@if ($article)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
@props(['modal' => true])
2+
3+
<div id="hyde-search" x-data="hydeSearch">
4+
<template id="search-highlight-template">
5+
<mark class="bg-yellow-400 dark:bg-yellow-300"></mark>
6+
</template>
7+
8+
<div class="relative">
9+
<input type="search" name="search" id="search-input" x-model="searchTerm" @input="search()" placeholder="Search..." autocomplete="off" autofocus
10+
{{ $attributes->merge(['class' => 'w-full rounded text-base leading-normal bg-gray-100 dark:bg-gray-700 py-2 px-3']) }}
11+
>
12+
13+
<div x-show="isLoading" class="absolute right-3 top-2.5">
14+
<div class="animate-spin h-5 w-5 border-2 border-gray-500 rounded-full border-t-transparent"></div>
15+
</div>
16+
</div>
17+
18+
<div x-show="searchTerm" class="mt-4">
19+
<p x-text="statusMessage" class="text-sm text-gray-600 dark:text-gray-400 mb-2 pb-2"></p>
20+
21+
<dl class="space-y-4 -mt-4 pl-2 -ml-2 {{ $modal ? 'max-h-[60vh] overflow-x-hidden overflow-y-auto' : '' }}">
22+
<template x-for="result in results" :key="result.slug">
23+
<div>
24+
<dt>
25+
<a :href="result.destination" x-text="result.title" class="text-indigo-600 dark:text-indigo-400 hover:underline font-medium"></a><span class="text-sm text-gray-600 dark:text-gray-400" x-text="`, ${result.matches} occurrence${result.matches !== 1 ? 's' : ''} found.`"></span>
26+
</dt>
27+
<dd class="mt-1 text-sm text-gray-700 dark:text-gray-300" x-html="result.context"></dd>
28+
</div>
29+
</template>
30+
</dl>
31+
</div>
32+
33+
<script>
34+
{!! file_get_contents(file_exists(Hyde::path('resources/js/HydeSearch.js'))
35+
? Hyde::path('resources/js/HydeSearch.js')
36+
: Hyde::vendorPath('resources/js/HydeSearch.js')
37+
) !!}
38+
39+
document.addEventListener('alpine:init', () => {
40+
Alpine.data('hydeSearch', () =>
41+
initHydeSearch('{{ Hyde::relativeLink(\Hyde\Framework\Features\Documentation\DocumentationSearchIndex::outputPath()) }}')
42+
);
43+
});
44+
</script>
45+
</div>

0 commit comments

Comments
 (0)