Resolve the package's own components through its namespace
Package views now write <x-livewire-material::button>, so a configured prefix (which Blade spells <x-m::button>) and an application component of the same name can no longer break or shadow them. The showcase rewrites its examples to the configured prefix. Adds the README, and waits for the adaptive rail to hear a resize before the navigation tests press its menu button. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
co-authored by
Claude Opus 5
parent
8f174520eb
commit
1e580c573e
@@ -0,0 +1,164 @@
|
|||||||
|
# Livewire Material
|
||||||
|
|
||||||
|
Material 3 Expressive components for Laravel and Livewire, built on Tailwind CSS 4.
|
||||||
|
|
||||||
|
- Anonymous Blade components for the current M3 Expressive catalogue: buttons and FABs, menus, chips, text fields, selection controls, sliders, pickers, dialogs and sheets, lists, cards, carousels, progress and loading indicators, snackbars, tabs, app bars, toolbars, navigation bars and rails, an adaptive app shell, data tables and pagination.
|
||||||
|
- A colour scheme generated from one seed colour with Google's colour science (`php artisan material:scheme`), light and dark, and a theme that is chosen before the first paint.
|
||||||
|
- The full Material Symbols Rounded set and the M3 Expressive shapes, drawn inline without an icon package.
|
||||||
|
- Error pages and a Markdown mail theme in the same scheme.
|
||||||
|
- A showcase of every component in the application's own scheme, a design guard for tests, and Laravel Boost guidelines and a skill for AI agents.
|
||||||
|
|
||||||
|
No JavaScript libraries beyond the Alpine that ships with Livewire. Browsers: Chrome 125+, Firefox 147+, Safari 18.4+.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
PHP 8.4+, Laravel 13, Livewire 4, Tailwind CSS 4 with Vite, and Node (for `material:scheme`).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The package is served from Gitea. Add the repository and require it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer config repositories.livewire-material vcs https://gitea.nonameweb.ch/noNameWEB/livewire-material.git
|
||||||
|
composer require nonameweb/livewire-material
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stylesheet and script
|
||||||
|
|
||||||
|
The application's build imports from `vendor/`, so Composer packages must be installed before `npm run build` — in a Dockerfile, copy `composer.json`, run `composer install`, then build the assets.
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* resources/css/app.css */
|
||||||
|
@import 'tailwindcss';
|
||||||
|
@import '../../vendor/nonameweb/livewire-material/resources/css/material.css';
|
||||||
|
@import './material-scheme.css';
|
||||||
|
|
||||||
|
@source '../../vendor/nonameweb/livewire-material/resources/views';
|
||||||
|
@source '../../vendor/nonameweb/livewire-material/src';
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
// resources/js/app.js
|
||||||
|
import '../../vendor/nonameweb/livewire-material/resources/js/material.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not install Alpine separately; Livewire provides it.
|
||||||
|
|
||||||
|
### Layout
|
||||||
|
|
||||||
|
The theme script goes in `<head>`, before `@vite`, so the page paints in the visitor's theme:
|
||||||
|
|
||||||
|
```blade
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<x-theme-script />
|
||||||
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
|
</head>
|
||||||
|
<body class="bg-surface font-sans text-on-surface antialiased">
|
||||||
|
{{ $slot }}
|
||||||
|
<x-toast />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Colour scheme
|
||||||
|
|
||||||
|
Generate the scheme from a seed colour. It writes `resources/css/material-scheme.css` (imported above) and `material-scheme.json` (read by the mail theme):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan material:scheme "#4f46e5" --variant=tonal-spot
|
||||||
|
```
|
||||||
|
|
||||||
|
Variants: `tonal-spot`, `vibrant`, `expressive`, `neutral`, `fidelity`, `content`, `monochrome`, `rainbow`, `fruit-salad`. `--contrast` runs from -1 to 1; `--success`, `--warning` and `--info` seed the state colours. Regenerate instead of editing the file.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan vendor:publish --tag=livewire-material-config
|
||||||
|
```
|
||||||
|
|
||||||
|
- `prefix` — components are `<x-button>`, `<x-card>`… Set `'m'` when a name clashes with the application's own components, and they become `<x-m::button>`. `<x-livewire-material::button>` always works.
|
||||||
|
- `theme.default` (`light`, `dark` or `system`), `theme.storage_key`, `theme.legacy_keys` (an earlier toggle's localStorage keys, adopted once).
|
||||||
|
- `fields.variant` — text fields `outlined` (default) or `filled`.
|
||||||
|
- `pagination` — draw Laravel's and Livewire's paginators in M3 (default `true`).
|
||||||
|
- `showcase.enabled`, `showcase.path`, `showcase.middleware`, `showcase.vite`.
|
||||||
|
- `node` — the Node binary for `material:scheme`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```blade
|
||||||
|
<x-card title="holiday-photos.zip" subtitle="248 MB · expires in 3 days" variant="outlined">
|
||||||
|
<x-slot:actions>
|
||||||
|
<x-button label="Copy link" icon="content_copy" wire:click="copy" />
|
||||||
|
<x-button label="Delete" danger wire:click="$set('confirming', true)" />
|
||||||
|
</x-slot:actions>
|
||||||
|
</x-card>
|
||||||
|
|
||||||
|
<x-modal wire:model="confirming" title="Delete this share?" icon="delete">
|
||||||
|
Recipients lose access at once.
|
||||||
|
<x-slot:actions>
|
||||||
|
<x-button label="Cancel" x-on:click="close()" />
|
||||||
|
<x-button label="Delete" danger wire:click="delete" />
|
||||||
|
</x-slot:actions>
|
||||||
|
</x-modal>
|
||||||
|
```
|
||||||
|
|
||||||
|
```php
|
||||||
|
use NoNameWeb\LivewireMaterial\Concerns\Toasts;
|
||||||
|
|
||||||
|
class Shares extends Component
|
||||||
|
{
|
||||||
|
use Toasts;
|
||||||
|
|
||||||
|
public function copy(): void
|
||||||
|
{
|
||||||
|
$this->success('Link copied');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Every component, prop and slot is documented in the Boost skill (`resources/boost/skills/livewire-material-development/SKILL.md`) and shown in the showcase.
|
||||||
|
|
||||||
|
## Showcase
|
||||||
|
|
||||||
|
While the application runs locally (or with `MATERIAL_SHOWCASE=true`), `/material` renders every token and component, in every variant, in the application's own scheme and theme.
|
||||||
|
|
||||||
|
## Testing the design
|
||||||
|
|
||||||
|
```php
|
||||||
|
use NoNameWeb\LivewireMaterial\Testing\DesignGuard;
|
||||||
|
|
||||||
|
it('uses only what compiles', function () {
|
||||||
|
expect(DesignGuard::scan([resource_path('views'), resource_path('js'), app_path()])
|
||||||
|
->forbidColours(['tertiary'])
|
||||||
|
->violations())->toBe([]);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The guard fails on maryUI tags, daisyUI classes, colours the theme does not declare, unknown Material Symbol names and Blade directives written inside component tags.
|
||||||
|
|
||||||
|
## AI agents
|
||||||
|
|
||||||
|
With [Laravel Boost](https://github.com/laravel/boost), `php artisan boost:install` (or `boost:update --discover`) picks up the package's guideline and the `livewire-material-development` skill.
|
||||||
|
|
||||||
|
## Developing the package
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer install && npm install
|
||||||
|
npm run build # the Workbench's assets (or `npm run dev` while working)
|
||||||
|
composer serve # the showcase at http://127.0.0.1:8000/material
|
||||||
|
vendor/bin/pest --testsuite=Feature
|
||||||
|
npx playwright install
|
||||||
|
vendor/bin/pest --testsuite=Browser --browser chrome # also firefox, safari
|
||||||
|
```
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Material Symbols, the M3 Expressive shapes, Google Sans Flex, material-color-utilities and Jetpack Compose Material 3's tokens and algorithms are Google's and the Android Open Source Project's; see `NOTICE`.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT. See `LICENSE`.
|
||||||
@@ -8,8 +8,10 @@ return [
|
|||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Every component is an anonymous Blade component. Without a prefix they are
|
| Every component is an anonymous Blade component. Without a prefix they are
|
||||||
| <x-button>, <x-card> and so on; set a prefix such as 'm-' when a name
|
| <x-button>, <x-card> and so on; set a prefix such as 'm' when a name
|
||||||
| clashes with one of the application's own components (<x-m-button>).
|
| clashes with one of the application's own components, and they become
|
||||||
|
| <x-m::button>, <x-m::card>. They are always <x-livewire-material::button>
|
||||||
|
| as well.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -764,7 +764,7 @@ It fails on maryUI tags, daisyUI classes, colours the theme does not declare, un
|
|||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
- Components are anonymous Blade components: `<x-name>` without a prefix, or `<x-{prefix}name>` when `config('livewire-material.prefix')` is set.
|
- Components are anonymous Blade components: `<x-name>` without a prefix, or `<x-{prefix}::name>` when `config('livewire-material.prefix')` is set; `<x-livewire-material::name>` always works.
|
||||||
- Write class names out whole. Tailwind cannot compile `'text-'.$tone` or `type-{{ $size }}`, and the design guard cannot read them.
|
- Write class names out whole. Tailwind cannot compile `'text-'.$tone` or `type-{{ $size }}`, and the design guard cannot read them.
|
||||||
- The showcase at `/material` (local only, `MATERIAL_SHOWCASE=true` to force it) renders every token and component.
|
- The showcase at `/material` (local only, `MATERIAL_SHOWCASE=true` to force it) renders every token and component.
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
$initials = $image ? null : ($avatar ?? \Illuminate\Support\Str::of((string) $name)->explode(' ')->filter()->take(2)->map(fn (string $word): string => mb_strtoupper(mb_substr($word, 0, 1)))->join(''));
|
$initials = $image ? null : ($avatar ?? \Illuminate\Support\Str::of((string) $name)->explode(' ')->filter()->take(2)->map(fn (string $word): string => mb_strtoupper(mb_substr($word, 0, 1)))->join(''));
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-menu :$label :$position {{ $attributes }}>
|
<x-livewire-material::menu :$label :$position {{ $attributes }}>
|
||||||
<x-slot:trigger>
|
<x-slot:trigger>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
@elseif (filled($initials))
|
@elseif (filled($initials))
|
||||||
{{ $initials }}
|
{{ $initials }}
|
||||||
@else
|
@else
|
||||||
<x-icon name="person" />
|
<x-livewire-material::icon name="person" />
|
||||||
@endif
|
@endif
|
||||||
</button>
|
</button>
|
||||||
</x-slot:trigger>
|
</x-slot:trigger>
|
||||||
@@ -60,20 +60,20 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<x-menu-separator />
|
<x-livewire-material::menu-separator />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
|
|
||||||
@if ($theme)
|
@if ($theme)
|
||||||
<x-menu-item icon="contrast" x-on:click="$store.theme.toggle()" data-account-theme>
|
<x-livewire-material::menu-item icon="contrast" x-on:click="$store.theme.toggle()" data-account-theme>
|
||||||
<span x-text="$store.theme.resolved === 'dark' ? @js(__('Light theme')) : @js(__('Dark theme'))">{{ __('Theme') }}</span>
|
<span x-text="$store.theme.resolved === 'dark' ? @js(__('Light theme')) : @js(__('Dark theme'))">{{ __('Theme') }}</span>
|
||||||
</x-menu-item>
|
</x-livewire-material::menu-item>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@isset($footer)
|
@isset($footer)
|
||||||
<x-menu-separator />
|
<x-livewire-material::menu-separator />
|
||||||
|
|
||||||
{{ $footer }}
|
{{ $footer }}
|
||||||
@endisset
|
@endisset
|
||||||
</x-menu>
|
</x-livewire-material::menu>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
{{ $attributes->class(['flex items-start gap-3 rounded-corner-md p-4', $colours]) }}
|
{{ $attributes->class(['flex items-start gap-3 rounded-corner-md p-4', $colours]) }}
|
||||||
>
|
>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" filled class="size-6" />
|
<x-livewire-material::icon :name="$icon" filled class="size-6" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="min-w-0 flex-1 space-y-1 self-center">
|
<div class="min-w-0 flex-1 space-y-1 self-center">
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
@if ($dismissible)
|
@if ($dismissible)
|
||||||
<button type="button" class="state-layer focus-ring -m-2 inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="shown = false">
|
<button type="button" class="state-layer focus-ring -m-2 inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="shown = false">
|
||||||
<x-icon name="close" class="size-5" />
|
<x-livewire-material::icon name="close" class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
class="sr-only focus:not-sr-only focus:fixed focus:start-4 focus:top-[calc(env(safe-area-inset-top)+1rem)] focus:z-[60] focus:rounded-corner-full focus:bg-inverse-surface focus:px-4 focus:py-2 focus:type-label-lg focus:text-inverse-on-surface focus:shadow-elevation-3 focus:outline-none"
|
class="sr-only focus:not-sr-only focus:fixed focus:start-4 focus:top-[calc(env(safe-area-inset-top)+1rem)] focus:z-[60] focus:rounded-corner-full focus:bg-inverse-surface focus:px-4 focus:py-2 focus:type-label-lg focus:text-inverse-on-surface focus:shadow-elevation-3 focus:outline-none"
|
||||||
>{{ __('Skip to content') }}</a>
|
>{{ __('Skip to content') }}</a>
|
||||||
|
|
||||||
<x-navigation-rail mode="adaptive" :label="$label" :width="$railWidth">
|
<x-livewire-material::navigation-rail mode="adaptive" :label="$label" :width="$railWidth">
|
||||||
@isset($brand)
|
@isset($brand)
|
||||||
<x-slot:brand>{{ $brand }}</x-slot:brand>
|
<x-slot:brand>{{ $brand }}</x-slot:brand>
|
||||||
@endisset
|
@endisset
|
||||||
@@ -99,14 +99,14 @@
|
|||||||
|
|
||||||
@foreach ($groups as $group)
|
@foreach ($groups as $group)
|
||||||
@if ($group->first()['section'] !== null)
|
@if ($group->first()['section'] !== null)
|
||||||
<x-navigation-rail-section :label="$group->first()['section']">
|
<x-livewire-material::navigation-rail-section :label="$group->first()['section']">
|
||||||
@foreach ($group as $item)
|
@foreach ($group as $item)
|
||||||
<x-navigation-rail-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
<x-livewire-material::navigation-rail-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-navigation-rail-section>
|
</x-livewire-material::navigation-rail-section>
|
||||||
@else
|
@else
|
||||||
@foreach ($group as $item)
|
@foreach ($group as $item)
|
||||||
<x-navigation-rail-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
<x-livewire-material::navigation-rail-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
@endisset
|
@endisset
|
||||||
</x-slot:footer>
|
</x-slot:footer>
|
||||||
@endif
|
@endif
|
||||||
</x-navigation-rail>
|
</x-livewire-material::navigation-rail>
|
||||||
|
|
||||||
<div class="flex min-w-0 flex-1 flex-col">
|
<div class="flex min-w-0 flex-1 flex-col">
|
||||||
{{ $top ?? '' }}
|
{{ $top ?? '' }}
|
||||||
@@ -134,13 +134,13 @@
|
|||||||
|
|
||||||
@if ($barItems->isNotEmpty())
|
@if ($barItems->isNotEmpty())
|
||||||
<div data-app-shell-bar class="fixed inset-x-0 bottom-0 z-30 sm:hidden">
|
<div data-app-shell-bar class="fixed inset-x-0 bottom-0 z-30 sm:hidden">
|
||||||
<x-navigation-bar :label="$label">
|
<x-livewire-material::navigation-bar :label="$label">
|
||||||
@foreach ($barItems as $item)
|
@foreach ($barItems as $item)
|
||||||
<x-navigation-bar-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
<x-livewire-material::navigation-bar-item :label="$item['title']" :icon="$item['icon']" :link="$item['url']" :active="$item['active']" :badge="$item['badge']" :no-wire-navigate="! $item['navigate']" />
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-navigation-bar>
|
</x-livewire-material::navigation-bar>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<x-toast />
|
<x-livewire-material::toast />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -202,13 +202,13 @@
|
|||||||
<{{ $tag }} {{ $attributes }}>
|
<{{ $tag }} {{ $attributes }}>
|
||||||
@if ($spinnerTarget)
|
@if ($spinnerTarget)
|
||||||
<span wire:loading.flex wire:target="{{ $spinnerTarget }}" class="items-center justify-center">
|
<span wire:loading.flex wire:target="{{ $spinnerTarget }}" class="items-center justify-center">
|
||||||
<x-loading :class="$iconSize" :label="false" />
|
<x-livewire-material::loading :class="$iconSize" :label="false" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<span class="contents" @if ($spinnerTarget) wire:loading.remove wire:target="{{ $spinnerTarget }}" @endif>
|
<span class="contents" @if ($spinnerTarget) wire:loading.remove wire:target="{{ $spinnerTarget }}" @endif>
|
||||||
<x-icon :name="$icon" :filled="$selected === true" :class="\Illuminate\Support\Arr::toCssClasses([$iconSize, 'max-sm:size-6' => $fab])" />
|
<x-livewire-material::icon :name="$icon" :filled="$selected === true" :class="\Illuminate\Support\Arr::toCssClasses([$iconSize, 'max-sm:size-6' => $fab])" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -217,10 +217,10 @@
|
|||||||
@endunless
|
@endunless
|
||||||
|
|
||||||
@if ($iconRight)
|
@if ($iconRight)
|
||||||
<x-icon :name="$iconRight" :class="$iconSize" />
|
<x-livewire-material::icon :name="$iconRight" :class="$iconSize" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($tip !== null)
|
@if ($tip !== null)
|
||||||
<x-tooltip :text="$tip" :side="$tipSide" :anchor="$anchor" />
|
<x-livewire-material::tooltip :text="$tip" :side="$tipSide" :anchor="$anchor" />
|
||||||
@endif
|
@endif
|
||||||
</{{ $tag }}>
|
</{{ $tag }}>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($separator)
|
@if ($separator)
|
||||||
<x-divider class="mt-4" />
|
<x-livewire-material::divider class="mt-4" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -136,7 +136,7 @@
|
|||||||
'hidden pointer-fine:flex' => $controls === null,
|
'hidden pointer-fine:flex' => $controls === null,
|
||||||
'flex' => $controls === true,
|
'flex' => $controls === true,
|
||||||
])>
|
])>
|
||||||
<x-button
|
<x-livewire-material::button
|
||||||
icon="chevron_left"
|
icon="chevron_left"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
:tooltip="__('Previous')"
|
:tooltip="__('Previous')"
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
x-on:click="previous()"
|
x-on:click="previous()"
|
||||||
class="rtl:-scale-x-100"
|
class="rtl:-scale-x-100"
|
||||||
/>
|
/>
|
||||||
<x-button
|
<x-livewire-material::button
|
||||||
icon="chevron_right"
|
icon="chevron_right"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
:tooltip="__('Next')"
|
:tooltip="__('Next')"
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
@if ($indeterminate) data-indeterminate @endif
|
@if ($indeterminate) data-indeterminate @endif
|
||||||
@if ($messages !== []) aria-invalid="true" aria-describedby="{{ $id }}-support" @endif
|
@if ($messages !== []) aria-invalid="true" aria-describedby="{{ $id }}-support" @endif
|
||||||
/>
|
/>
|
||||||
<x-icon name="check" class="size-4" data-check />
|
<x-livewire-material::icon name="check" class="size-4" data-check />
|
||||||
<x-icon name="remove" class="size-4" data-mixed />
|
<x-livewire-material::icon name="remove" class="size-4" data-mixed />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@if (filled($label) || filled($hint))
|
@if (filled($label) || filled($hint))
|
||||||
|
|||||||
@@ -230,7 +230,7 @@
|
|||||||
<img src="{{ $avatar }}" alt="" @class(['me-2 size-6 shrink-0 rounded-corner-full object-cover', 'opacity-38' => $disabled]) />
|
<img src="{{ $avatar }}" alt="" @class(['me-2 size-6 shrink-0 rounded-corner-full object-cover', 'opacity-38' => $disabled]) />
|
||||||
@endif
|
@endif
|
||||||
@elseif ($icon)
|
@elseif ($icon)
|
||||||
<x-icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['me-2 size-4.5', $leadingInk])" />
|
<x-livewire-material::icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['me-2 size-4.5', $leadingInk])" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span data-chip-label class="truncate">{{ $label ?? $slot }}</span>
|
<span data-chip-label class="truncate">{{ $label ?? $slot }}</span>
|
||||||
@@ -251,7 +251,7 @@
|
|||||||
'cursor-not-allowed' => $disabled,
|
'cursor-not-allowed' => $disabled,
|
||||||
])
|
])
|
||||||
>
|
>
|
||||||
<x-icon name="close" class="size-4.5" />
|
<x-livewire-material::icon name="close" class="size-4.5" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($tooltip !== null)
|
@if ($tooltip !== null)
|
||||||
<x-tooltip :text="$tooltip" :anchor="$anchor" />
|
<x-livewire-material::tooltip :text="$tooltip" :anchor="$anchor" />
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
@@ -277,22 +277,22 @@
|
|||||||
'h-4.5 w-0 transition-[width] duration-(--md-sys-motion-effects-default-duration) ease-effects-default group-has-checked/chip:w-4.5 group-has-checked/chip:duration-(--md-sys-motion-spatial-fast-duration) group-has-checked/chip:ease-spatial-fast group-aria-pressed/chip:w-4.5 group-aria-pressed/chip:duration-(--md-sys-motion-spatial-fast-duration) group-aria-pressed/chip:ease-spatial-fast' => blank($icon),
|
'h-4.5 w-0 transition-[width] duration-(--md-sys-motion-effects-default-duration) ease-effects-default group-has-checked/chip:w-4.5 group-has-checked/chip:duration-(--md-sys-motion-spatial-fast-duration) group-has-checked/chip:ease-spatial-fast group-aria-pressed/chip:w-4.5 group-aria-pressed/chip:duration-(--md-sys-motion-spatial-fast-duration) group-aria-pressed/chip:ease-spatial-fast' => blank($icon),
|
||||||
])>
|
])>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['size-4.5 transition-opacity duration-(--md-sys-motion-effects-fast-duration) ease-effects-fast group-has-checked/chip:opacity-0 group-aria-pressed/chip:opacity-0', $leadingInk])" />
|
<x-livewire-material::icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['size-4.5 transition-opacity duration-(--md-sys-motion-effects-fast-duration) ease-effects-fast group-has-checked/chip:opacity-0 group-aria-pressed/chip:opacity-0', $leadingInk])" />
|
||||||
@endif
|
@endif
|
||||||
<x-icon name="check" data-chip-check :class="$check" />
|
<x-livewire-material::icon name="check" data-chip-check :class="$check" />
|
||||||
</span>
|
</span>
|
||||||
@elseif ($icon)
|
@elseif ($icon)
|
||||||
<x-icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['me-2 size-4.5', $leadingInk])" />
|
<x-livewire-material::icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['me-2 size-4.5', $leadingInk])" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span class="truncate">{{ $label ?? $slot }}</span>
|
<span class="truncate">{{ $label ?? $slot }}</span>
|
||||||
|
|
||||||
@if ($iconRight)
|
@if ($iconRight)
|
||||||
<x-icon :name="$iconRight" :class="\Illuminate\Support\Arr::toCssClasses(['ms-2 size-4.5', $trailingInk])" />
|
<x-livewire-material::icon :name="$iconRight" :class="\Illuminate\Support\Arr::toCssClasses(['ms-2 size-4.5', $trailingInk])" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($tooltip !== null)
|
@if ($tooltip !== null)
|
||||||
<x-tooltip :text="$tooltip" :anchor="$anchor" />
|
<x-livewire-material::tooltip :text="$tooltip" :anchor="$anchor" />
|
||||||
@endif
|
@endif
|
||||||
</{{ $tag }}>
|
</{{ $tag }}>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
@if ($model === null) x-modelable="value" @endif
|
@if ($model === null) x-modelable="value" @endif
|
||||||
>
|
>
|
||||||
<div style="anchor-name: {{ $anchor }}">
|
<div style="anchor-name: {{ $anchor }}">
|
||||||
<x-field :$id :$label :$hint :$messages :$icon :$variant>
|
<x-livewire-material::field :$id :$label :$hint :$messages :$icon :$variant>
|
||||||
<input
|
<input
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -144,9 +144,9 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<x-slot:trailing>
|
<x-slot:trailing>
|
||||||
<x-icon name="arrow_drop_down" class="field-trailing field-arrow size-(--field-icon)" />
|
<x-livewire-material::icon name="arrow_drop_down" class="field-trailing field-arrow size-(--field-icon)" />
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
class="field-option"
|
class="field-option"
|
||||||
>
|
>
|
||||||
<span x-text="option.label"></span>
|
<span x-text="option.label"></span>
|
||||||
<x-icon name="check" class="field-check size-6" />
|
<x-livewire-material::icon name="check" class="field-check size-6" />
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<li x-show="filtered.length === 0" class="px-4 py-3 type-body-md text-on-surface-variant">{{ __('Nothing matches') }}</li>
|
<li x-show="filtered.length === 0" class="px-4 py-3 type-body-md text-on-surface-variant">{{ __('Nothing matches') }}</li>
|
||||||
@@ -202,9 +202,9 @@
|
|||||||
}"
|
}"
|
||||||
@if ($model === null) x-modelable="selection" @endif
|
@if ($model === null) x-modelable="selection" @endif
|
||||||
>
|
>
|
||||||
<x-chip-set :$label :$hint :error-field="$model">
|
<x-livewire-material::chip-set :$label :$hint :error-field="$model">
|
||||||
@foreach ($choices as $index => $choice)
|
@foreach ($choices as $index => $choice)
|
||||||
<x-chip
|
<x-livewire-material::chip
|
||||||
type="filter"
|
type="filter"
|
||||||
:label="$choice['label']"
|
:label="$choice['label']"
|
||||||
:selected="$isSelected($choice['value'])"
|
:selected="$isSelected($choice['value'])"
|
||||||
@@ -213,6 +213,6 @@
|
|||||||
x-on:click="toggle({{ $index }})"
|
x-on:click="toggle({{ $index }})"
|
||||||
/>
|
/>
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-chip-set>
|
</x-livewire-material::chip-set>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -28,12 +28,12 @@
|
|||||||
'px-4' => $variant === 'filled',
|
'px-4' => $variant === 'filled',
|
||||||
])>
|
])>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" class="size-6 text-on-surface-variant" />
|
<x-livewire-material::icon :name="$icon" class="size-6 text-on-surface-variant" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span class="min-w-0 flex-1">{{ $heading ?? $title }}</span>
|
<span class="min-w-0 flex-1">{{ $heading ?? $title }}</span>
|
||||||
|
|
||||||
<x-icon name="expand_more" class="size-6 text-on-surface-variant transition-[rotate] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast group-open/collapse:rotate-180" />
|
<x-livewire-material::icon name="expand_more" class="size-6 text-on-surface-variant transition-[rotate] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast group-open/collapse:rotate-180" />
|
||||||
</summary>
|
</summary>
|
||||||
|
|
||||||
<div @class(['pb-4 type-body-md text-on-surface-variant', 'px-4' => $variant === 'filled', 'pt-1'])>
|
<div @class(['pb-4 type-body-md text-on-surface-variant', 'px-4' => $variant === 'filled', 'pt-1'])>
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
data-datepicker
|
data-datepicker
|
||||||
>
|
>
|
||||||
<div style="anchor-name: {{ $anchor }}">
|
<div style="anchor-name: {{ $anchor }}">
|
||||||
<x-field
|
<x-livewire-material::field
|
||||||
:$id
|
:$id
|
||||||
:$label
|
:$label
|
||||||
:$icon
|
:$icon
|
||||||
@@ -191,10 +191,10 @@
|
|||||||
@disabled($attributes->get('disabled') || $attributes->get('readonly'))
|
@disabled($attributes->get('disabled') || $attributes->get('readonly'))
|
||||||
data-datepicker-toggle
|
data-datepicker-toggle
|
||||||
>
|
>
|
||||||
<x-icon name="calendar_today" class="size-(--field-icon)" />
|
<x-livewire-material::icon name="calendar_today" class="size-(--field-icon)" />
|
||||||
</button>
|
</button>
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="{{ $id }}-support" data-datepicker-support data-size="{{ in_array($size, ['sm', 'xs'], true) ? $size : 'md' }}">
|
<div id="{{ $id }}-support" data-datepicker-support data-size="{{ in_array($size, ['sm', 'xs'], true) ? $size : 'md' }}">
|
||||||
@@ -241,10 +241,10 @@
|
|||||||
<p data-datepicker-headline aria-live="polite" x-text="headline"></p>
|
<p data-datepicker-headline aria-live="polite" x-text="headline"></p>
|
||||||
|
|
||||||
<span x-show="! typing">
|
<span x-show="! typing">
|
||||||
<x-button icon="edit" :tooltip="__('Switch to text input mode')" x-on:click="toggleTyping()" data-datepicker-switch />
|
<x-livewire-material::button icon="edit" :tooltip="__('Switch to text input mode')" x-on:click="toggleTyping()" data-datepicker-switch />
|
||||||
</span>
|
</span>
|
||||||
<span x-show="typing">
|
<span x-show="typing">
|
||||||
<x-button icon="date_range" :tooltip="__('Switch to calendar input mode')" x-on:click="toggleTyping()" data-datepicker-switch />
|
<x-livewire-material::button icon="date_range" :tooltip="__('Switch to calendar input mode')" x-on:click="toggleTyping()" data-datepicker-switch />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -261,19 +261,19 @@
|
|||||||
x-bind:aria-label="monthYear + ', ' + @js(__('Switch to selecting a year'))"
|
x-bind:aria-label="monthYear + ', ' + @js(__('Switch to selecting a year'))"
|
||||||
>
|
>
|
||||||
<span x-text="monthYear"></span>
|
<span x-text="monthYear"></span>
|
||||||
<x-icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
<x-livewire-material::icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
||||||
<x-button icon="chevron_left" :tooltip="__('Previous month')" x-on:click="step(-1)" x-bind:disabled="view !== 'days' || ! canStep(-1)" data-datepicker-previous />
|
<x-livewire-material::button icon="chevron_left" :tooltip="__('Previous month')" x-on:click="step(-1)" x-bind:disabled="view !== 'days' || ! canStep(-1)" data-datepicker-previous />
|
||||||
<x-button icon="chevron_right" :tooltip="__('Next month')" x-on:click="step(1)" x-bind:disabled="view !== 'days' || ! canStep(1)" data-datepicker-next />
|
<x-livewire-material::button icon="chevron_right" :tooltip="__('Next month')" x-on:click="step(1)" x-bind:disabled="view !== 'days' || ! canStep(1)" data-datepicker-next />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-datepicker-nav data-docked x-show="presentation === 'docked'">
|
<div data-datepicker-nav data-docked x-show="presentation === 'docked'">
|
||||||
<span data-datepicker-stepper>
|
<span data-datepicker-stepper>
|
||||||
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
||||||
<x-button icon="chevron_left" :tooltip="__('Previous month')" x-on:click="step(-1)" x-bind:disabled="view !== 'days' || ! canStep(-1)" />
|
<x-livewire-material::button icon="chevron_left" :tooltip="__('Previous month')" x-on:click="step(-1)" x-bind:disabled="view !== 'days' || ! canStep(-1)" />
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -283,16 +283,16 @@
|
|||||||
x-bind:aria-label="monthLabel + ', ' + @js(__('Switch to selecting a month'))"
|
x-bind:aria-label="monthLabel + ', ' + @js(__('Switch to selecting a month'))"
|
||||||
>
|
>
|
||||||
<span x-text="monthLabel"></span>
|
<span x-text="monthLabel"></span>
|
||||||
<x-icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
<x-livewire-material::icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
||||||
</button>
|
</button>
|
||||||
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
||||||
<x-button icon="chevron_right" :tooltip="__('Next month')" x-on:click="step(1)" x-bind:disabled="view !== 'days' || ! canStep(1)" />
|
<x-livewire-material::button icon="chevron_right" :tooltip="__('Next month')" x-on:click="step(1)" x-bind:disabled="view !== 'days' || ! canStep(1)" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span data-datepicker-stepper>
|
<span data-datepicker-stepper>
|
||||||
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
||||||
<x-button icon="chevron_left" :tooltip="__('Previous year')" x-on:click="step(-12)" x-bind:disabled="view !== 'days' || ! canStep(-12)" />
|
<x-livewire-material::button icon="chevron_left" :tooltip="__('Previous year')" x-on:click="step(-12)" x-bind:disabled="view !== 'days' || ! canStep(-12)" />
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -302,10 +302,10 @@
|
|||||||
x-bind:aria-label="yearLabel + ', ' + @js(__('Switch to selecting a year'))"
|
x-bind:aria-label="yearLabel + ', ' + @js(__('Switch to selecting a year'))"
|
||||||
>
|
>
|
||||||
<span x-text="yearLabel"></span>
|
<span x-text="yearLabel"></span>
|
||||||
<x-icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
<x-livewire-material::icon name="arrow_drop_down" class="size-4.5" data-datepicker-menu-arrow />
|
||||||
</button>
|
</button>
|
||||||
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
<span data-datepicker-arrows x-bind:data-concealed="view !== 'days' ? '' : null">
|
||||||
<x-button icon="chevron_right" :tooltip="__('Next year')" x-on:click="step(12)" x-bind:disabled="view !== 'days' || ! canStep(12)" />
|
<x-livewire-material::button icon="chevron_right" :tooltip="__('Next year')" x-on:click="step(12)" x-bind:disabled="view !== 'days' || ! canStep(12)" />
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
x-on:click="month.disabled || showMonthOf(+shown.slice(0, 4), month.value)"
|
x-on:click="month.disabled || showMonthOf(+shown.slice(0, 4), month.value)"
|
||||||
data-datepicker-option
|
data-datepicker-option
|
||||||
>
|
>
|
||||||
<x-icon name="check" data-datepicker-check />
|
<x-livewire-material::icon name="check" data-datepicker-check />
|
||||||
<span x-text="month.label"></span>
|
<span x-text="month.label"></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
@@ -388,7 +388,7 @@
|
|||||||
x-on:click="showMonthOf(year.value, +shown.slice(5, 7))"
|
x-on:click="showMonthOf(year.value, +shown.slice(5, 7))"
|
||||||
data-datepicker-option
|
data-datepicker-option
|
||||||
>
|
>
|
||||||
<x-icon name="check" data-datepicker-check />
|
<x-livewire-material::icon name="check" data-datepicker-check />
|
||||||
<span x-text="year.label"></span>
|
<span x-text="year.label"></span>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
@@ -397,7 +397,7 @@
|
|||||||
|
|
||||||
<div x-show="typing" data-datepicker-entry>
|
<div x-show="typing" data-datepicker-entry>
|
||||||
<div @if ($range) data-range @endif data-datepicker-entry-fields>
|
<div @if ($range) data-range @endif data-datepicker-entry-fields>
|
||||||
<x-field id="{{ $id }}-entry" :label="$range ? __('Start date') : __('Date')" :$variant x-bind:data-invalid="entryError !== '' ? '' : null">
|
<x-livewire-material::field id="{{ $id }}-entry" :label="$range ? __('Start date') : __('Date')" :$variant x-bind:data-invalid="entryError !== '' ? '' : null">
|
||||||
<input
|
<input
|
||||||
id="{{ $id }}-entry"
|
id="{{ $id }}-entry"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -412,10 +412,10 @@
|
|||||||
x-on:keydown.enter.prevent="confirm()"
|
x-on:keydown.enter.prevent="confirm()"
|
||||||
class="field-control"
|
class="field-control"
|
||||||
/>
|
/>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|
||||||
@if ($range)
|
@if ($range)
|
||||||
<x-field id="{{ $id }}-entry-end" :label="__('End date')" :$variant x-bind:data-invalid="entryError !== '' ? '' : null">
|
<x-livewire-material::field id="{{ $id }}-entry-end" :label="__('End date')" :$variant x-bind:data-invalid="entryError !== '' ? '' : null">
|
||||||
<input
|
<input
|
||||||
id="{{ $id }}-entry-end"
|
id="{{ $id }}-entry-end"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -429,7 +429,7 @@
|
|||||||
x-on:keydown.enter.prevent="confirm()"
|
x-on:keydown.enter.prevent="confirm()"
|
||||||
class="field-control"
|
class="field-control"
|
||||||
/>
|
/>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -439,8 +439,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div x-show="view === 'days' || typing || presentation === 'modal'" data-datepicker-actions>
|
<div x-show="view === 'days' || typing || presentation === 'modal'" data-datepicker-actions>
|
||||||
<x-button :label="__('Cancel')" x-on:click="cancel()" data-datepicker-cancel />
|
<x-livewire-material::button :label="__('Cancel')" x-on:click="cancel()" data-datepicker-cancel />
|
||||||
<x-button :label="__('OK')" x-on:click="confirm()" data-datepicker-confirm />
|
<x-livewire-material::button :label="__('OK')" x-on:click="confirm()" data-datepicker-confirm />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|||||||
@@ -113,13 +113,13 @@
|
|||||||
|
|
||||||
@if ($withCloseButton)
|
@if ($withCloseButton)
|
||||||
<span class="-me-3 -mt-2 inline-flex shrink-0">
|
<span class="-me-3 -mt-2 inline-flex shrink-0">
|
||||||
<x-button icon="close" :tooltip-left="__('Close')" x-on:click="close()" />
|
<x-livewire-material::button icon="close" :tooltip-left="__('Close')" x-on:click="close()" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($separator)
|
@if ($separator)
|
||||||
<x-divider class="mt-4" />
|
<x-livewire-material::divider class="mt-4" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
<div {{ $attributes->class('flex flex-col items-center gap-4 px-4 py-10 text-center') }}>
|
<div {{ $attributes->class('flex flex-col items-center gap-4 px-4 py-10 text-center') }}>
|
||||||
<div class="relative grid size-28 place-items-center">
|
<div class="relative grid size-28 place-items-center">
|
||||||
<x-shape :name="$shape" class="absolute inset-0 size-full text-secondary-container" />
|
<x-livewire-material::shape :name="$shape" class="absolute inset-0 size-full text-secondary-container" />
|
||||||
<x-icon :name="$icon" class="relative size-12 text-on-secondary-container" />
|
<x-livewire-material::icon :name="$icon" class="relative size-12 text-on-secondary-container" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($title)
|
@if ($title)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
<{{ $tag }} {{ $attributes }}>
|
<{{ $tag }} {{ $attributes }}>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" class="size-6" />
|
<x-livewire-material::icon :name="$icon" class="size-6" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span>{{ $label ?? $slot }}</span>
|
<span>{{ $label ?? $slot }}</span>
|
||||||
|
|||||||
@@ -49,8 +49,8 @@
|
|||||||
$colours,
|
$colours,
|
||||||
])
|
])
|
||||||
>
|
>
|
||||||
<x-icon :name="$icon" class="size-6 group-aria-expanded/fab:hidden" />
|
<x-livewire-material::icon :name="$icon" class="size-6 group-aria-expanded/fab:hidden" />
|
||||||
<x-icon name="close" class="hidden size-5 group-aria-expanded/fab:block" />
|
<x-livewire-material::icon name="close" class="hidden size-5 group-aria-expanded/fab:block" />
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
<{{ $tag }} {{ $attributes }}>
|
<{{ $tag }} {{ $attributes }}>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" :class="$iconSize" />
|
<x-livewire-material::icon :name="$icon" :class="$iconSize" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($extended)
|
@if ($extended)
|
||||||
@@ -73,6 +73,6 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($tooltip !== null)
|
@if ($tooltip !== null)
|
||||||
<x-tooltip :text="$tooltip" :anchor="$anchor" />
|
<x-livewire-material::tooltip :text="$tooltip" :anchor="$anchor" />
|
||||||
@endif
|
@endif
|
||||||
</{{ $tag }}>
|
</{{ $tag }}>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
>
|
>
|
||||||
<div class="field-box">
|
<div class="field-box">
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" class="field-icon size-(--field-icon)" />
|
<x-livewire-material::icon :name="$icon" class="field-icon size-(--field-icon)" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (filled($prefix))
|
@if (filled($prefix))
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
: [];
|
: [];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-field :$id :$label :$hint :$messages :$variant floated :class="$attributes->get('class')">
|
<x-livewire-material::field :$id :$label :$hint :$messages :$variant floated :class="$attributes->get('class')">
|
||||||
<input
|
<input
|
||||||
{{ $attributes->except(['class', 'id', 'type']) }}
|
{{ $attributes->except(['class', 'id', 'type']) }}
|
||||||
type="file"
|
type="file"
|
||||||
@@ -35,4 +35,4 @@
|
|||||||
@if ($messages !== [] || filled($hint)) aria-describedby="{{ $id }}-support" @endif
|
@if ($messages !== [] || filled($hint)) aria-describedby="{{ $id }}-support" @endif
|
||||||
class="field-control"
|
class="field-control"
|
||||||
/>
|
/>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
@isset($actions)
|
@isset($actions)
|
||||||
@if ($separator)
|
@if ($separator)
|
||||||
<x-divider />
|
<x-livewire-material::divider />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div {{ $actions->attributes->class(['flex flex-wrap items-center justify-end gap-2']) }}>
|
<div {{ $actions->attributes->class(['flex flex-wrap items-center justify-end gap-2']) }}>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
@if (filled(data_get($option, $optionIcon)))
|
@if (filled(data_get($option, $optionIcon)))
|
||||||
<x-icon :name="data_get($option, $optionIcon)" :class="$iconSize" />
|
<x-livewire-material::icon :name="data_get($option, $optionIcon)" :class="$iconSize" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span class="truncate">{{ data_get($option, $optionLabel) }}</span>
|
<span class="truncate">{{ data_get($option, $optionLabel) }}</span>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$prefix :$suffix :$size :$variant :$mono :class="$attributes->get('class')" :data-readonly="$attributes->get('readonly') ? '' : null">
|
<x-livewire-material::field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$prefix :$suffix :$size :$variant :$mono :class="$attributes->get('class')" :data-readonly="$attributes->get('readonly') ? '' : null">
|
||||||
<input
|
<input
|
||||||
{{ $attributes->except(['class', 'id', 'placeholder'])->merge(['type' => 'text']) }}
|
{{ $attributes->except(['class', 'id', 'placeholder'])->merge(['type' => 'text']) }}
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
aria-label="{{ __('Clear') }}"
|
aria-label="{{ __('Clear') }}"
|
||||||
data-field-clear
|
data-field-clear
|
||||||
>
|
>
|
||||||
<x-icon name="close" class="size-(--field-icon)" />
|
<x-livewire-material::icon name="close" class="size-(--field-icon)" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -67,13 +67,13 @@
|
|||||||
aria-label="{{ __('Copy') }}"
|
aria-label="{{ __('Copy') }}"
|
||||||
data-field-copy
|
data-field-copy
|
||||||
>
|
>
|
||||||
<x-icon name="content_copy" class="size-(--field-icon)" />
|
<x-livewire-material::icon name="content_copy" class="size-(--field-icon)" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($iconRight)
|
@if ($iconRight)
|
||||||
<x-icon :name="$iconRight" class="field-trailing size-(--field-icon)" />
|
<x-livewire-material::icon :name="$iconRight" class="field-trailing size-(--field-icon)" />
|
||||||
@endif
|
@endif
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
@endif
|
@endif
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
@elseif ($image)
|
@elseif ($image)
|
||||||
<img src="{{ $image }}" alt="" class="size-14 shrink-0 rounded-corner-sm object-cover" />
|
<img src="{{ $image }}" alt="" class="size-14 shrink-0 rounded-corner-sm object-cover" />
|
||||||
@elseif ($icon)
|
@elseif ($icon)
|
||||||
<x-icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['size-6', 'text-on-surface-variant' => ! $selected && ! $disabled])" />
|
<x-livewire-material::icon :name="$icon" :class="\Illuminate\Support\Arr::toCssClasses(['size-6', 'text-on-surface-variant' => ! $selected && ! $disabled])" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
@@ -94,6 +94,6 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($iconRight)
|
@if ($iconRight)
|
||||||
<x-icon :name="$iconRight" :class="\Illuminate\Support\Arr::toCssClasses(['size-6', 'text-on-surface-variant' => ! $selected && ! $disabled])" />
|
<x-livewire-material::icon :name="$iconRight" :class="\Illuminate\Support\Arr::toCssClasses(['size-6', 'text-on-surface-variant' => ! $selected && ! $disabled])" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
<{{ $tag }} {{ $attributes }}>
|
<{{ $tag }} {{ $attributes }}>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" :filled="$selected === true" :class="'size-5 '.$iconInk" />
|
<x-livewire-material::icon :name="$icon" :filled="$selected === true" :class="'size-5 '.$iconInk" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<span class="min-w-0 flex-1">
|
<span class="min-w-0 flex-1">
|
||||||
@@ -76,6 +76,6 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($iconRight)
|
@if ($iconRight)
|
||||||
<x-icon :name="$iconRight" :class="'size-5 '.$iconInk" />
|
<x-livewire-material::icon :name="$iconRight" :class="'size-5 '.$iconInk" />
|
||||||
@endif
|
@endif
|
||||||
</{{ $tag }}>
|
</{{ $tag }}>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
])>
|
])>
|
||||||
@if ($fullscreen)
|
@if ($fullscreen)
|
||||||
<div class="flex h-16 shrink-0 items-center gap-1 px-1 sm:hidden">
|
<div class="flex h-16 shrink-0 items-center gap-1 px-1 sm:hidden">
|
||||||
<x-button icon="close" :tooltip="__('Close')" x-on:click="close()" />
|
<x-livewire-material::button icon="close" :tooltip="__('Close')" x-on:click="close()" />
|
||||||
|
|
||||||
@if (filled($title))
|
@if (filled($title))
|
||||||
<span class="truncate type-title-lg">{{ $title }}</span>
|
<span class="truncate type-title-lg">{{ $title }}</span>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
@if (filled($title) || $icon)
|
@if (filled($title) || $icon)
|
||||||
<div @class(['mb-4', 'max-sm:hidden' => $fullscreen && ! $icon, 'text-center' => $icon])>
|
<div @class(['mb-4', 'max-sm:hidden' => $fullscreen && ! $icon, 'text-center' => $icon])>
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" class="mx-auto mb-4 size-6 text-secondary" />
|
<x-livewire-material::icon :name="$icon" class="mx-auto mb-4 size-6 text-secondary" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (filled($title))
|
@if (filled($title))
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($separator)
|
@if ($separator)
|
||||||
<x-divider class="mt-4" />
|
<x-livewire-material::divider class="mt-4" />
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -49,13 +49,13 @@
|
|||||||
<span data-navigation-indicator>
|
<span data-navigation-indicator>
|
||||||
<span class="relative inline-flex">
|
<span class="relative inline-flex">
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" :filled="$active" class="size-6" />
|
<x-livewire-material::icon :name="$icon" :filled="$active" class="size-6" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($dot)
|
@if ($dot)
|
||||||
<x-badge floating />
|
<x-livewire-material::badge floating />
|
||||||
@elseif ($count)
|
@elseif ($count)
|
||||||
<x-badge :value="$badge" max="999" floating />
|
<x-livewire-material::badge :value="$badge" max="999" floating />
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -51,13 +51,13 @@
|
|||||||
<span data-navigation-indicator>
|
<span data-navigation-indicator>
|
||||||
<span class="relative inline-flex">
|
<span class="relative inline-flex">
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" :filled="$active" class="size-6" />
|
<x-livewire-material::icon :name="$icon" :filled="$active" class="size-6" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($dot)
|
@if ($dot)
|
||||||
<x-badge floating />
|
<x-livewire-material::badge floating />
|
||||||
@elseif ($count)
|
@elseif ($count)
|
||||||
<span class="hidden rail-collapsed:contents"><x-badge :value="$badge" max="999" floating /></span>
|
<span class="hidden rail-collapsed:contents"><x-livewire-material::badge :value="$badge" max="999" floating /></span>
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
<span data-navigation-label>{{ $label ?? $slot }}</span>
|
<span data-navigation-label>{{ $label ?? $slot }}</span>
|
||||||
|
|
||||||
@if ($count)
|
@if ($count)
|
||||||
<span class="flex shrink-0 rail-collapsed:hidden"><x-badge :value="$badge" max="999" /></span>
|
<span class="flex shrink-0 rail-collapsed:hidden"><x-livewire-material::badge :value="$badge" max="999" /></span>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($spoken !== null)
|
@if ($spoken !== null)
|
||||||
|
|||||||
@@ -107,8 +107,8 @@
|
|||||||
x-bind:aria-expanded="expanded.toString()"
|
x-bind:aria-expanded="expanded.toString()"
|
||||||
class="state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant after:absolute after:top-1/2 after:left-1/2 after:size-12 after:-translate-x-1/2 after:-translate-y-1/2"
|
class="state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant after:absolute after:top-1/2 after:left-1/2 after:size-12 after:-translate-x-1/2 after:-translate-y-1/2"
|
||||||
>
|
>
|
||||||
<span class="contents rail-collapsed:hidden"><x-icon name="menu_open" class="size-6" /></span>
|
<span class="contents rail-collapsed:hidden"><x-livewire-material::icon name="menu_open" class="size-6" /></span>
|
||||||
<span class="hidden rail-collapsed:contents"><x-icon name="menu" class="size-6" /></span>
|
<span class="hidden rail-collapsed:contents"><x-livewire-material::icon name="menu" class="size-6" /></span>
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$size :$variant :class="$attributes->get('class')" x-data="{ shown: false }">
|
<x-livewire-material::field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$size :$variant :class="$attributes->get('class')" x-data="{ shown: false }">
|
||||||
<input
|
<input
|
||||||
{{ $attributes->except(['class', 'id', 'type', 'placeholder']) }}
|
{{ $attributes->except(['class', 'id', 'type', 'placeholder']) }}
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
class="field-trailing field-button"
|
class="field-trailing field-button"
|
||||||
data-field-reveal
|
data-field-reveal
|
||||||
>
|
>
|
||||||
<x-icon name="visibility" class="size-(--field-icon)" x-show="! shown" />
|
<x-livewire-material::icon name="visibility" class="size-(--field-icon)" x-show="! shown" />
|
||||||
<x-icon name="visibility_off" class="size-(--field-icon)" x-show="shown" x-cloak />
|
<x-livewire-material::icon name="visibility_off" class="size-(--field-icon)" x-show="shown" x-cloak />
|
||||||
</button>
|
</button>
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|||||||
@@ -37,11 +37,11 @@
|
|||||||
>
|
>
|
||||||
<div data-search-bar role="search" x-on:click="if ($event.target === $el) $refs.input.focus()">
|
<div data-search-bar role="search" x-on:click="if ($event.target === $el) $refs.input.focus()">
|
||||||
<span data-search-leading x-show="! fullScreen">
|
<span data-search-leading x-show="! fullScreen">
|
||||||
<x-icon :name="$icon" />
|
<x-livewire-material::icon :name="$icon" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button type="button" data-search-leading data-search-back x-show="fullScreen" x-cloak x-on:click="close()" aria-label="{{ __('Back') }}">
|
<button type="button" data-search-leading data-search-back x-show="fullScreen" x-cloak x-on:click="close()" aria-label="{{ __('Back') }}">
|
||||||
<x-icon name="arrow_back" />
|
<x-livewire-material::icon name="arrow_back" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<button type="button" data-search-clear x-on:click="clear()" aria-label="{{ __('Clear') }}">
|
<button type="button" data-search-clear x-on:click="clear()" aria-label="{{ __('Clear') }}">
|
||||||
<x-icon name="close" />
|
<x-livewire-material::icon name="close" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@isset($trailing)
|
@isset($trailing)
|
||||||
|
|||||||
@@ -33,21 +33,21 @@
|
|||||||
<div {{ $attributes->class(['min-w-0']) }} data-section-nav>
|
<div {{ $attributes->class(['min-w-0']) }} data-section-nav>
|
||||||
@if ($current)
|
@if ($current)
|
||||||
<div class="sm:hidden" data-section-picker>
|
<div class="sm:hidden" data-section-picker>
|
||||||
<x-menu :$label position="bottom-start">
|
<x-livewire-material::menu :$label position="bottom-start">
|
||||||
<x-slot:trigger>
|
<x-slot:trigger>
|
||||||
<button type="button" class="focus-ring flex h-12 w-[min(20rem,calc(100vw-2rem))] cursor-pointer items-center gap-3 rounded-corner-xs border border-outline px-4 text-start type-body-lg text-on-surface">
|
<button type="button" class="focus-ring flex h-12 w-[min(20rem,calc(100vw-2rem))] cursor-pointer items-center gap-3 rounded-corner-xs border border-outline px-4 text-start type-body-lg text-on-surface">
|
||||||
@isset($current['icon'])
|
@isset($current['icon'])
|
||||||
<x-icon :name="$current['icon']" class="size-5 text-on-surface-variant" />
|
<x-livewire-material::icon :name="$current['icon']" class="size-5 text-on-surface-variant" />
|
||||||
@endisset
|
@endisset
|
||||||
<span class="min-w-0 flex-1 truncate">{{ $current['title'] }}</span>
|
<span class="min-w-0 flex-1 truncate">{{ $current['title'] }}</span>
|
||||||
<x-icon name="arrow_drop_down" class="size-6 text-on-surface-variant" />
|
<x-livewire-material::icon name="arrow_drop_down" class="size-6 text-on-surface-variant" />
|
||||||
</button>
|
</button>
|
||||||
</x-slot:trigger>
|
</x-slot:trigger>
|
||||||
|
|
||||||
@foreach ($items as $item)
|
@foreach ($items as $item)
|
||||||
<x-menu-item :label="$item['title']" :icon="$item['icon'] ?? null" :link="$item['url']" :selected="$isCurrent($item)" :no-wire-navigate="$noWireNavigate" />
|
<x-livewire-material::menu-item :label="$item['title']" :icon="$item['icon'] ?? null" :link="$item['url']" :selected="$isCurrent($item)" :no-wire-navigate="$noWireNavigate" />
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-menu>
|
</x-livewire-material::menu>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -65,11 +65,11 @@
|
|||||||
>
|
>
|
||||||
<span data-tab-content>
|
<span data-tab-content>
|
||||||
@isset($item['icon'])
|
@isset($item['icon'])
|
||||||
<x-icon :name="$item['icon']" :filled="$on" class="size-5" />
|
<x-livewire-material::icon :name="$item['icon']" :filled="$on" class="size-5" />
|
||||||
@endisset
|
@endisset
|
||||||
<span class="truncate">{{ $item['title'] }}</span>
|
<span class="truncate">{{ $item['title'] }}</span>
|
||||||
@if (filled($item['badge'] ?? null))
|
@if (filled($item['badge'] ?? null))
|
||||||
<x-badge :value="$item['badge']" />
|
<x-livewire-material::badge :value="$item['badge']" />
|
||||||
@endif
|
@endif
|
||||||
<span data-tab-indicator aria-hidden="true"></span>
|
<span data-tab-indicator aria-hidden="true"></span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$size :$variant floated :class="$attributes->get('class')">
|
<x-livewire-material::field :$id :$label :$hint :hint-class="$hintClass" :$messages :$icon :$size :$variant floated :class="$attributes->get('class')">
|
||||||
<select
|
<select
|
||||||
{{ $attributes->except(['class', 'id']) }}
|
{{ $attributes->except(['class', 'id']) }}
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
@@ -52,6 +52,6 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<x-slot:trailing>
|
<x-slot:trailing>
|
||||||
<x-icon name="arrow_drop_down" class="field-trailing field-arrow size-(--field-icon)" />
|
<x-livewire-material::icon name="arrow_drop_down" class="field-trailing field-arrow size-(--field-icon)" />
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|||||||
@@ -321,7 +321,7 @@
|
|||||||
@class(['absolute top-1/2 flex -translate-y-1/2 rtl:-scale-x-100', $iconInk[$color], 'group-has-disabled/slider:text-on-surface/38'])
|
@class(['absolute top-1/2 flex -translate-y-1/2 rtl:-scale-x-100', $iconInk[$color], 'group-has-disabled/slider:text-on-surface/38'])
|
||||||
style="left: {{ $calc($iconAt) }}"
|
style="left: {{ $calc($iconAt) }}"
|
||||||
>
|
>
|
||||||
<x-icon :name="$icon" :class="$iconSize === 32 ? 'size-8' : 'size-6'" />
|
<x-livewire-material::icon :name="$icon" :class="$iconSize === 32 ? 'size-8' : 'size-6'" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
])
|
])
|
||||||
>
|
>
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
<x-icon :name="$direction === 'desc' ? 'arrow_downward' : 'arrow_upward'" :class="\Illuminate\Support\Arr::toCssClasses([
|
<x-livewire-material::icon :name="$direction === 'desc' ? 'arrow_downward' : 'arrow_upward'" :class="\Illuminate\Support\Arr::toCssClasses([
|
||||||
'size-4 transition-opacity duration-(--md-sys-motion-effects-fast-duration)',
|
'size-4 transition-opacity duration-(--md-sys-motion-effects-fast-duration)',
|
||||||
'opacity-0 group-hover/sort:opacity-60 group-focus-visible/sort:opacity-60' => ! $active,
|
'opacity-0 group-hover/sort:opacity-60 group-focus-visible/sort:opacity-60' => ! $active,
|
||||||
])" />
|
])" />
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<div data-button-group="split" data-size="{{ $size }}" {{ $attributes->only('class')->class('inline-flex items-center gap-0.5') }}>
|
<div data-button-group="split" data-size="{{ $size }}" {{ $attributes->only('class')->class('inline-flex items-center gap-0.5') }}>
|
||||||
<x-button
|
<x-livewire-material::button
|
||||||
{{ $attributes->except('class') }}
|
{{ $attributes->except('class') }}
|
||||||
:label="$label"
|
:label="$label"
|
||||||
:icon="$icon"
|
:icon="$icon"
|
||||||
@@ -51,9 +51,9 @@
|
|||||||
:class="$leadingPadding"
|
:class="$leadingPadding"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<x-menu :position="$position" :label="$menuLabel">
|
<x-livewire-material::menu :position="$position" :label="$menuLabel">
|
||||||
<x-slot:trigger>
|
<x-slot:trigger>
|
||||||
<x-button
|
<x-livewire-material::button
|
||||||
icon="keyboard_arrow_down"
|
icon="keyboard_arrow_down"
|
||||||
:aria-label="$menuLabel"
|
:aria-label="$menuLabel"
|
||||||
:variant="$variant"
|
:variant="$variant"
|
||||||
@@ -67,5 +67,5 @@
|
|||||||
</x-slot:trigger>
|
</x-slot:trigger>
|
||||||
|
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</x-menu>
|
</x-livewire-material::menu>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div {{ $attributes->class('flex flex-col gap-1 rounded-corner-lg bg-surface-container p-4') }}>
|
<div {{ $attributes->class('flex flex-col gap-1 rounded-corner-lg bg-surface-container p-4') }}>
|
||||||
<div class="flex items-center gap-2 type-label-lg text-on-surface-variant">
|
<div class="flex items-center gap-2 type-label-lg text-on-surface-variant">
|
||||||
@if ($icon)
|
@if ($icon)
|
||||||
<x-icon :name="$icon" class="size-5" />
|
<x-livewire-material::icon :name="$icon" class="size-5" />
|
||||||
@endif
|
@endif
|
||||||
<span>{{ $title }}</span>
|
<span>{{ $title }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -72,12 +72,12 @@
|
|||||||
>
|
>
|
||||||
<span data-tab-content>
|
<span data-tab-content>
|
||||||
@isset($tab['icon'])
|
@isset($tab['icon'])
|
||||||
<x-icon :name="$tab['icon']" class="size-6" />
|
<x-livewire-material::icon :name="$tab['icon']" class="size-6" />
|
||||||
@endisset
|
@endisset
|
||||||
<span class="inline-flex items-center gap-1.5">
|
<span class="inline-flex items-center gap-1.5">
|
||||||
{{ $tab['label'] }}
|
{{ $tab['label'] }}
|
||||||
@if (filled($tab['badge'] ?? null))
|
@if (filled($tab['badge'] ?? null))
|
||||||
<x-badge :value="$tab['badge']" />
|
<x-livewire-material::badge :value="$tab['badge']" />
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
<span data-tab-indicator aria-hidden="true"></span>
|
<span data-tab-indicator aria-hidden="true"></span>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
$messages = $model !== null && isset($errors) ? \Illuminate\Support\Arr::flatten($errors->get($model)) : [];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<x-field :$id :$label :$hint :hint-class="$hintClass" :$messages :$variant :class="$attributes->get('class')" :data-readonly="$attributes->get('readonly') ? '' : null">
|
<x-livewire-material::field :$id :$label :$hint :hint-class="$hintClass" :$messages :$variant :class="$attributes->get('class')" :data-readonly="$attributes->get('readonly') ? '' : null">
|
||||||
<textarea
|
<textarea
|
||||||
{{ $attributes->except(['class', 'id', 'placeholder']) }}
|
{{ $attributes->except(['class', 'id', 'placeholder']) }}
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
@@ -36,4 +36,4 @@
|
|||||||
@if ($messages !== [] || filled($hint)) aria-describedby="{{ $id }}-support" @endif
|
@if ($messages !== [] || filled($hint)) aria-describedby="{{ $id }}-support" @endif
|
||||||
class="field-control"
|
class="field-control"
|
||||||
></textarea>
|
></textarea>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|||||||
@@ -40,8 +40,8 @@
|
|||||||
data-theme-option="{{ $choice }}"
|
data-theme-option="{{ $choice }}"
|
||||||
class="state-layer focus-ring inline-flex min-w-0 flex-1 cursor-pointer items-center justify-center gap-2 border-outline px-3 type-label-lg text-on-surface not-first:border-s first:rounded-s-corner-full last:rounded-e-corner-full aria-checked:bg-secondary-container aria-checked:text-on-secondary-container"
|
class="state-layer focus-ring inline-flex min-w-0 flex-1 cursor-pointer items-center justify-center gap-2 border-outline px-3 type-label-lg text-on-surface not-first:border-s first:rounded-s-corner-full last:rounded-e-corner-full aria-checked:bg-secondary-container aria-checked:text-on-secondary-container"
|
||||||
>
|
>
|
||||||
<x-icon name="check" class="hidden size-4.5 in-aria-checked:block" />
|
<x-livewire-material::icon name="check" class="hidden size-4.5 in-aria-checked:block" />
|
||||||
<x-icon :name="$icon" class="size-4.5 in-aria-checked:hidden" />
|
<x-livewire-material::icon :name="$icon" class="size-4.5 in-aria-checked:hidden" />
|
||||||
{{ __($text) }}
|
{{ __($text) }}
|
||||||
</button>
|
</button>
|
||||||
@endforeach
|
@endforeach
|
||||||
@@ -65,12 +65,12 @@
|
|||||||
{{ $attributes->class(['state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant transition-[border-radius] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast active:rounded-corner-sm']) }}
|
{{ $attributes->class(['state-layer focus-ring inline-flex size-10 shrink-0 cursor-pointer items-center justify-center rounded-corner-full text-on-surface-variant transition-[border-radius] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast active:rounded-corner-sm']) }}
|
||||||
>
|
>
|
||||||
@if ($mode === 'cycle')
|
@if ($mode === 'cycle')
|
||||||
<x-icon name="light_mode" x-cloak x-show="$store.theme.choice === 'light'" />
|
<x-livewire-material::icon name="light_mode" x-cloak x-show="$store.theme.choice === 'light'" />
|
||||||
<x-icon name="dark_mode" x-cloak x-show="$store.theme.choice === 'dark'" />
|
<x-livewire-material::icon name="dark_mode" x-cloak x-show="$store.theme.choice === 'dark'" />
|
||||||
<x-icon name="brightness_auto" x-cloak x-show="$store.theme.choice === 'system'" />
|
<x-livewire-material::icon name="brightness_auto" x-cloak x-show="$store.theme.choice === 'system'" />
|
||||||
@else
|
@else
|
||||||
<x-icon name="light_mode" x-cloak x-show="$store.theme.resolved === 'dark'" />
|
<x-livewire-material::icon name="light_mode" x-cloak x-show="$store.theme.resolved === 'dark'" />
|
||||||
<x-icon name="dark_mode" x-cloak x-show="$store.theme.resolved !== 'dark'" />
|
<x-livewire-material::icon name="dark_mode" x-cloak x-show="$store.theme.resolved !== 'dark'" />
|
||||||
@endif
|
@endif
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
x-data="materialTimepicker(@if ($model !== null) @entangle($attributes->wire('model')) @else @js($current) @endif, @js($config))"
|
x-data="materialTimepicker(@if ($model !== null) @entangle($attributes->wire('model')) @else @js($current) @endif, @js($config))"
|
||||||
@if ($model === null) x-modelable="value" @endif
|
@if ($model === null) x-modelable="value" @endif
|
||||||
>
|
>
|
||||||
<x-field :$id :$label :$hint :$messages :$icon :$size :$variant data-timepicker-field>
|
<x-livewire-material::field :$id :$label :$hint :$messages :$icon :$size :$variant data-timepicker-field>
|
||||||
<input
|
<input
|
||||||
{{ $inputAttributes }}
|
{{ $inputAttributes }}
|
||||||
id="{{ $id }}"
|
id="{{ $id }}"
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
data-field-clear
|
data-field-clear
|
||||||
@disabled($disabled)
|
@disabled($disabled)
|
||||||
>
|
>
|
||||||
<x-icon name="close" class="size-(--field-icon)" />
|
<x-livewire-material::icon name="close" class="size-(--field-icon)" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -185,10 +185,10 @@
|
|||||||
data-timepicker-open
|
data-timepicker-open
|
||||||
@disabled($disabled)
|
@disabled($disabled)
|
||||||
>
|
>
|
||||||
<x-icon name="schedule" class="size-(--field-icon)" />
|
<x-livewire-material::icon name="schedule" class="size-(--field-icon)" />
|
||||||
</button>
|
</button>
|
||||||
</x-slot:trailing>
|
</x-slot:trailing>
|
||||||
</x-field>
|
</x-livewire-material::field>
|
||||||
|
|
||||||
@if (filled($name))
|
@if (filled($name))
|
||||||
<input type="hidden" name="{{ $name }}" value="{{ $current }}" x-bind:value="value ?? ''" />
|
<input type="hidden" name="{{ $name }}" value="{{ $current }}" x-bind:value="value ?? ''" />
|
||||||
@@ -348,14 +348,14 @@
|
|||||||
|
|
||||||
<div data-timepicker-actions>
|
<div data-timepicker-actions>
|
||||||
<span data-timepicker-when="dial">
|
<span data-timepicker-when="dial">
|
||||||
<x-button icon="keyboard" :tooltip="__('Switch to text input mode')" x-on:click="toggleMode()" data-timepicker-mode="input" />
|
<x-livewire-material::button icon="keyboard" :tooltip="__('Switch to text input mode')" x-on:click="toggleMode()" data-timepicker-mode="input" />
|
||||||
</span>
|
</span>
|
||||||
<span data-timepicker-when="input">
|
<span data-timepicker-when="input">
|
||||||
<x-button icon="schedule" :tooltip="__('Switch to clock mode')" x-on:click="toggleMode()" data-timepicker-mode="dial" />
|
<x-livewire-material::button icon="schedule" :tooltip="__('Switch to clock mode')" x-on:click="toggleMode()" data-timepicker-mode="dial" />
|
||||||
</span>
|
</span>
|
||||||
<span data-timepicker-spacer></span>
|
<span data-timepicker-spacer></span>
|
||||||
<x-button :label="__('Cancel')" x-on:click="cancel()" data-timepicker-cancel />
|
<x-livewire-material::button :label="__('Cancel')" x-on:click="cancel()" data-timepicker-cancel />
|
||||||
<x-button :label="__('OK')" x-on:click="confirm()" data-timepicker-confirm />
|
<x-livewire-material::button :label="__('OK')" x-on:click="confirm()" data-timepicker-confirm />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|||||||
@@ -47,10 +47,10 @@
|
|||||||
'text-inverse-warning': current.type === 'warning',
|
'text-inverse-warning': current.type === 'warning',
|
||||||
'text-inverse-info': current.type === 'info',
|
'text-inverse-info': current.type === 'info',
|
||||||
}">
|
}">
|
||||||
<span x-show="current.type === 'success'"><x-icon name="check_circle" filled class="size-6" /></span>
|
<span x-show="current.type === 'success'"><x-livewire-material::icon name="check_circle" filled class="size-6" /></span>
|
||||||
<span x-show="current.type === 'error'"><x-icon name="error" filled class="size-6" /></span>
|
<span x-show="current.type === 'error'"><x-livewire-material::icon name="error" filled class="size-6" /></span>
|
||||||
<span x-show="current.type === 'warning'"><x-icon name="warning" filled class="size-6" /></span>
|
<span x-show="current.type === 'warning'"><x-livewire-material::icon name="warning" filled class="size-6" /></span>
|
||||||
<span x-show="current.type === 'info'"><x-icon name="info" filled class="size-6" /></span>
|
<span x-show="current.type === 'info'"><x-livewire-material::icon name="info" filled class="size-6" /></span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
<template x-if="current.action || ! current.timeout">
|
<template x-if="current.action || ! current.timeout">
|
||||||
<button type="button" class="state-layer focus-ring inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="dismiss()">
|
<button type="button" class="state-layer focus-ring inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="dismiss()">
|
||||||
<x-icon name="close" class="size-5" />
|
<x-livewire-material::icon name="close" class="size-5" />
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
/>
|
/>
|
||||||
<span data-handle>
|
<span data-handle>
|
||||||
@if ($icons)
|
@if ($icons)
|
||||||
<x-icon name="check" class="size-4" data-on />
|
<x-livewire-material::icon name="check" class="size-4" data-on />
|
||||||
<x-icon name="close" class="size-4" data-off />
|
<x-livewire-material::icon name="close" class="size-4" data-off />
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -11,6 +11,6 @@
|
|||||||
@section('message', __('It was open for a while. Refresh it, then try again.'))
|
@section('message', __('It was open for a while. Refresh it, then try again.'))
|
||||||
|
|
||||||
@section('actions')
|
@section('actions')
|
||||||
<x-button :link="url()->previous()" :label="__('Refresh the page')" variant="filled" size="md" no-wire-navigate />
|
<x-livewire-material::button :link="url()->previous()" :label="__('Refresh the page')" variant="filled" size="md" no-wire-navigate />
|
||||||
<x-button :link="url('/')" :label="__('Go home')" variant="text" size="md" no-wire-navigate />
|
<x-livewire-material::button :link="url('/')" :label="__('Go home')" variant="text" size="md" no-wire-navigate />
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -18,5 +18,5 @@
|
|||||||
@section('message', $reason !== '' && $reason !== 'Service Unavailable' ? __($reason) : __('We’re making some improvements. Please check back soon.'))
|
@section('message', $reason !== '' && $reason !== 'Service Unavailable' ? __($reason) : __('We’re making some improvements. Please check back soon.'))
|
||||||
|
|
||||||
@section('actions')
|
@section('actions')
|
||||||
<x-button :label="__('Try again')" variant="filled" size="md" onclick="location.reload()" />
|
<x-livewire-material::button :label="__('Try again')" variant="filled" size="md" onclick="location.reload()" />
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<title>@yield('title') · {{ config('app.name') }}</title>
|
<title>@yield('title') · {{ config('app.name') }}</title>
|
||||||
|
|
||||||
<x-theme-script />
|
<x-livewire-material::theme-script />
|
||||||
|
|
||||||
@if ($assets !== null)
|
@if ($assets !== null)
|
||||||
{{ $assets }}
|
{{ $assets }}
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
<main data-error-page class="mx-auto flex min-h-dvh max-w-xl flex-col items-center justify-center px-6 py-12 text-center">
|
<main data-error-page class="mx-auto flex min-h-dvh max-w-xl flex-col items-center justify-center px-6 py-12 text-center">
|
||||||
<div data-error-art class="relative grid size-48 shrink-0 place-items-center sm:size-60">
|
<div data-error-art class="relative grid size-48 shrink-0 place-items-center sm:size-60">
|
||||||
<div data-error-shape class="absolute inset-0">
|
<div data-error-shape class="absolute inset-0">
|
||||||
<x-shape :name="trim($__env->yieldContent('shape', 'cookie-7'))" class="size-full text-primary-container" />
|
<x-livewire-material::shape :name="trim($__env->yieldContent('shape', 'cookie-7'))" class="size-full text-primary-container" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p data-error-code class="relative type-emphasized-display-lg text-on-primary-container tabular-nums">@yield('code')</p>
|
<p data-error-code class="relative type-emphasized-display-lg text-on-primary-container tabular-nums">@yield('code')</p>
|
||||||
@@ -71,10 +71,10 @@
|
|||||||
@hasSection('actions')
|
@hasSection('actions')
|
||||||
@yield('actions')
|
@yield('actions')
|
||||||
@else
|
@else
|
||||||
<x-button :link="url('/')" :label="__('Go home')" variant="filled" size="md" no-wire-navigate />
|
<x-livewire-material::button :link="url('/')" :label="__('Go home')" variant="filled" size="md" no-wire-navigate />
|
||||||
|
|
||||||
@if ($back !== null)
|
@if ($back !== null)
|
||||||
<x-button :link="$back" :label="__('Go back')" variant="text" size="md" no-wire-navigate />
|
<x-livewire-material::button :link="$back" :label="__('Go back')" variant="text" size="md" no-wire-navigate />
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,15 +4,15 @@
|
|||||||
@if ($paginator->hasPages())
|
@if ($paginator->hasPages())
|
||||||
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" data-pagination class="flex items-center justify-between gap-4">
|
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" data-pagination class="flex items-center justify-between gap-4">
|
||||||
@if ($paginator->onFirstPage())
|
@if ($paginator->onFirstPage())
|
||||||
<x-button variant="outlined" icon="chevron_left" :label="__('Previous')" disabled />
|
<x-livewire-material::button variant="outlined" icon="chevron_left" :label="__('Previous')" disabled />
|
||||||
@else
|
@else
|
||||||
<x-button variant="outlined" icon="chevron_left" :label="__('Previous')" :link="$paginator->previousPageUrl()" no-wire-navigate rel="prev" />
|
<x-livewire-material::button variant="outlined" icon="chevron_left" :label="__('Previous')" :link="$paginator->previousPageUrl()" no-wire-navigate rel="prev" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($paginator->hasMorePages())
|
@if ($paginator->hasMorePages())
|
||||||
<x-button variant="outlined" icon-right="chevron_right" :label="__('Next')" :link="$paginator->nextPageUrl()" no-wire-navigate rel="next" />
|
<x-livewire-material::button variant="outlined" icon-right="chevron_right" :label="__('Next')" :link="$paginator->nextPageUrl()" no-wire-navigate rel="next" />
|
||||||
@else
|
@else
|
||||||
<x-button variant="outlined" icon-right="chevron_right" :label="__('Next')" disabled />
|
<x-livewire-material::button variant="outlined" icon-right="chevron_right" :label="__('Next')" disabled />
|
||||||
@endif
|
@endif
|
||||||
</nav>
|
</nav>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -19,11 +19,11 @@
|
|||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
@if ($paginator->onFirstPage())
|
@if ($paginator->onFirstPage())
|
||||||
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Previous') }}">
|
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Previous') }}">
|
||||||
<x-icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="{{ $live }}" aria-label="{{ __('Previous') }}">
|
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="{{ $live }}" aria-label="{{ __('Previous') }}">
|
||||||
<x-icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
|
|
||||||
@if ($paginator->hasMorePages())
|
@if ($paginator->hasMorePages())
|
||||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="{{ $live }}" aria-label="{{ __('Next') }}">
|
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="{{ $live }}" aria-label="{{ __('Next') }}">
|
||||||
<x-icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
||||||
</a>
|
</a>
|
||||||
@else
|
@else
|
||||||
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Next') }}">
|
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Next') }}">
|
||||||
<x-icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,21 +19,21 @@
|
|||||||
@if ($paginator->hasPages())
|
@if ($paginator->hasPages())
|
||||||
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" data-pagination class="flex items-center justify-between gap-4">
|
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" data-pagination class="flex items-center justify-between gap-4">
|
||||||
@if ($paginator->onFirstPage())
|
@if ($paginator->onFirstPage())
|
||||||
<x-button variant="outlined" icon="chevron_left" :label="__('Previous')" disabled />
|
<x-livewire-material::button variant="outlined" icon="chevron_left" :label="__('Previous')" disabled />
|
||||||
@elseif ($cursor)
|
@elseif ($cursor)
|
||||||
@php($previousCursor = $paginator->previousCursor() ?? $paginator->cursor())
|
@php($previousCursor = $paginator->previousCursor() ?? $paginator->cursor())
|
||||||
<x-button variant="outlined" icon="chevron_left" :label="__('Previous')" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $previousCursor?->encode() }}" wire:click="setPage('{{ $previousCursor?->encode() }}', '{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage" />
|
<x-livewire-material::button variant="outlined" icon="chevron_left" :label="__('Previous')" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $previousCursor?->encode() }}" wire:click="setPage('{{ $previousCursor?->encode() }}', '{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage" />
|
||||||
@else
|
@else
|
||||||
<x-button variant="outlined" icon="chevron_left" :label="__('Previous')" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage" />
|
<x-livewire-material::button variant="outlined" icon="chevron_left" :label="__('Previous')" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if (! $paginator->hasMorePages())
|
@if (! $paginator->hasMorePages())
|
||||||
<x-button variant="outlined" icon-right="chevron_right" :label="__('Next')" disabled />
|
<x-livewire-material::button variant="outlined" icon-right="chevron_right" :label="__('Next')" disabled />
|
||||||
@elseif ($cursor)
|
@elseif ($cursor)
|
||||||
@php($nextCursor = $paginator->nextCursor() ?? $paginator->cursor())
|
@php($nextCursor = $paginator->nextCursor() ?? $paginator->cursor())
|
||||||
<x-button variant="outlined" icon-right="chevron_right" :label="__('Next')" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $nextCursor?->encode() }}" wire:click="setPage('{{ $nextCursor?->encode() }}', '{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage" />
|
<x-livewire-material::button variant="outlined" icon-right="chevron_right" :label="__('Next')" wire:key="cursor-{{ $paginator->getCursorName() }}-{{ $nextCursor?->encode() }}" wire:click="setPage('{{ $nextCursor?->encode() }}', '{{ $paginator->getCursorName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage" />
|
||||||
@else
|
@else
|
||||||
<x-button variant="outlined" icon-right="chevron_right" :label="__('Next')" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage" />
|
<x-livewire-material::button variant="outlined" icon-right="chevron_right" :label="__('Next')" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage" />
|
||||||
@endif
|
@endif
|
||||||
</nav>
|
</nav>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
@@ -35,11 +35,11 @@
|
|||||||
<div class="flex items-center gap-1">
|
<div class="flex items-center gap-1">
|
||||||
@if ($paginator->onFirstPage())
|
@if ($paginator->onFirstPage())
|
||||||
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Previous') }}">
|
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Previous') }}">
|
||||||
<x-icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
<button type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.'.$paginator->getPageName() }}" class="{{ $live }}" aria-label="{{ __('Previous') }}">
|
<button type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.'.$paginator->getPageName() }}" class="{{ $live }}" aria-label="{{ __('Previous') }}">
|
||||||
<x-icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_left" class="size-6 rtl:-scale-x-100" />
|
||||||
</button>
|
</button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -63,11 +63,11 @@
|
|||||||
|
|
||||||
@if ($paginator->hasMorePages())
|
@if ($paginator->hasMorePages())
|
||||||
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.'.$paginator->getPageName() }}" class="{{ $live }}" aria-label="{{ __('Next') }}">
|
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" wire:loading.attr="disabled" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.'.$paginator->getPageName() }}" class="{{ $live }}" aria-label="{{ __('Next') }}">
|
||||||
<x-icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
||||||
</button>
|
</button>
|
||||||
@else
|
@else
|
||||||
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Next') }}">
|
<span class="{{ $dead }}" aria-disabled="true" aria-label="{{ __('Next') }}">
|
||||||
<x-icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
<x-livewire-material::icon name="chevron_right" class="size-6 rtl:-scale-x-100" />
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,6 +3,21 @@
|
|||||||
|
|
||||||
@props(['title' => null, 'code', 'stack' => false])
|
@props(['title' => null, 'code', 'stack' => false])
|
||||||
|
|
||||||
|
@php
|
||||||
|
// Written as an application without a prefix writes it; under a configured prefix the tags are
|
||||||
|
// rewritten to it, so what renders and what is shown is what this application would write.
|
||||||
|
$prefix = config('livewire-material.prefix');
|
||||||
|
|
||||||
|
if (filled($prefix)) {
|
||||||
|
$names = collect(glob(\NoNameWeb\LivewireMaterial\LivewireMaterialServiceProvider::componentPath().'/*.blade.php'))
|
||||||
|
->map(fn (string $path): string => preg_quote(basename($path, '.blade.php'), '/'))
|
||||||
|
->sortByDesc(fn (string $name): int => strlen($name))
|
||||||
|
->implode('|');
|
||||||
|
|
||||||
|
$code = preg_replace('/<(\/?)x-('.$names.')(?=[\s\/>])/', '<$1x-'.$prefix.'::$2', $code);
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
<div class="space-y-4 rounded-corner-lg bg-surface-container p-4">
|
<div class="space-y-4 rounded-corner-lg bg-surface-container p-4">
|
||||||
@if ($title)
|
@if ($title)
|
||||||
<h3 class="type-title-md">{{ $title }}</h3>
|
<h3 class="type-title-md">{{ $title }}</h3>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<title>@yield('title', 'Livewire Material')</title>
|
<title>@yield('title', 'Livewire Material')</title>
|
||||||
|
|
||||||
<x-theme-script />
|
<x-livewire-material::theme-script />
|
||||||
|
|
||||||
@vite(config('livewire-material.showcase.vite'))
|
@vite(config('livewire-material.showcase.vite'))
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
@yield('content')
|
@yield('content')
|
||||||
|
|
||||||
<x-toast />
|
<x-livewire-material::toast />
|
||||||
|
|
||||||
@livewireScripts
|
@livewireScripts
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@
|
|||||||
<x-button icon="format_underlined" aria-label="Underline" variant="tonal" :selected="false" />
|
<x-button icon="format_underlined" aria-label="Underline" variant="tonal" :selected="false" />
|
||||||
</x-button-group>
|
</x-button-group>
|
||||||
BLADE,
|
BLADE,
|
||||||
'A choice as a connected group (<x-group>)' => <<<'BLADE'
|
'A choice as a connected group' => <<<'BLADE'
|
||||||
<div x-data="{ theme: 'system', days: ['mon'] }" class="grid w-full gap-6 md:grid-cols-2">
|
<div x-data="{ theme: 'system', days: ['mon'] }" class="grid w-full gap-6 md:grid-cols-2">
|
||||||
<x-group label="Theme" name="showcase-theme" x-model="theme" :options="[
|
<x-group label="Theme" name="showcase-theme" x-model="theme" :options="[
|
||||||
['id' => 'light', 'name' => 'Light', 'icon' => 'light_mode'],
|
['id' => 'light', 'name' => 'Light', 'icon' => 'light_mode'],
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<div class="flex flex-wrap items-center gap-4">
|
<div class="flex flex-wrap items-center gap-4">
|
||||||
<label class="flex min-w-72 flex-1 items-center gap-2 rounded-corner-xs border border-outline px-3 py-2 focus-within:outline-3 focus-within:outline-secondary">
|
<label class="flex min-w-72 flex-1 items-center gap-2 rounded-corner-xs border border-outline px-3 py-2 focus-within:outline-3 focus-within:outline-secondary">
|
||||||
<x-icon name="search" class="size-5 text-on-surface-variant" />
|
<x-livewire-material::icon name="search" class="size-5 text-on-surface-variant" />
|
||||||
<input type="search" x-model.debounce.150ms="query" placeholder="Search {{ number_format(count(\NoNameWeb\LivewireMaterial\Support\SvgFile::symbolNames())) }} symbols" class="w-full bg-transparent type-body-lg outline-none" />
|
<input type="search" x-model.debounce.150ms="query" placeholder="Search {{ number_format(count(\NoNameWeb\LivewireMaterial\Support\SvgFile::symbolNames())) }} symbols" class="w-full bg-transparent type-body-lg outline-none" />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
@foreach (['401', '402', '403', '404', '419', '429', '500', '503'] as $code)
|
@foreach (['401', '402', '403', '404', '419', '429', '500', '503'] as $code)
|
||||||
<x-button :link="route('livewire-material.error', $code)" :label="$code" variant="tonal" no-wire-navigate />
|
<x-livewire-material::button :link="route('livewire-material.error', $code)" :label="$code" variant="tonal" no-wire-navigate />
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
<x-button :link="route('livewire-material.mail')" label="Sample mail" icon="mail" variant="outlined" no-wire-navigate />
|
<x-livewire-material::button :link="route('livewire-material.mail')" label="Sample mail" icon="mail" variant="outlined" no-wire-navigate />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<div class="grid grid-cols-3 gap-4 sm:grid-cols-5 lg:grid-cols-7">
|
<div class="grid grid-cols-3 gap-4 sm:grid-cols-5 lg:grid-cols-7">
|
||||||
@foreach (\NoNameWeb\LivewireMaterial\Support\SvgFile::shapeNames() as $shape)
|
@foreach (\NoNameWeb\LivewireMaterial\Support\SvgFile::shapeNames() as $shape)
|
||||||
<div class="space-y-2 text-center">
|
<div class="space-y-2 text-center">
|
||||||
<x-shape :name="$shape" class="mx-auto size-20 text-secondary-container" />
|
<x-livewire-material::shape :name="$shape" class="mx-auto size-20 text-secondary-container" />
|
||||||
<code class="type-label-md text-on-surface-variant">{{ $shape }}</code>
|
<code class="type-label-md text-on-surface-variant">{{ $shape }}</code>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
@@ -33,54 +33,54 @@
|
|||||||
|
|
||||||
<title>{{ $current['title'] }} · App shell · Livewire Material</title>
|
<title>{{ $current['title'] }} · App shell · Livewire Material</title>
|
||||||
|
|
||||||
<x-theme-script />
|
<x-livewire-material::theme-script />
|
||||||
|
|
||||||
@vite(config('livewire-material.showcase.vite'))
|
@vite(config('livewire-material.showcase.vite'))
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-surface font-sans text-on-surface antialiased">
|
<body class="bg-surface font-sans text-on-surface antialiased">
|
||||||
<x-app-shell :destinations="$destinations">
|
<x-livewire-material::app-shell :destinations="$destinations">
|
||||||
<x-slot:brand>
|
<x-slot:brand>
|
||||||
<a href="{{ route('livewire-material.showcase') }}" class="block truncate rounded-corner-xs type-title-lg focus-ring">Livewire Material</a>
|
<a href="{{ route('livewire-material.showcase') }}" class="block truncate rounded-corner-xs type-title-lg focus-ring">Livewire Material</a>
|
||||||
</x-slot:brand>
|
</x-slot:brand>
|
||||||
|
|
||||||
<x-slot:rail-header>
|
<x-slot:rail-header>
|
||||||
<span class="rail-collapsed:hidden"><x-fab label="Compose" icon="edit" x-on:click="materialToast('Compose opens here')" /></span>
|
<span class="rail-collapsed:hidden"><x-livewire-material::fab label="Compose" icon="edit" x-on:click="materialToast('Compose opens here')" /></span>
|
||||||
<span class="hidden rail-collapsed:inline-flex"><x-fab icon="edit" tooltip-right="Compose" x-on:click="materialToast('Compose opens here')" /></span>
|
<span class="hidden rail-collapsed:inline-flex"><x-livewire-material::fab icon="edit" tooltip-right="Compose" x-on:click="materialToast('Compose opens here')" /></span>
|
||||||
</x-slot:rail-header>
|
</x-slot:rail-header>
|
||||||
|
|
||||||
<x-slot:rail-footer>
|
<x-slot:rail-footer>
|
||||||
<x-navigation-rail-item label="Settings" icon="settings" link="#settings" no-wire-navigate />
|
<x-livewire-material::navigation-rail-item label="Settings" icon="settings" link="#settings" no-wire-navigate />
|
||||||
</x-slot:rail-footer>
|
</x-slot:rail-footer>
|
||||||
|
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-button icon="dark_mode" tooltip-right="Switch theme" x-data x-on:click="$store.theme.toggle()" />
|
<x-livewire-material::button icon="dark_mode" tooltip-right="Switch theme" x-data x-on:click="$store.theme.toggle()" />
|
||||||
<x-button icon="help" tooltip-right="Help" x-on:click="materialToast('Help opens here')" />
|
<x-livewire-material::button icon="help" tooltip-right="Help" x-on:click="materialToast('Help opens here')" />
|
||||||
</x-slot:actions>
|
</x-slot:actions>
|
||||||
|
|
||||||
<x-slot:top>
|
<x-slot:top>
|
||||||
<header class="sticky top-0 z-20 flex h-16 items-center gap-1 bg-surface px-1 pt-[env(safe-area-inset-top)] sm:px-4">
|
<header class="sticky top-0 z-20 flex h-16 items-center gap-1 bg-surface px-1 pt-[env(safe-area-inset-top)] sm:px-4">
|
||||||
<span class="sm:hidden"><x-button icon="menu" tooltip="Open navigation" x-data x-on:click="$store.rail.show()" data-test="shell-menu" /></span>
|
<span class="sm:hidden"><x-livewire-material::button icon="menu" tooltip="Open navigation" x-data x-on:click="$store.rail.show()" data-test="shell-menu" /></span>
|
||||||
<h1 class="min-w-0 flex-1 truncate px-3 type-title-lg sm:px-0">{{ $current['title'] }}</h1>
|
<h1 class="min-w-0 flex-1 truncate px-3 type-title-lg sm:px-0">{{ $current['title'] }}</h1>
|
||||||
<x-button icon="search" tooltip="Search" />
|
<x-livewire-material::button icon="search" tooltip="Search" />
|
||||||
</header>
|
</header>
|
||||||
</x-slot:top>
|
</x-slot:top>
|
||||||
|
|
||||||
<div class="mx-auto w-full max-w-5xl space-y-4 px-4 pb-6 sm:px-6">
|
<div class="mx-auto w-full max-w-5xl space-y-4 px-4 pb-6 sm:px-6">
|
||||||
<p class="type-body-md text-on-surface-variant" data-test="shell-page">This is the {{ strtolower($current['title']) }} page.</p>
|
<p class="type-body-md text-on-surface-variant" data-test="shell-page">This is the {{ strtolower($current['title']) }} page.</p>
|
||||||
|
|
||||||
<x-list segmented>
|
<x-livewire-material::list segmented>
|
||||||
@foreach (range(1, 14) as $index)
|
@foreach (range(1, 14) as $index)
|
||||||
<x-list-item :title="$current['title'].' item '.$index" description="A line of supporting text for this item" :icon="$current['icon']" trailing="{{ $index }}h" wire:key="item-{{ $index }}" />
|
<x-livewire-material::list-item :title="$current['title'].' item '.$index" description="A line of supporting text for this item" :icon="$current['icon']" trailing="{{ $index }}h" wire:key="item-{{ $index }}" />
|
||||||
@endforeach
|
@endforeach
|
||||||
</x-list>
|
</x-livewire-material::list>
|
||||||
|
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
<x-button label="Show a toast" variant="tonal" x-data x-on:click="materialToast('Moved to archive', { action: { label: 'Undo', handler: () => {} } })" />
|
<x-livewire-material::button label="Show a toast" variant="tonal" x-data x-on:click="materialToast('Moved to archive', { action: { label: 'Undo', handler: () => {} } })" />
|
||||||
<x-button label="Back to the showcase" link="{{ route('livewire-material.showcase') }}#navigation" no-wire-navigate />
|
<x-livewire-material::button label="Back to the showcase" link="{{ route('livewire-material.showcase') }}#navigation" no-wire-navigate />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-app-shell>
|
</x-livewire-material::app-shell>
|
||||||
|
|
||||||
@livewireScripts
|
@livewireScripts
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -47,6 +47,15 @@ class LivewireMaterialServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The anonymous components. Blade names their view namespace after a hash of this string, and
|
||||||
|
* compiled views keep that name, so it stays written the way it always was.
|
||||||
|
*/
|
||||||
|
public static function componentPath(): string
|
||||||
|
{
|
||||||
|
return __DIR__.'/../resources/views/components';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The error-view root: a folder holding only `errors/`.
|
* The error-view root: a folder holding only `errors/`.
|
||||||
*/
|
*/
|
||||||
@@ -105,11 +114,15 @@ class LivewireMaterialServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the components as anonymous Blade components under the configured prefix.
|
* Register the components as anonymous Blade components under the configured prefix.
|
||||||
|
*
|
||||||
|
* The package's own views never go through this registration: they write
|
||||||
|
* `<x-livewire-material::button>`, which resolves through the view namespace whatever the
|
||||||
|
* prefix, and which an application's own `<x-button>` cannot shadow.
|
||||||
*/
|
*/
|
||||||
protected function registerComponents(): void
|
protected function registerComponents(): void
|
||||||
{
|
{
|
||||||
Blade::anonymousComponentPath(
|
Blade::anonymousComponentPath(
|
||||||
__DIR__.'/../resources/views/components',
|
static::componentPath(),
|
||||||
filled(config('livewire-material.prefix')) ? config('livewire-material.prefix') : null,
|
filled(config('livewire-material.prefix')) ? config('livewire-material.prefix') : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ function navigationReady(mixed $page): mixed
|
|||||||
|
|
||||||
function shellPage(int $width = 1280, int $height = 900, string $path = '/material/shell'): mixed
|
function shellPage(int $width = 1280, int $height = 900, string $path = '/material/shell'): mixed
|
||||||
{
|
{
|
||||||
return navigationReady(visit($path)->resize($width, $height));
|
// The window is resized after the page starts loading, and an adaptive rail hears of the new
|
||||||
|
// width from a media query's change event, which can arrive after the first key press.
|
||||||
|
return navigationReady(visit($path)->resize($width, $height))
|
||||||
|
->assertScript("window.eval(\"(() => { const rail = document.querySelector('[data-navigation-rail]'); return ! rail || rail.dataset.navigationRail !== 'adaptive' || Alpine.\$data(rail).wide === window.matchMedia('(min-width: 64rem)').matches; })()\")");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Blade;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
|
use NoNameWeb\LivewireMaterial\LivewireMaterialServiceProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The package's own component names, longest first.
|
||||||
|
*
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
function packageComponentNames(): array
|
||||||
|
{
|
||||||
|
return collect(File::files(LivewireMaterialServiceProvider::componentPath()))
|
||||||
|
->map(fn (SplFileInfo $file): string => $file->getBasename('.blade.php'))
|
||||||
|
->sortByDesc(fn (string $name): int => strlen($name))
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
it('refers to its own components through its namespace, which no prefix or app component changes', function () {
|
||||||
|
$names = implode('|', array_map(fn (string $name): string => preg_quote($name, '/'), packageComponentNames()));
|
||||||
|
|
||||||
|
$unqualified = collect(File::allFiles(__DIR__.'/../../resources/views'))
|
||||||
|
->filter(fn (SplFileInfo $file): bool => str_ends_with($file->getFilename(), '.blade.php'))
|
||||||
|
->flatMap(function (SplFileInfo $file) use ($names): array {
|
||||||
|
// Comments document usage as an application writes it, and the showcase's examples
|
||||||
|
// are that usage; neither is compiled as the package's own markup.
|
||||||
|
$source = preg_replace(['/\{\{--.*?--\}\}/s', "/<<<'BLADE'.*?^\\s*BLADE,/sm"], '', $file->getContents());
|
||||||
|
|
||||||
|
preg_match_all('/<\/?x-('.$names.')(?=[\s\/>])/', $source, $matches);
|
||||||
|
|
||||||
|
return array_map(fn (string $tag): string => $file->getRelativePathname().': '.$tag, $matches[0]);
|
||||||
|
})
|
||||||
|
->values();
|
||||||
|
|
||||||
|
expect($unqualified->all())->toBe([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders components that use others under a prefix', function () {
|
||||||
|
config(['livewire-material.prefix' => 'm']);
|
||||||
|
|
||||||
|
Blade::anonymousComponentPath(LivewireMaterialServiceProvider::componentPath(), 'm');
|
||||||
|
|
||||||
|
expect(Blade::render('<x-m::drawer title="Share" with-close-button separator><x-m::input label="Name" clearable /></x-m::drawer>'))
|
||||||
|
->toContain('aria-label="Close"')
|
||||||
|
->toContain('role="separator"')
|
||||||
|
->toContain('data-field-clear');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is not shadowed by an application component of the same name', function () {
|
||||||
|
$views = sys_get_temp_dir().'/livewire-material-shadow-'.uniqid();
|
||||||
|
File::ensureDirectoryExists($views.'/components');
|
||||||
|
File::put($views.'/components/button.blade.php', '<span>the application\'s button</span>');
|
||||||
|
View::getFinder()->prependLocation($views);
|
||||||
|
|
||||||
|
try {
|
||||||
|
expect(Blade::render('<x-button />'))->toContain('the application\'s button')
|
||||||
|
->and(Blade::render('<x-drawer title="Share" with-close-button />'))->not->toContain('the application\'s button')
|
||||||
|
->toContain('aria-label="Close"');
|
||||||
|
} finally {
|
||||||
|
File::deleteDirectory($views);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows the showcase\'s examples as an application with a prefix writes them', function () {
|
||||||
|
config(['livewire-material.prefix' => 'm']);
|
||||||
|
Blade::anonymousComponentPath(LivewireMaterialServiceProvider::componentPath(), 'm');
|
||||||
|
|
||||||
|
expect(Blade::render('<x-showcase::example title="Buttons" :code="$code" />', ['code' => '<x-button label="Save" />']))
|
||||||
|
->toContain('<x-m::button label="Save" />')
|
||||||
|
->toContain('Save</span>');
|
||||||
|
});
|
||||||
@@ -26,12 +26,12 @@ it('registers the components without a prefix', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('registers the components under a configured prefix', function () {
|
it('registers the components under a configured prefix', function () {
|
||||||
config(['livewire-material.prefix' => 'm-']);
|
config(['livewire-material.prefix' => 'm']);
|
||||||
|
|
||||||
$provider = app()->getProvider(LivewireMaterialServiceProvider::class);
|
$provider = app()->getProvider(LivewireMaterialServiceProvider::class);
|
||||||
(fn () => $this->registerComponents())->call($provider);
|
(fn () => $this->registerComponents())->call($provider);
|
||||||
|
|
||||||
expect(packageComponentPaths()->last()['prefix'])->toBe('m-');
|
expect(packageComponentPaths()->last()['prefix'])->toBe('m');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('keeps blade-icons from registering an <x-icon> that would shadow ours', function () {
|
it('keeps blade-icons from registering an <x-icon> that would shadow ours', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user