├── README.md ├── composer.json ├── composer.lock ├── config └── turbine.php ├── resources ├── js │ └── turbine-ui.js └── views │ ├── auth │ └── breeze │ │ ├── tui-confirm-password.blade.php │ │ ├── tui-forgot-password.blade.php │ │ ├── tui-login.blade.php │ │ ├── tui-register.blade.php │ │ ├── tui-reset-password.blade.php │ │ └── tui-verify-email.blade.php │ ├── components │ ├── alert.blade.php │ ├── avatar.blade.php │ ├── badge.blade.php │ ├── burger.blade.php │ ├── button-group.blade.php │ ├── button.blade.php │ ├── card.blade.php │ ├── code.blade.php │ ├── container.blade.php │ ├── dropdown.blade.php │ ├── faq.blade.php │ ├── grid.blade.php │ ├── heading.blade.php │ ├── input-group.blade.php │ ├── input.blade.php │ ├── label.blade.php │ ├── link.blade.php │ ├── list-group.blade.php │ ├── media.blade.php │ ├── menu.blade.php │ ├── modal.blade.php │ ├── nav-link.blade.php │ ├── navbar.blade.php │ ├── progress.blade.php │ ├── section.blade.php │ ├── select.blade.php │ ├── sidebar.blade.php │ ├── stat.blade.php │ ├── table.blade.php │ ├── text.blade.php │ ├── textarea.blade.php │ ├── theme-switcher.blade.php │ ├── toast.blade.php │ └── toggle.blade.php │ ├── profile │ ├── partials │ │ ├── tui-delete-user-form.blade.php │ │ ├── tui-update-password-form.blade.php │ │ └── tui-update-profile-information-form.blade.php │ └── tui-edit.blade.php │ └── themes │ ├── kinetic.php │ └── primal.php └── src ├── Console ├── CreateVariant.php └── stubs │ └── variant.stub ├── Turbine.php ├── TurbineUiCoreServiceProvider.php └── View └── Components ├── Alert.php ├── Avatar.php ├── Badge.php ├── Burger.php ├── Button.php ├── ButtonGroup.php ├── Card.php ├── Code.php ├── Container.php ├── Dropdown.php ├── Faq.php ├── Grid.php ├── Heading.php ├── Input.php ├── InputGroup.php ├── Label.php ├── Link.php ├── ListGroup.php ├── Media.php ├── Menu.php ├── Modal.php ├── NavLink.php ├── Navbar.php ├── Progress.php ├── Section.php ├── Select.php ├── Sidebar.php ├── Stat.php ├── Table.php ├── Text.php ├── Textarea.php ├── ThemeSwitcher.php ├── Toast.php └── Toggle.php /README.md: -------------------------------------------------------------------------------- 1 | # About Turbine UI 2 | 3 | Turbine UI is a Laravel Blade & Tailwind CSS UI component library that helps you build elegant and responsive user interfaces that'll make your pages pop. Say goodbye to designer's block forever. 4 | 5 | # Documentation 6 | 7 | ## Download 8 | 9 | Turbine UI is free and can be downloaded via composer: 10 | 11 | ``` 12 | composer require brandymedia/turbine-ui-core 13 | ``` 14 | 15 | ## Installation 16 | 17 | #### Requirements 18 | 19 | - **MUST** be using at least Laravel 10 20 | - **MUST** be using at least PHP 8.1 21 | - **MUST** be using Tailwind CSS 22 | 23 | ### Tailwind CSS Setup 24 | 25 | Once you've installed Turbine UI you'll need to update your **tailwind.config.js** file. 26 | 27 | In the 'content' section, add **./vendor/brandymedia/turbine-ui-core/**/*.php** as a new line: 28 | 29 | ``` 30 | content: [ 31 | '...', 32 | './vendor/brandymedia/turbine-ui-core/**/*.php', 33 | ], 34 | ``` 35 | 36 | You'll also need to make sure you're using the Tailwind Forms plugin in your **tailwind.config.js** file. This is normally included by default when using a starter kit such as Laravel Breeze. 37 | 38 | ``` 39 | import forms from '@tailwindcss/forms'; 40 | 41 | export default { 42 | ... 43 | plugins: [forms], 44 | }; 45 | ``` 46 | 47 | Then in development run: 48 | 49 | ``` 50 | npm run dev 51 | ``` 52 | 53 | Or in production run: 54 | 55 | ``` 56 | npm run build 57 | ``` 58 | 59 | ### Themes 60 | 61 | Turbine UI comes with 2 themes by default with further themes in development: 62 | 63 | - Kinetic (default) 64 | - Primal (Pro) 65 | 66 | You can switch themes by adding the **TURBINE_UI_THEME** key to your .env file: 67 | 68 | ``` 69 | TURBINE_UI_THEME=kinetic|primal 70 | ``` 71 | 72 | You can also edit themes by publishing the packages assets: 73 | 74 | ``` 75 | php artisan vendor:publish --tag=turbine-ui-themes 76 | ``` 77 | 78 | This makes local copies of the themes in the **./resources/views/vendor/turbine-ui/themes** directory which can then be edited to meet your requirements. 79 | 80 | > [!NOTE] 81 | > To use local themes, you will need to update your **tailwind.config.js** file. 82 | 83 | In the 'content' section, add **./resources/views/**/*.php** as a new line: 84 | 85 | ``` 86 | content: [ 87 | '...', 88 | './resources/views/**/*.php', 89 | ], 90 | ``` 91 | 92 | ### Variants 93 | 94 | Think of variants as colour palettes. The default themes already come with several predefined variants but you can create your own, or even overwrite existing one. 95 | 96 | To create a new variant, run the following command in your CLI: 97 | 98 | ``` 99 | php artisan turbine:create-variant 100 | ``` 101 | 102 | You will then be prompted to enter the variants name. **To overwrite an existing theme level variant, use the same name for example ___primary___**. 103 | 104 | Once the new variant has been created you will find it here **../resources/views/vendor/turbine-ui/variants**. 105 | 106 | > [!NOTE] 107 | > To use local variants, you will need to update your **tailwind.config.js** file. 108 | 109 | In the 'content' section, add **./resources/views/**/*.php** as a new line: 110 | 111 | ``` 112 | content: [ 113 | '...', 114 | './resources/views/**/*.php', 115 | ], 116 | ``` 117 | 118 | You can now use your new variant on your components using kebab-case formatting. 119 | 120 | ### JavaScript 121 | 122 | > [!NOTE] 123 | > Some of the Turbine UI components require JavaScript to function properly. 124 | 125 | You'll need to first publish the js files: 126 | 127 | ``` 128 | php artisan vendor:publish --tag=turbine-ui-js 129 | ``` 130 | 131 | Then add the Turbine UI blade directive to your head: 132 | 133 | ``` 134 | @turbineUI 135 | ``` 136 | 137 | ### Components 138 | 139 | You can view the documentation for each of the components [here](https://turbineui.com/components) -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "brandymedia/turbine-ui-core", 3 | "description": "Tailwind CSS styled Laravel Blade components", 4 | "license": "MIT", 5 | "autoload": { 6 | "psr-4": { 7 | "Brandymedia\\TurbineUiCore\\": "src/" 8 | } 9 | }, 10 | "authors": [ 11 | { 12 | "name": "Andy Griffiths" 13 | } 14 | ], 15 | "extra": { 16 | "laravel": { 17 | "providers": [ 18 | "Brandymedia\\TurbineUiCore\\TurbineUiCoreServiceProvider" 19 | ] 20 | } 21 | }, 22 | "require": { 23 | "php": "^8.1.0", 24 | "gehrisandro/tailwind-merge-laravel": "^1.0", 25 | "laravel/prompts": "^0.3", 26 | "illuminate/support": "^10.0|^11.0|^12.0", 27 | "illuminate/console": "^10.0|^11.0|^12.0", 28 | "illuminate/view": "^10.0|^11.0|^12.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /config/turbine.php: -------------------------------------------------------------------------------- 1 | env('TURBINE_UI_THEME', 'kinetic'), 5 | ]; -------------------------------------------------------------------------------- /resources/js/turbine-ui.js: -------------------------------------------------------------------------------- 1 | (function() 2 | { 3 | 4 | document.querySelectorAll('.tui-dismissible').forEach(item => { 5 | item.addEventListener('click', e => { 6 | let toast = e.currentTarget.classList.contains('tui-toast'); 7 | if (toast) { 8 | e.currentTarget.parentNode.parentNode.remove(); 9 | } 10 | e.currentTarget.parentNode.remove(); 11 | }) 12 | }); 13 | 14 | const burger = document.querySelector('.tui-burger'); 15 | const menu = document.querySelector('.tui-menu'); 16 | const bars = document.querySelectorAll('.tui-bar'); 17 | 18 | if (burger) { 19 | burger.addEventListener('click', () => { 20 | menu.classList.toggle('hidden'); 21 | bars[0].classList.toggle('transform'); 22 | bars[0].classList.toggle('translate-y-1.5'); 23 | bars[0].classList.toggle('-rotate-45'); 24 | bars[1].classList.toggle('hidden'); 25 | bars[2].classList.toggle('transform'); 26 | bars[2].classList.toggle('-translate-y-1'); 27 | bars[2].classList.toggle('rotate-45'); 28 | }); 29 | } 30 | 31 | const dropdowns = document.querySelectorAll('.tui-dropdown'); 32 | 33 | if (dropdowns) { 34 | dropdowns.forEach(dropdown => { 35 | const button = dropdown.querySelector('button'); 36 | const content = dropdown.querySelector('.tui-dropdown-content'); 37 | 38 | button.addEventListener('click', e => { 39 | e.stopPropagation(); 40 | content.classList.toggle('hidden'); 41 | }); 42 | }); 43 | 44 | document.addEventListener('click', e => { 45 | dropdowns.forEach(dropdown => { 46 | const content = dropdown.querySelector('.tui-dropdown-content'); 47 | content.classList.add('hidden'); 48 | }); 49 | }); 50 | } 51 | }()); -------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-confirm-password.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | @csrf 4 | 9 | 10 | 16 | {{ __('Confirm password') }} 17 | 18 | 19 | 20 | @if ($errors->any()) 21 | 29 |
    30 | @foreach ($errors->all() as $error) 31 |
  • {{ $error }}
  • 32 | @endforeach 33 |
34 |
35 | @endif 36 | 43 | {{ __('This is a secure area of the application. Please confirm your password before continuing.') }} 44 | 45 | 55 |
56 | 57 | 58 | 63 | {{ __('Confirm') }} 64 | 65 | @if (Route::has('password.request')) 66 |
67 | 71 | {{ __('Forgot your password?') }} 72 | 73 |
74 | @endif 75 |
76 |
77 |
78 |
79 |
-------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-forgot-password.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | @csrf 4 | 9 | 10 | 16 | {{ __('Forgot your password?') }} 17 | 18 | 19 | 20 | @if (session('status')) 21 | 29 | {{ session('status') }} 30 | 31 | @endif 32 | @if ($errors->any()) 33 | 41 |
    42 | @foreach ($errors->all() as $error) 43 |
  • {{ $error }}
  • 44 | @endforeach 45 |
46 |
47 | @endif 48 | 60 |
61 | 62 | 63 | 68 | {{ __('Email Password Reset Link') }} 69 | 70 |
71 | 75 | {{ __('Login instead?') }} 76 | 77 |
78 |
79 |
80 |
81 |
82 |
-------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-login.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | @csrf 4 | 9 | 10 | 16 | {{ __('Login to your account') }} 17 | 18 | 19 | 20 | @if ($errors->any()) 21 | 29 |
    30 | @foreach ($errors->all() as $error) 31 |
  • {{ $error }}
  • 32 | @endforeach 33 |
34 |
35 | @endif 36 | 48 | 58 | 65 |
66 | 67 | 68 | 73 | {{ __('Log In') }} 74 | 75 | @if (Route::has('password.request')) 76 |
77 | 81 | {{ __('Forgot your password?') }} 82 | 83 |
84 | @endif 85 |
86 |
87 |
88 |
89 |
-------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-register.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | @csrf 4 | 9 | 10 | 16 | {{ __('Register a new account') }} 17 | 18 | 19 | 20 | @if ($errors->any()) 21 | 29 |
    30 | @foreach ($errors->all() as $error) 31 |
  • {{ $error }}
  • 32 | @endforeach 33 |
34 |
35 | @endif 36 | 48 | 59 | 69 | 79 |
80 | 81 | 82 | 87 | {{ __('Register') }} 88 | 89 |
90 | 94 | {{ __('Already registered?') }} 95 | 96 |
97 |
98 |
99 |
100 |
101 |
-------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-reset-password.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | @csrf 4 | 9 | 10 | 16 | {{ __('Reset password') }} 17 | 18 | 19 | 20 | @if ($errors->any()) 21 | 29 |
    30 | @foreach ($errors->all() as $error) 31 |
  • {{ $error }}
  • 32 | @endforeach 33 |
34 |
35 | @endif 36 | 37 | 49 | 59 | 69 |
70 | 71 | 72 | 77 | {{ __('Reset Password') }} 78 | 79 |
80 | 84 | {{ __('Login instead?') }} 85 | 86 |
87 |
88 |
89 |
90 |
91 |
-------------------------------------------------------------------------------- /resources/views/auth/breeze/tui-verify-email.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | {{ __('Verify your email') }} 15 | 16 | 17 | 18 | @if (session('status') == 'verification-link-sent') 19 | 27 | {{ __('A new verification link has been sent to the email address you provided during registration.') }} 28 | 29 | @endif 30 | 37 | {{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }} 38 | 39 | 40 | 41 | 42 |
43 | @csrf 44 | 50 | {{ __('Resend Verification Email') }} 51 | 52 |
53 |
54 | @csrf 55 | 62 | {{ __('Log Out') }} 63 | 64 |
65 |
66 |
67 |
68 |
-------------------------------------------------------------------------------- /resources/views/components/alert.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | @isset($icon) 3 | {!! $icon !!} 4 | @endisset 5 |
twMergeFor('content', $contentClasses) }}> 6 | @isset($title) 7 |

twMergeFor('title', $titleClasses) }}>{{ $title }}

8 | @endisset 9 | @if($slot->isNotEmpty()) 10 | {{ $slot }} 11 | @endif 12 |
13 | @isset($dismissible) 14 | 19 | @endisset 20 |
-------------------------------------------------------------------------------- /resources/views/components/avatar.blade.php: -------------------------------------------------------------------------------- 1 | @if ($label) 2 |
twMerge(['class' => $classes]) }}> 3 |
twMergeFor('label', 'tui-label '.$labelClasses) }}> 4 | {{ $label }} 5 |
6 |
7 | @else 8 | twMerge(['class' => $classes]) }} src="{{ $img }}" alt="{{ $alt }}"> 9 | @endif -------------------------------------------------------------------------------- /resources/views/components/badge.blade.php: -------------------------------------------------------------------------------- 1 | twMerge(['class' => $classes]) }}> 2 | @isset($prefix) 3 | twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!} 4 | @endisset 5 | @isset($icon) 6 | twMergeFor('icon', 'tui-icon '.$iconClasses) }}>{!! $icon !!} 7 | @endisset 8 | twMergeFor('content', 'tui-content '.$contentClasses) }}>{{ $slot }} 9 | @isset($suffix) 10 | twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!} 11 | @endisset 12 | -------------------------------------------------------------------------------- /resources/views/components/burger.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $background = $classes['background'] ?? null; 3 | @endphp 4 |
twMerge(['class' => 'tui-burger '.$classes['base']]) }}> 5 |
twMergeFor('bar', 'tui-bar '.$barClasses.' '.$background) }}>
6 |
twMergeFor('bar', 'tui-bar '.$barClasses.' '.$background) }}>
7 |
twMergeFor('bar', 'tui-bar '.$barClasses.' '.$background) }}">
8 |
-------------------------------------------------------------------------------- /resources/views/components/button-group.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /resources/views/components/button.blade.php: -------------------------------------------------------------------------------- 1 | @isset ($href) 2 | twMerge(['class' => $classes]) }} 5 | > 6 | @isset($prefix) 7 | twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!} 8 | @endisset 9 | twMergeFor('content', 'tui-content '.$contentClasses) }}>{{ $slot }} 10 | @isset($suffix) 11 | twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!} 12 | @endisset 13 | 14 | @else 15 | 27 | @endisset -------------------------------------------------------------------------------- /resources/views/components/card.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 | @isset($header) 4 |
twMergeFor('header', 'tui-header '.$headerClasses.' '.$header->attributes['class']) }}> 5 | {{ $header }} 6 |
7 | @endisset 8 | @isset($body) 9 |
twMergeFor('body', 'tui-body '.$bodyClasses.' '.$body->attributes['class']) }}> 10 | {{ $body }} 11 |
12 | @endisset 13 | @isset($footer) 14 |
twMergeFor('footer', 'tui-footer '.$footerClasses.' '.$footer->attributes['class']) }}> 15 | {{ $footer }} 16 |
17 | @endisset 18 |
-------------------------------------------------------------------------------- /resources/views/components/code.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 |
3 | @if ($blade)
4 | {!! $slot !!}
5 | @else
6 | {!! htmlentities($slot) !!}
7 | @endif
8 | 
9 |
-------------------------------------------------------------------------------- /resources/views/components/container.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /resources/views/components/dropdown.blade.php: -------------------------------------------------------------------------------- 1 |
2 | {{ $slot }} 3 |
twMerge(['class' => 'tui-dropdown-content ' . $classes]) }}> 4 | {{ $content }} 5 |
6 |
-------------------------------------------------------------------------------- /resources/views/components/faq.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | @isset($question) 3 | twMergeFor('question', $questionClasses.' '.$question->attributes['class']) }}> 4 |
{{ $question }}
5 | twMergeFor('expand-icon', $expandIconClasses) }}> 6 | 7 | 8 |
9 | @endisset 10 | @isset($answer) 11 |
twMergeFor('answer', $answerClasses.' '.$answer->attributes['class']) }}> 12 | {{ $answer }} 13 |
14 | @endisset 15 |
-------------------------------------------------------------------------------- /resources/views/components/grid.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /resources/views/components/heading.blade.php: -------------------------------------------------------------------------------- 1 | <{{ $heading }} {{ $attributes->twMerge(['class' => $classes]) }}>{{ $slot }} -------------------------------------------------------------------------------- /resources/views/components/input-group.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /resources/views/components/input.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $base = $attributes->only('class')->withoutTwMergeClasses()->twMerge(['class' => $classes]); 3 | @endphp 4 | 5 | @if($type === 'range') 6 | @if ($label) 7 |
twMergeFor('input-range-wrapper', 'tui-input-range-wrapper '.$inputRangeWrapperClasses) }}> 8 | twMergeFor('input-range-label', 'tui-input-range-label '.$inputRangeLabelClasses) }}>{{ $label }} 9 | @endif 10 | twMergeFor('input-range', ['class' => $classes.' tui-input-range '.$inputRangeClasses]) }} type="{{ $type }}" {{ $attributes->except('class') }}> 11 | @if ($label) 12 |
13 | @endif 14 | @elseif($type === 'color') 15 | @if ($label) 16 |
twMergeFor('input-wrapper', 'tui-input-wrapper '.$inputWrapperClasses) }}> 17 | {{ $label }} 18 | @endif 19 | twMerge(['class' => $classes]) }} type="{{ $type }}"> 20 | @if ($label) 21 |
22 | @endif 23 | @elseif($type === 'checkbox') 24 |
twMergeFor('input-checkbox-wrapper', 'tui-input-checkbox-wrapper '.$inputCheckboxWrapperClasses) }}> 25 | twMergeFor('input-checkbox', ['class' => $classes.' tui-input-checkbox '.$inputCheckboxClasses]) }} type="{{ $type }}" {{ $attributes->except('class') }}> 26 | @if ($label) 27 | twMergeFor('input-checkbox-label', 'tui-input-checkbox-label '.$inputCheckboxLabelClasses) }}> 28 | {{ $label }} 29 | 30 | @endif 31 |
32 | @elseif($type === 'radio') 33 |
twMergeFor('input-radio-wrapper', 'tui-input-radio-wrapper '.$inputRadioWrapperClasses) }}> 34 | twMergeFor('input-radio', ['class' => $classes.' tui-input-radio '.$inputRadioClasses]) }} type="{{ $type }}" {{ $attributes->except('class') }}> 35 | @if ($label) 36 | twMergeFor('input-radio-label', 'tui-input-radio-label '.$inputRadioLabelClasses) }}> 37 | {{ $label }} 38 | 39 | @endif 40 |
41 | @elseif($type === 'hidden') 42 | merge() }} type="{{ $type }}"> 43 | @elseif($type === 'file') 44 | @if ($label) 45 |
twMergeFor('input-wrapper', 'tui-input-wrapper '.$inputWrapperClasses) }}> 46 | twMergeFor('label', 'tui-label '.$labelClasses) }}>{{ $label }} 47 | @endif 48 |
only('class')->twMerge(['class' => $classes]) }}> 49 | @if ($prefix) 50 |
twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!}
51 | @endif 52 | except('class') }} type="{{ $type }}" {{ $attributes->twMergeFor('input', 'tui-input file:hidden cursor-pointer pl-3 '.$inputClasses) }}> 53 | @if ($suffix) 54 |
twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!}
55 | @endif 56 |
57 | @if ($label) 58 |
59 | @endif 60 | @else 61 | @if ($label) 62 |
twMergeFor('input-wrapper', 'tui-input-wrapper '.$inputWrapperClasses) }}> 63 | twMergeFor('label', 'tui-label '.$labelClasses) }}>{{ $label }}twMergeFor('hint', 'tui-hint '.$hintClasses) }}>{{ $hint }} 64 | @endif 65 |
66 | @if ($prefix) 67 |
twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!}
68 | @endif 69 | except('class') }} type="{{ $type ?? 'text' }}" {{ $attributes->twMergeFor('input', 'tui-input '.$inputClasses) }}> 70 | @if ($suffix) 71 |
twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!}
72 | @endif 73 |
74 | @if ($label) 75 |
76 | @endif 77 | @endif -------------------------------------------------------------------------------- /resources/views/components/label.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/components/link.blade.php: -------------------------------------------------------------------------------- 1 | twMerge(['class' => $classes]) }}> 2 | @isset($prefix) 3 | twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!} 4 | @endisset 5 | twMergeFor('content', 'tui-content '.$contentClasses) }}>{{ $slot }} 6 | @isset($suffix) 7 | twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!} 8 | @endisset 9 | -------------------------------------------------------------------------------- /resources/views/components/list-group.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/components/media.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 | @isset($thumbnail) 4 |
twMergeFor('thumbnail', 'tui-thumbnail '.$thumbnailClasses.' '.$thumbnail->attributes['class']) }}> 5 | {{ $thumbnail }} 6 |
7 | @endisset 8 |
twMergeFor('body', 'tui-body '.$bodyClasses) }}> 9 | @isset($title) 10 |
twMergeFor('title', 'tui-title '.$titleClasses.' '.$title->attributes['class']) }}> 11 | {{ $title }} 12 |
13 | @endisset 14 | @isset($description) 15 |
twMergeFor('description', 'tui-description '.$descriptionClasses.' '.$description->attributes['class']) }}> 16 | {{ $description }} 17 |
18 | @endisset 19 |
20 |
-------------------------------------------------------------------------------- /resources/views/components/menu.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/components/modal.blade.php: -------------------------------------------------------------------------------- 1 |
2 |
twMergeFor('backdrop', 'tui-backdrop '.$backdropClasses) }}> 3 |
twMergeFor('content', 'tui-content '.$contentClasses) }}> 4 | {{ $content }} 5 |
6 | @isset($dismissible) 7 | 12 | @endisset 13 |
14 | {{ $slot }} 15 |
16 | 17 | -------------------------------------------------------------------------------- /resources/views/components/nav-link.blade.php: -------------------------------------------------------------------------------- 1 | twMerge(['class' => $classes]) }}> 2 | @isset($prefix) 3 | twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!} 4 | @endisset 5 | twMergeFor('content', 'tui-content '.$contentClasses) }}>{{ $slot }} 6 | @isset($suffix) 7 | twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!} 8 | @endisset 9 | -------------------------------------------------------------------------------- /resources/views/components/navbar.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | 10 |
-------------------------------------------------------------------------------- /resources/views/components/progress.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $base = $attributes->withoutTwMergeClasses()->twMerge(['class' => $classes]); 3 | @endphp 4 |
twMergeFor('progress-wrapper', 'tui-progress-wrapper '.$progressWrapperClasses) }}> 5 |
twMergeFor('text-wrapper', 'tui-text-wrapper '.$textWrapperClasses) }}> 6 | @if ($label) 7 | twMergeFor('label', 'tui-label '.$labelClasses) }}>{{ $label }} 8 | @endif 9 | twMergeFor('percentage', 'tui-percentage '.$percentageClasses) }}>{{ $percentage ? $percentage : 0 }}% 10 |
11 |
twMergeFor('bar', 'tui-bar '.$barClasses) }}> 12 |
13 |
14 |
-------------------------------------------------------------------------------- /resources/views/components/section.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | {{ $slot }} 3 |
-------------------------------------------------------------------------------- /resources/views/components/select.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $base = $attributes->only('class')->withoutTwMergeClasses()->twMerge(['class' => $classes]); 3 | @endphp 4 | 5 | @if ($label) 6 |
twMergeFor('select-wrapper', 'tui-select-wrapper '.$selectWrapperClasses) }}> 7 | twMergeFor('label', 'tui-label '.$labelClasses) }}>{{ $label }}twMergeFor('hint', 'tui-hint '.$hintClasses) }}>{{ $hint }} 8 | @endif 9 |
10 | @if ($prefix) 11 |
twMergeFor('prefix', 'tui-prefix '.$prefixClasses) }}>{!! $prefix !!}
12 | @endif 13 | 16 | @if ($suffix) 17 |
twMergeFor('suffix', 'tui-suffix '.$suffixClasses) }}>{!! $suffix !!}
18 | @endif 19 |
20 | @if ($label) 21 |
22 | @endif -------------------------------------------------------------------------------- /resources/views/components/sidebar.blade.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | @isset($dismissible) 13 | 20 | @endisset -------------------------------------------------------------------------------- /resources/views/components/stat.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 | @isset($icon) 3 |
twMergeFor('icon', 'tui-icon '.$iconClasses) }}>{!! $icon !!}
4 | @endisset 5 | @isset($title) 6 |
twMergeFor('title', 'tui-title '.$titleClasses.' '.$title->attributes['class']) }}> 7 | {{ $title }} 8 |
9 | @endisset 10 | @isset($value) 11 |
twMergeFor('value', 'tui-value '.$valueClasses.' '.$value->attributes['class']) }}> 12 | {{ $value }} 13 |
14 | @endisset 15 | @isset($description) 16 |
twMergeFor('description', 'tui-description '.$descriptionClasses.' '.$description->attributes['class']) }}> 17 | {{ $description }} 18 |
19 | @endisset 20 |
-------------------------------------------------------------------------------- /resources/views/components/table.blade.php: -------------------------------------------------------------------------------- 1 | twMerge(['class' => $classes]) }}> 2 | @isset($thead) 3 | twMergeFor('thead', 'tui-thead '.$theadClasses.' '.$thead->attributes['class']) }}> 4 | {{ $thead }} 5 | 6 | @endisset 7 | @isset($tbody) 8 | twMergeFor('tbody', 'tui-tbody '.$tbodyClasses.' '.$tbody->attributes['class']) }}> 9 | {{ $tbody }} 10 | 11 | @endisset 12 | @isset($tfoot) 13 | twMergeFor('tfoot', 'tui-tfoot '.$tfootClasses.' '.$tfoot->attributes['class']) }}> 14 | {{ $tfoot }} 15 | 16 | @endisset 17 | {{ $slot }} 18 |
-------------------------------------------------------------------------------- /resources/views/components/text.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $tag = match ($level) { 3 | '1' => 'h1', 4 | '2' => 'h2', 5 | '3' => 'h3', 6 | '4' => 'h4', 7 | '5' => 'h5', 8 | '6' => 'h6', 9 | default => 'p', 10 | }; 11 | @endphp 12 | <{{ $tag }} {{ $attributes->twMerge(['class' => $classes]) }}>{{ $slot }} -------------------------------------------------------------------------------- /resources/views/components/textarea.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $base = $attributes->withoutTwMergeClasses()->twMerge(['class' => $classes]); 3 | @endphp 4 | @if ($label) 5 |
twMergeFor('textarea-wrapper', 'tui-textarea-wrapper '.$textareaWrapperClasses) }}> 6 | twMergeFor('label', 'tui-label '.$labelClasses) }}>{{ $label }} 7 | @endif 8 |
9 | @isset($header) 10 |
twMergeFor('header', 'tui-header '.$headerClasses.' '.$header->attributes['class']) }}> 11 | {{ $header }} 12 |
13 | @endisset 14 | 15 | @isset($footer) 16 |
twMergeFor('footer', 'tui-footer '.$footerClasses.' '.$footer->attributes['class']) }}> 17 | {{ $footer }} 18 |
19 | @endisset 20 |
21 | @if ($label) 22 |
23 | @endif -------------------------------------------------------------------------------- /resources/views/components/theme-switcher.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $lightIcon = config('turbine.components.theme-switcher.icons.light') ?? ""; 3 | $darkIcon = config('turbine.components.theme-switcher.icons.dark') ?? ""; 4 | $systemIcon = config('turbine.components.theme-switcher.icons.system') ?? ""; 5 | @endphp 6 | twMerge('tui-theme-switcher ' . $classes) }}> 7 | twMergeFor('switch-button', 'tui-theme-switcher-button '.$switchButtonClasses) }}> 8 | 9 | twMergeFor('list-group', $listGroupClasses) }}> 10 | @if (config('turbine.components.theme-switcher.options.light') !== false) 11 | twMergeFor('light-button', 'tui-theme-switcher-option '.$lightButtonClasses) }}> 12 | {{ config('turbine.components.theme-switcher.text.light') ?? __('Light') }} 13 | 14 | @endif 15 | @if (config('turbine.components.theme-switcher.options.dark') !== false) 16 | twMergeFor('dark-button', 'tui-theme-switcher-option '.$darkButtonClasses) }}> 17 | {{ config('turbine.components.theme-switcher.text.dark') ?? __('Dark') }} 18 | 19 | @endif 20 | @if (config('turbine.components.theme-switcher.options.system') !== false) 21 | twMergeFor('system-button', 'tui-theme-switcher-option '.$systemButtonClasses) }}> 22 | {{ config('turbine.components.theme-switcher.text.system') ?? __('System') }} 23 | 24 | @endif 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/views/components/toast.blade.php: -------------------------------------------------------------------------------- 1 |
twMerge(['class' => $classes]) }}> 2 |
twMergeFor('toast', $toastClasses) }}> 3 | @isset($icon) 4 | {!! $icon !!} 5 | @endisset 6 |
twMergeFor('content', $contentClasses) }}> 7 | @isset($title) 8 |

twMergeFor('title', $titleClasses) }}>{{ $title }}

9 | @endisset 10 | @if($slot->isNotEmpty()) 11 | {{ $slot }} 12 | @endif 13 |
14 | @isset($dismissible) 15 | 20 | @endisset 21 |
22 |
-------------------------------------------------------------------------------- /resources/views/components/toggle.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/profile/partials/tui-delete-user-form.blade.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | {{ __('Delete Account') }} 14 | 15 | 16 | 17 | @if ($errors->userDeletion->get('password')) 18 | 26 |
    27 |
  • {{ $errors->userDeletion->get('password')[0] }}
  • 28 |
29 |
30 | @endif 31 | {{ __("Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.") }} 32 |
33 | 34 | 35 | 36 |
37 | @csrf 38 | @method('delete') 39 | 43 | 44 | {{ __('Are you sure you want to delete your account?') }} 45 | 46 | 47 | 54 | {{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }} 55 | 56 | @if ($errors->userDeletion->get('password')) 57 | 65 |
    66 |
  • {{ $errors->userDeletion->get('password')[0] }}
  • 67 |
68 |
69 | @endif 70 | 80 |
81 | 82 | 83 | 88 | {{ __('Delete Account') }} 89 | 90 |
91 | 95 | {{ __('Cancel') }} 96 | 97 |
98 |
99 |
100 |
101 |
102 |
103 | 109 | {{ __('Delete Account') }} 110 | 111 |
112 |
113 |
-------------------------------------------------------------------------------- /resources/views/profile/partials/tui-update-password-form.blade.php: -------------------------------------------------------------------------------- 1 | @if (session('status') === 'password-updated') 2 |
8 | 11 | {{ __('Saved.') }} 12 | 13 |
14 | @endif 15 |
16 | @csrf 17 | @method('put') 18 | 23 | 24 | 30 | {{ __('Update Password') }} 31 | 32 | 33 | 34 | {{ __("Ensure your account is using a long, random password to stay secure.") }} 35 | 43 | 44 | 52 | 53 | 61 | 62 | 63 | 64 | 69 | {{ __('Save') }} 70 | 71 | 72 | 73 |
-------------------------------------------------------------------------------- /resources/views/profile/partials/tui-update-profile-information-form.blade.php: -------------------------------------------------------------------------------- 1 | @if (session('status') === 'profile-updated') 2 |
8 | 11 | {{ __('Saved.') }} 12 | 13 |
14 | @endif 15 |
16 | @csrf 17 |
18 |
19 | @csrf 20 | @method('patch') 21 | 26 | 27 | 33 | {{ __('Profile Information') }} 34 | 35 | 36 | 37 | {{ __("Update your account's profile information and email address.") }} 38 | 49 | 50 | 61 | 62 | 63 | @if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail()) 64 | 71 | 72 | {{ __('Your email address is unverified.') }} 73 | 79 | {{ __('Resend Verification Email') }} 80 | 81 | 82 | 83 | @if (session('status') === 'verification-link-sent') 84 | 91 | {{ __('A new verification link has been sent to your email address.') }} 92 | 93 | @endif 94 | @endif 95 | 96 | 97 | 102 | {{ __('Save') }} 103 | 104 | 105 | 106 |
-------------------------------------------------------------------------------- /resources/views/profile/tui-edit.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | {{ __('Profile') }} 10 | 11 | 12 | 13 | 17 | @include('profile.partials.update-profile-information-form') 18 | 19 | 20 | 21 | 25 | @include('profile.partials.update-password-form') 26 | 27 | 28 | 29 | 33 | @include('profile.partials.delete-user-form') 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/Console/CreateVariant.php: -------------------------------------------------------------------------------- 1 | match (true) { 43 | File::exists($localVariantPath.Str::kebab(Str::lower($value)).'.php') => 'The name must be unique.', 44 | default => null 45 | } 46 | ); 47 | 48 | $fileName = Str::kebab(Str::lower($name)); 49 | 50 | if (File::missing($localVariantPath.$fileName.'.php')) { 51 | File::ensureDirectoryExists(dirname($localVariantPath.$fileName.'.php'), 0755, true); 52 | $fileContents = File::get($this->getStub()); 53 | $fileContents = str_replace("{{ name }}", $fileName, $fileContents); 54 | File::put($localVariantPath.$fileName.'.php', $fileContents); 55 | } 56 | 57 | info('Variant created successfully. ' . $localVariantPath.$fileName.'.php'); 58 | } 59 | } -------------------------------------------------------------------------------- /src/Console/stubs/variant.stub: -------------------------------------------------------------------------------- 1 | [ 5 | 'background' => '', 6 | 'text' => '', 7 | 'border' => '', 8 | 'shadow' => '', 9 | 'ring' => '', 10 | 'hover' => '', 11 | 'focus' => '', 12 | 'active' => '', 13 | 'gradient' => '', 14 | 'divide' => '', 15 | 'accent' => '', 16 | ] 17 | ]; -------------------------------------------------------------------------------- /src/Turbine.php: -------------------------------------------------------------------------------- 1 | theme = $this->getTheme(); 16 | } 17 | 18 | private function linkComponent($component, $attributes, $classes) 19 | { 20 | $options = collect($this->theme['design']['components'][$component]['options'] ?? null); 21 | $hasBackground = $this->theme['design']['components'][$component]['options']['background'] ?? null; 22 | 23 | if (!$hasBackground) { 24 | if ($options->contains('hover')) { 25 | if ($options['hover']) { 26 | $classes = $classes->merge(['hover:bg-transparent', 'hover:dark:bg-transparent']); 27 | TailwindMerge::merge($classes->flatten()->implode(' ')); 28 | } 29 | } 30 | } 31 | 32 | return $classes; 33 | } 34 | 35 | private function inputComponent($component, $attributes, $classes) 36 | { 37 | $attributes = collect($attributes); 38 | $attributes['type'] === 'checkbox' ? $isCheckbox = true : $isCheckbox = false; 39 | $attributes['type'] === 'radio' ? $isRadio = true : $isRadio = false; 40 | $attributes['type'] === 'range' ? $isRange = true : $isRange = false; 41 | 42 | if ($isCheckbox || $isRadio) { 43 | $classes->forget('base'); 44 | $classes->forget('size'); 45 | } 46 | 47 | if ($isRange) { 48 | $classes->forget('base'); 49 | } 50 | 51 | return $classes; 52 | } 53 | 54 | private function headingComponent($component, $attributes, $classes) 55 | { 56 | $attributes = collect($attributes); 57 | $level = $attributes['level'] ?? null; 58 | $levels = $this->theme['design']['components'][$component]['sizes'] ?? null; 59 | $size = $attributes['size'] ?? null; 60 | $sizes = $this->theme['design']['components'][$component]['sizes']['h' . $level][$size] ?? null; 61 | $base = $this->theme['design']['components'][$component]['sizes']['h' . $level]['base'] ?? null; 62 | $balance = $attributes['balance'] ?? null; 63 | $pretty = $attributes['pretty'] ?? null; 64 | 65 | if ($level && $levels && $size && $sizes) { 66 | $classes->put('size', $levels['h' . $level][$size]); 67 | } else if ($base) { 68 | $classes->put('size', $base); 69 | } 70 | 71 | if ($balance) { 72 | $classes->put('text-wrap', '[text-wrap:balance]'); 73 | } 74 | 75 | if ($pretty) { 76 | $classes->put('text-wrap', '[text-wrap:pretty]'); 77 | } 78 | 79 | return $classes; 80 | } 81 | 82 | private function textComponent($component, $attributes, $classes) 83 | { 84 | $attributes = collect($attributes); 85 | $level = $attributes['level'] ?? null; 86 | $levels = $this->theme['design']['components'][$component]['sizes'] ?? null; 87 | $size = $attributes['size'] ?? null; 88 | $balance = $attributes['balance'] ?? null; 89 | $pretty = $attributes['pretty'] ?? null; 90 | 91 | if ($level) { 92 | $sizes = $this->theme['design']['components'][$component]['sizes']['h' . $level][$size] ?? null; 93 | } else { 94 | $sizes = $this->theme['design']['components'][$component]['sizes']['p'][$size] ?? null; 95 | } 96 | if ($level) { 97 | $base = $this->theme['design']['components'][$component]['sizes']['h' . $level]['base'] ?? null; 98 | } else { 99 | $base = $this->theme['design']['components'][$component]['sizes']['p']['base'] ?? null; 100 | } 101 | 102 | if ($level && $levels && $size && $sizes) { 103 | $classes->put('size', $levels['h' . $level][$size]); 104 | } else if ($levels && $size && $sizes) { 105 | $classes->put('size', $levels['p'][$size]); 106 | } else if ($base) { 107 | $classes->put('size', $base); 108 | } 109 | 110 | if ($balance) { 111 | $classes->put('text-wrap', '[text-wrap:balance]'); 112 | } 113 | 114 | if ($pretty) { 115 | $classes->put('text-wrap', '[text-wrap:pretty]'); 116 | } 117 | 118 | return $classes; 119 | } 120 | 121 | private function buttonComponent($component, $attributes, $classes) 122 | { 123 | $attributes = collect($attributes); 124 | $link = $attributes->get('link'); 125 | 126 | if ($link) { 127 | $classes->forget('background'); 128 | $classes->forget('border'); 129 | $classes->forget('shadow'); 130 | $classes->forget('ring'); 131 | $classes->forget('hover'); 132 | $classes->forget('gradient'); 133 | $classes->forget('divide'); 134 | $classes = collect(explode(' ', collect($classes)->flatten()->implode(' '))); 135 | } 136 | 137 | return $classes; 138 | } 139 | 140 | private function enabledAttributes($component, $attributes) 141 | { 142 | $attributes = collect($attributes); 143 | $enabledAttributes = collect(); 144 | 145 | if ($attributes) { 146 | foreach ($attributes as $key => $componentLocalAttribute) { 147 | 148 | if ($componentLocalAttribute === '1') { 149 | $enabledAttributes->push($key); 150 | } 151 | 152 | $componentGlobalAttribute = $this->theme['design']['components'][$component]['attributes'][$key] ?? null; 153 | 154 | if ($componentGlobalAttribute && $componentLocalAttribute !== "false") { 155 | if (!is_array($componentGlobalAttribute) && !$componentGlobalAttribute[0] === false) { 156 | if (!$enabledAttributes->contains($key)) { 157 | $enabledAttributes->push($key); 158 | } 159 | } 160 | } 161 | 162 | } 163 | } 164 | 165 | return $enabledAttributes->reverse() ?? null; 166 | } 167 | 168 | private function attributeClasses($component, $attributes) 169 | { 170 | $enabledAttributes = $this->enabledAttributes($component, $attributes); 171 | $attributeClasses = collect(); 172 | 173 | if ($enabledAttributes) { 174 | foreach ($enabledAttributes as $enabledAttribute) { 175 | $componentGlobalAttribute = $this->theme['design']['components'][$component]['attributes'][$enabledAttribute] ?? null; 176 | 177 | if ($componentGlobalAttribute) { 178 | if (is_array($componentGlobalAttribute)) { 179 | $attributeClasses->put($enabledAttribute, $componentGlobalAttribute[1]); 180 | } else { 181 | $attributeClasses->put($enabledAttribute, $componentGlobalAttribute); 182 | } 183 | } 184 | } 185 | } 186 | 187 | return $attributeClasses ?? null; 188 | } 189 | 190 | private function localVariant($variant) 191 | { 192 | $localVariantPath = base_path().'/resources/views/vendor/turbine-ui/variants/'.$variant.'.php'; 193 | $localVariant = null; 194 | 195 | if (File::exists($localVariantPath)) { 196 | $localVariantFile = File::getRequire($localVariantPath); 197 | if (isset($localVariantFile[$variant])) { 198 | $localVariant = $localVariantFile[$variant]; 199 | } 200 | } 201 | 202 | return $localVariant; 203 | } 204 | 205 | private function variantClasses($component, $variant, $attributes) 206 | { 207 | $hasVariant = $this->theme['design']['variants'][$variant] ?? null; 208 | $localVariant = $this->localVariant($variant ?? 'default') ?? null; 209 | $hasVariant ? $variantName = $variant : $variantName = 'default'; 210 | $hasHollow = $attributes['hollow'] ?? null; 211 | $hasHover = $this->theme['design']['components'][$component]['options']['hover'] ?? null; 212 | $hasFocus = $this->theme['design']['components'][$component]['options']['focus'] ?? null; 213 | $hasGradient = $this->theme['design']['components'][$component]['options']['gradient'] ?? null; 214 | $hasBackground = $this->theme['design']['components'][$component]['options']['background'] ?? null; 215 | $hasText = $this->theme['design']['components'][$component]['options']['text'] ?? null; 216 | $hasAccent = $attributes['accent'] ?? null; 217 | 218 | if ($hasBackground !== false) { 219 | $backgroundEnabled = true; 220 | } else { 221 | $backgroundEnabled = false; 222 | } 223 | 224 | if ($hasText !== false) { 225 | $textEnabled = true; 226 | } else { 227 | $textEnabled = false; 228 | } 229 | 230 | $enabledAttributes = $this->enabledAttributes($component, $attributes); 231 | $variantClasses = collect(); 232 | 233 | if (isset($localVariant['border']) && $hasAccent) { 234 | $variantClasses->put('border', $localVariant['border']); 235 | } else { 236 | if (isset($this->theme['design']['variants'][$variantName]['border']) && $hasAccent) { 237 | $variantClasses->put('border', $this->theme['design']['variants'][$variantName]['border']); 238 | } 239 | } 240 | 241 | if (isset($localVariant['background']) && !$hasHollow && !$hasGradient && $backgroundEnabled) { 242 | $variantClasses->put('background', $localVariant['background']); 243 | } else { 244 | if (isset($this->theme['design']['variants'][$variantName]['background']) && !$hasHollow && !$hasGradient && $backgroundEnabled) { 245 | $variantClasses->put('background', $this->theme['design']['variants'][$variantName]['background']); 246 | } 247 | } 248 | 249 | if (isset($localVariant['text'])) { 250 | $variantClasses->put('text', $localVariant['text']); 251 | } else { 252 | if (isset($this->theme['design']['variants'][$variantName]['text'])) { 253 | $variantClasses->put('text', $this->theme['design']['variants'][$variantName]['text']); 254 | } 255 | } 256 | 257 | if ($hasHover) { 258 | if (isset($localVariant['hover'])) { 259 | $variantClasses->put('hover', $localVariant['hover']); 260 | } else { 261 | if (isset($this->theme['design']['variants'][$variantName]['hover'])) { 262 | $variantClasses->put('hover', $this->theme['design']['variants'][$variantName]['hover']); 263 | } 264 | } 265 | } 266 | 267 | if ($hasFocus) { 268 | if (isset($localVariant['focus'])) { 269 | $variantClasses->put('focus', $localVariant['focus']); 270 | } else { 271 | if (isset($this->theme['design']['variants'][$variantName]['focus'])) { 272 | $variantClasses->put('focus', $this->theme['design']['variants'][$variantName]['focus']); 273 | } 274 | } 275 | } 276 | 277 | if ($hasGradient && !$hasHollow) { 278 | if (isset($localVariant['gradient'])) { 279 | $variantClasses->put('gradient', $localVariant['gradient']); 280 | } else { 281 | if (isset($this->theme['design']['variants'][$variantName]['gradient'])) { 282 | $variantClasses->put('gradient', $this->theme['design']['variants'][$variantName]['gradient']); 283 | $variantClasses->forget('text'); 284 | } 285 | } 286 | } 287 | 288 | if (isset($localVariant['accent'])) { 289 | $variantClasses->put('accent', $localVariant['accent']); 290 | } else { 291 | if (isset($this->theme['design']['variants'][$variantName]['accent'])) { 292 | $variantClasses->put('accent', $this->theme['design']['variants'][$variantName]['accent']); 293 | } 294 | } 295 | 296 | if (!$textEnabled) { 297 | $variantClasses->forget('text'); 298 | } 299 | 300 | if ($enabledAttributes) { 301 | foreach ($enabledAttributes as $enabledAttribute) { 302 | if (isset($localVariant[$enabledAttribute])) { 303 | $variantAttribute = $localVariant[$enabledAttribute] ?? null; 304 | } else { 305 | $variantAttribute = $this->theme['design']['variants'][$variantName][$enabledAttribute] ?? null; 306 | } 307 | 308 | if ($variantAttribute) { 309 | $variantClasses->put($enabledAttribute, $variantAttribute); 310 | } 311 | } 312 | } 313 | 314 | return $variantClasses ?? null; 315 | } 316 | 317 | public function sizeClasses($component, $size) 318 | { 319 | $sizeClasses = collect(); 320 | $hasSize = $this->theme['design']['components'][$component]['sizes'][$size] ?? null; 321 | $base = config('turbine.components.'.$component.'.size') ?? 'base'; 322 | 323 | if ($hasSize) { 324 | $sizeClasses->put('size', $hasSize); 325 | } else { 326 | if (isset($this->theme['design']['components'][$component]['sizes'][$base])) { 327 | $sizeClasses->put('size', $this->theme['design']['components'][$component]['sizes'][$base]); 328 | } 329 | } 330 | 331 | return $sizeClasses ?? null; 332 | } 333 | 334 | public function gridClasses($component, $grid) 335 | { 336 | $gridClasses = collect(); 337 | $hasGrid = $this->theme['design']['components'][$component]['grids'][$grid] ?? null; 338 | 339 | if ($hasGrid) { 340 | $gridClasses->put('grid', $hasGrid); 341 | } 342 | 343 | return $gridClasses ?? null; 344 | } 345 | 346 | public function colClasses($component, $col) 347 | { 348 | $colClasses = collect(); 349 | $hasCol = $this->theme['design']['components'][$component]['cols'][$col] ?? null; 350 | 351 | if ($hasCol) { 352 | $colClasses->put('col', $hasCol); 353 | } 354 | 355 | return $colClasses ?? null; 356 | } 357 | 358 | public function gapClasses($component, $gap) 359 | { 360 | $gapClasses = collect(); 361 | 362 | if (isset($gap)) { 363 | 364 | $hasGap = $this->theme['design']['components'][$component]['gap'][$gap] ?? null; 365 | 366 | if ($hasGap) { 367 | $gapClasses->put('gap', $hasGap); 368 | } else { 369 | if (isset($this->theme['design']['components'][$component]['gap']['base'])) { 370 | $gapClasses->put('gap', $this->theme['design']['components'][$component]['gap']['base']); 371 | } 372 | } 373 | 374 | } 375 | 376 | return $gapClasses ?? null; 377 | } 378 | 379 | public function classBuilder($component, $variant, $attributes, $componentTheme = null) 380 | { 381 | $classes = collect(); 382 | 383 | if ($componentTheme) { 384 | $this->theme = $this->getTheme($componentTheme); 385 | } 386 | 387 | $baseClasses = collect(['base' => $this->theme['design']['components'][$component]['base'] ?? null]); 388 | $attributeClasses = $this->attributeClasses($component, $attributes); 389 | $variantClasses = $this->variantClasses($component, $variant, $attributes); 390 | $sizeClasses = $this->sizeClasses($component, $attributes['size'] ?? null); 391 | $gridClasses = $this->gridClasses($component, $attributes['grid'] ?? null); 392 | $colClasses = $this->colClasses($component, $attributes['cols'] ?? null); 393 | $gapClasses = $this->gapClasses($component, $attributes['gap'] ?? null); 394 | $classes = $baseClasses->mergeRecursive($attributeClasses); 395 | $classes = $classes->mergeRecursive($variantClasses); 396 | $classes = $classes->mergeRecursive($sizeClasses); 397 | $classes = $classes->mergeRecursive($gridClasses); 398 | $classes = $classes->mergeRecursive($colClasses); 399 | $classes = $classes->mergeRecursive($gapClasses); 400 | 401 | $componentName = Str::camel($component); 402 | $methodName = $componentName.'Component'; 403 | if (method_exists($this, $methodName)) { 404 | $classes = $this->$methodName($component, $attributes, $classes); 405 | } 406 | 407 | if ($component === 'burger') { 408 | return $classes; 409 | } else { 410 | return $classes ? $classes->flatten()->implode(' ') : null; 411 | } 412 | } 413 | 414 | private function getTheme($name = null) 415 | { 416 | if ($name) { 417 | $theme = $name; 418 | } else { 419 | $theme = config('turbine.theme') ?? 'kinetic'; 420 | } 421 | 422 | $proInstalled = class_exists('\Brandymedia\TurbineUi\TurbinePro'); 423 | 424 | if ($proInstalled) { 425 | $proPackageThemePath = base_path().'/vendor/brandymedia/turbine-ui/resources/views/themes/'.$theme.'.php'; 426 | } else { 427 | $proPackageThemePath = false; 428 | } 429 | 430 | $packageThemePath = __DIR__.'/../resources/views/themes/'.$theme.'.php'; 431 | $localThemePath = base_path().'/resources/views/vendor/turbine-ui/themes/'.$theme.'.php'; 432 | 433 | if (File::exists($localThemePath)) { 434 | $currentTheme = File::getRequire($localThemePath); 435 | } elseif (File::exists($packageThemePath)) { 436 | $currentTheme = File::getRequire($packageThemePath); 437 | } elseif (File::exists($proPackageThemePath)) { 438 | $currentTheme = File::getRequire($proPackageThemePath); 439 | } else { 440 | $currentTheme = File::getRequire(__DIR__.'/../resources/views/themes/kinetic.php'); 441 | } 442 | 443 | return $currentTheme; 444 | } 445 | 446 | public function elementClasses($component, $elements = null, $size) 447 | { 448 | $elementClasses = []; 449 | 450 | if ($elements) { 451 | $sizeOverride = config('turbine.components.'.$component.'.size') ?? null; 452 | 453 | if (!$size) { 454 | $size = $sizeOverride ?? $size ?? null; 455 | } 456 | 457 | foreach ($elements as $element) { 458 | $elementName = Str::kebab($element); 459 | $base = $this->theme['design']['components'][$component]['elements'][$elementName]['base'] ?? null; 460 | $hasSize = $this->theme['design']['components'][$component]['elements'][$elementName]['sizes'][$size] ?? null; 461 | 462 | if (!$hasSize) { 463 | $hasSize = $this->theme['design']['components'][$component]['elements'][$elementName]['sizes']['base'] ?? null; 464 | } 465 | 466 | $elementClasses[$element.'Classes'] = $base . ' ' . $hasSize; 467 | } 468 | } 469 | 470 | return $elementClasses; 471 | } 472 | 473 | } -------------------------------------------------------------------------------- /src/TurbineUiCoreServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom( 48 | __DIR__.'/../config/turbine.php', 'turbine' 49 | ); 50 | 51 | $this->loadViewsFrom(__DIR__.'/../resources/views', 'turbine-ui'); 52 | 53 | $viewComponents = [ 54 | Alert::class, 55 | Avatar::class, 56 | Badge::class, 57 | Burger::class, 58 | Button::class, 59 | ButtonGroup::class, 60 | Card::class, 61 | Code::class, 62 | Container::class, 63 | Dropdown::class, 64 | Faq::class, 65 | Grid::class, 66 | Heading::class, 67 | Input::class, 68 | InputGroup::class, 69 | Label::class, 70 | Link::class, 71 | ListGroup::class, 72 | Media::class, 73 | Menu::class, 74 | Modal::class, 75 | Navbar::class, 76 | NavLink::class, 77 | Progress::class, 78 | Section::class, 79 | Select::class, 80 | Sidebar::class, 81 | Stat::class, 82 | Table::class, 83 | Text::class, 84 | Textarea::class, 85 | ThemeSwitcher::class, 86 | Toast::class, 87 | Toggle::class, 88 | ]; 89 | 90 | $this->loadViewComponentsAs('turbine-ui', $viewComponents); 91 | $this->loadViewComponentsAs('t', $viewComponents); 92 | 93 | if ($this->app->runningInConsole()) { 94 | $this->publishes([ 95 | __DIR__.'/../resources/views/themes/' => $this->app->resourcePath('views/vendor/turbine-ui/themes') 96 | ], 'turbine-ui-themes'); 97 | $this->publishes([ 98 | __DIR__.'/../resources/views/auth/breeze/' => $this->app->resourcePath('views/auth') 99 | ], 'turbine-ui-auth-breeze'); 100 | $this->publishes([ 101 | __DIR__.'/../resources/views/profile/' => $this->app->resourcePath('views/profile') 102 | ], 'turbine-ui-profile'); 103 | $this->publishes([ 104 | __DIR__.'/../resources/js/' => public_path('vendor/turbine-ui/') 105 | ], 'turbine-ui-js'); 106 | $this->commands([ 107 | CreateVariant::class, 108 | ]); 109 | } 110 | 111 | Blade::directive('turbineUI', function () { 112 | return ''; 113 | }); 114 | } 115 | 116 | public function register() 117 | { 118 | 119 | } 120 | } -------------------------------------------------------------------------------- /src/View/Components/Alert.php: -------------------------------------------------------------------------------- 1 | classBuilder( 31 | 'alert', 32 | $variant, 33 | [ 34 | 'accent' => $accent, 35 | 'border' => $border, 36 | 'hollow' => $hollow, 37 | 'ring' => $ring, 38 | 'rounded' => $rounded, 39 | 'shadow' => $shadow, 40 | 'size' => $size, 41 | ], 42 | $theme, 43 | ); 44 | 45 | $this->classes = $classes; 46 | 47 | $elementClasses = $turbine->elementClasses( 48 | 'alert', 49 | [ 50 | 'content', 51 | 'dismissButton', 52 | 'dismissIcon', 53 | 'title', 54 | ], 55 | $size, 56 | ); 57 | 58 | foreach ($elementClasses as $key => $value) { 59 | $this->$key = $value; 60 | } 61 | } 62 | 63 | public function render() 64 | { 65 | return view('turbine-ui::components.alert'); 66 | } 67 | } -------------------------------------------------------------------------------- /src/View/Components/Avatar.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'avatar', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'ring' => $ring, 33 | 'rounded' => $rounded, 34 | 'shadow' => $shadow, 35 | 'size' => $size, 36 | ], 37 | $theme, 38 | ); 39 | 40 | $this->classes = $classes; 41 | 42 | $elementClasses = $turbine->elementClasses( 43 | 'avatar', 44 | [ 45 | 'label', 46 | ], 47 | $size, 48 | ); 49 | 50 | foreach ($elementClasses as $key => $value) { 51 | $this->$key = $value; 52 | } 53 | } 54 | 55 | public function render() 56 | { 57 | return view('turbine-ui::components.avatar'); 58 | } 59 | } -------------------------------------------------------------------------------- /src/View/Components/Badge.php: -------------------------------------------------------------------------------- 1 | classBuilder( 31 | 'badge', 32 | $variant, 33 | [ 34 | 'accent' => $accent, 35 | 'border' => $border, 36 | 'hollow' => $hollow, 37 | 'icon' => $icon, 38 | 'prefix' => $prefix, 39 | 'ring' => $ring, 40 | 'rounded' => $rounded, 41 | 'shadow' => $shadow, 42 | 'size' => $size, 43 | 'suffix' => $suffix, 44 | ], 45 | $theme, 46 | ); 47 | 48 | $this->classes = $classes; 49 | 50 | $elementClasses = $turbine->elementClasses( 51 | 'badge', 52 | [ 53 | 'content', 54 | 'icon', 55 | 'prefix', 56 | 'suffix', 57 | ], 58 | $size, 59 | ); 60 | 61 | foreach ($elementClasses as $key => $value) { 62 | $this->$key = $value; 63 | } 64 | } 65 | 66 | public function render() 67 | { 68 | return view('turbine-ui::components.badge'); 69 | } 70 | } -------------------------------------------------------------------------------- /src/View/Components/Burger.php: -------------------------------------------------------------------------------- 1 | classBuilder( 18 | 'burger', 19 | $variant, 20 | [ 21 | 22 | ], 23 | $theme, 24 | ); 25 | 26 | $this->classes = $classes; 27 | 28 | $elementClasses = $turbine->elementClasses( 29 | 'burger', 30 | [ 31 | 'bar', 32 | ], 33 | null, 34 | ); 35 | 36 | foreach ($elementClasses as $key => $value) { 37 | $this->$key = $value; 38 | } 39 | } 40 | 41 | public function render() 42 | { 43 | return view('turbine-ui::components.burger'); 44 | } 45 | } -------------------------------------------------------------------------------- /src/View/Components/Button.php: -------------------------------------------------------------------------------- 1 | classBuilder( 38 | 'button', 39 | $variant, 40 | [ 41 | 'accent' => $accent, 42 | 'active' => $active, 43 | 'animate' => $animate, 44 | 'border' => $border, 45 | 'divide' => $divide, 46 | 'full' => $full, 47 | 'gradient' => $gradient, 48 | 'hollow' => $hollow, 49 | 'hover' => $hover, 50 | 'link' => $link, 51 | 'ring' => $ring, 52 | 'rounded' => $rounded, 53 | 'shadow' => $shadow, 54 | 'size' => $size, 55 | ], 56 | $theme, 57 | ); 58 | 59 | $this->classes = $classes; 60 | 61 | $elementClasses = $turbine->elementClasses( 62 | 'button', 63 | [ 64 | 'content', 65 | 'prefix', 66 | 'suffix', 67 | ], 68 | $size, 69 | ); 70 | 71 | if (!$divide) { 72 | if (isset($prefix)) { 73 | $elementClasses['contentClasses'] .= ' pl-0'; 74 | $elementClasses['prefixClasses'] .= ' pr-0'; 75 | } 76 | 77 | if (isset($suffix)) { 78 | $elementClasses['contentClasses'] .= ' pr-0'; 79 | $elementClasses['suffixClasses'] .= ' pl-0'; 80 | } 81 | } else { 82 | $this->classes .= ' gap-0'; 83 | } 84 | 85 | foreach ($elementClasses as $key => $value) { 86 | $this->$key = $value; 87 | } 88 | } 89 | 90 | public function render() 91 | { 92 | return view('turbine-ui::components.button'); 93 | } 94 | } -------------------------------------------------------------------------------- /src/View/Components/ButtonGroup.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'button-group', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'divide' => $divide, 33 | 'full' => $full, 34 | 'hollow' => $hollow, 35 | 'hover' => $hover, 36 | 'ring' => $ring, 37 | 'rounded' => $rounded, 38 | 'shadow' => $shadow, 39 | ], 40 | $theme, 41 | ); 42 | 43 | $this->classes = $classes; 44 | } 45 | 46 | public function render() 47 | { 48 | return view('turbine-ui::components.button-group'); 49 | } 50 | } -------------------------------------------------------------------------------- /src/View/Components/Card.php: -------------------------------------------------------------------------------- 1 | classBuilder( 28 | 'card', 29 | $variant, 30 | [ 31 | 'accent' => $accent, 32 | 'border' => $border, 33 | 'divide' => $divide, 34 | 'hollow' => $hollow, 35 | 'ring' => $ring, 36 | 'rounded' => $rounded, 37 | 'shadow' => $shadow, 38 | 'size' => $size, 39 | ], 40 | $theme, 41 | ); 42 | 43 | $this->classes = $classes; 44 | 45 | $elementClasses = $turbine->elementClasses( 46 | 'card', 47 | [ 48 | 'body', 49 | 'footer', 50 | 'header', 51 | ], 52 | $size, 53 | ); 54 | 55 | foreach ($elementClasses as $key => $value) { 56 | $this->$key = $value; 57 | } 58 | } 59 | 60 | public function render() 61 | { 62 | return view('turbine-ui::components.card'); 63 | } 64 | } -------------------------------------------------------------------------------- /src/View/Components/Code.php: -------------------------------------------------------------------------------- 1 | classBuilder( 25 | 'code', 26 | $variant, 27 | [ 28 | 'accent' => $accent, 29 | 'border' => $border, 30 | 'hollow' => $hollow, 31 | 'ring' => $ring, 32 | 'rounded' => $rounded, 33 | 'shadow' => $shadow, 34 | 'size' => $size, 35 | ], 36 | $theme, 37 | ); 38 | 39 | $this->classes = $classes; 40 | } 41 | 42 | public function render() 43 | { 44 | return view('turbine-ui::components.code'); 45 | } 46 | } -------------------------------------------------------------------------------- /src/View/Components/Container.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'container', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'gradient' => $gradient, 33 | 'grid' => $grid, 34 | 'hollow' => $hollow, 35 | 'ring' => $ring, 36 | 'rounded' => $rounded, 37 | 'shadow' => $shadow, 38 | 'size' => $size, 39 | ], 40 | $theme, 41 | ); 42 | 43 | $this->classes = $classes; 44 | } 45 | 46 | public function render() 47 | { 48 | return view('turbine-ui::components.container'); 49 | } 50 | } -------------------------------------------------------------------------------- /src/View/Components/Dropdown.php: -------------------------------------------------------------------------------- 1 | classBuilder( 23 | 'dropdown', 24 | $variant, 25 | [ 26 | 'accent' => $accent, 27 | 'border' => $border, 28 | 'ring' => $ring, 29 | 'rounded' => $rounded, 30 | 'shadow' => $shadow, 31 | 'size' => $size, 32 | ], 33 | $theme, 34 | ); 35 | 36 | $this->classes = $classes; 37 | } 38 | 39 | public function render() 40 | { 41 | return view('turbine-ui::components.dropdown'); 42 | } 43 | } -------------------------------------------------------------------------------- /src/View/Components/Faq.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'faq', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'hollow' => $hollow, 33 | 'ring' => $ring, 34 | 'rounded' => $rounded, 35 | 'shadow' => $shadow, 36 | 'size' => $size, 37 | ], 38 | $theme, 39 | ); 40 | 41 | $this->classes = $classes; 42 | 43 | $elementClasses = $turbine->elementClasses( 44 | 'faq', 45 | [ 46 | 'answer', 47 | 'expandIcon', 48 | 'question', 49 | ], 50 | $size, 51 | ); 52 | 53 | foreach ($elementClasses as $key => $value) { 54 | $this->$key = $value; 55 | } 56 | } 57 | 58 | public function render() 59 | { 60 | return view('turbine-ui::components.faq'); 61 | } 62 | } -------------------------------------------------------------------------------- /src/View/Components/Grid.php: -------------------------------------------------------------------------------- 1 | classBuilder( 20 | 'grid', 21 | $variant, 22 | [ 23 | 'cols' => $cols, 24 | 'gap' => $gap, 25 | 'rows' => $rows, 26 | ], 27 | $theme, 28 | ); 29 | 30 | $this->classes = $classes; 31 | } 32 | 33 | public function render() 34 | { 35 | return view('turbine-ui::components.grid'); 36 | } 37 | } -------------------------------------------------------------------------------- /src/View/Components/Heading.php: -------------------------------------------------------------------------------- 1 | classBuilder( 23 | 'heading', 24 | $variant, 25 | [ 26 | 'balance' => $balance, 27 | 'level' => $level, 28 | 'pretty' => $pretty, 29 | 'size' => $size, 30 | ], 31 | $theme, 32 | ); 33 | 34 | $this->classes = $classes; 35 | 36 | $this->heading = match ($this->level) { 37 | '1' => 'h1', 38 | '2' => 'h2', 39 | '3' => 'h3', 40 | '4' => 'h4', 41 | '5' => 'h5', 42 | '6' => 'h6', 43 | default => 'h3', 44 | }; 45 | } 46 | 47 | public function render() 48 | { 49 | return view('turbine-ui::components.heading'); 50 | } 51 | } -------------------------------------------------------------------------------- /src/View/Components/Input.php: -------------------------------------------------------------------------------- 1 | classBuilder( 47 | 'input', 48 | $variant, 49 | [ 50 | 'accent' => $accent, 51 | 'border' => $border, 52 | 'divide' => $divide, 53 | 'full' => $full, 54 | 'hollow' => $hollow, 55 | 'label' => $label, 56 | 'prefix' => $prefix, 57 | 'ring' => $ring, 58 | 'rounded' => $rounded, 59 | 'shadow' => $shadow, 60 | 'size' => $size, 61 | 'suffix' => $suffix, 62 | 'type' => $type, 63 | ], 64 | $theme, 65 | ); 66 | 67 | $this->classes = $classes; 68 | 69 | $elementClasses = $turbine->elementClasses( 70 | 'input', 71 | [ 72 | 'hint', 73 | 'input', 74 | 'inputWrapper', 75 | 'inputCheckbox', 76 | 'inputCheckboxWrapper', 77 | 'inputCheckboxLabel', 78 | 'inputRange', 79 | 'inputRangeWrapper', 80 | 'inputRangeLabel', 81 | 'inputRadio', 82 | 'inputRadioWrapper', 83 | 'inputRadioLabel', 84 | 'label', 85 | 'prefix', 86 | 'suffix', 87 | ], 88 | $size, 89 | ); 90 | 91 | foreach ($elementClasses as $key => $value) { 92 | $this->$key = $value; 93 | } 94 | } 95 | 96 | public function render() 97 | { 98 | return view('turbine-ui::components.input'); 99 | } 100 | } -------------------------------------------------------------------------------- /src/View/Components/InputGroup.php: -------------------------------------------------------------------------------- 1 | classBuilder( 29 | 'input-group', 30 | $variant, 31 | [ 32 | 'accent' => $accent, 33 | 'border' => $border, 34 | 'cols' => $cols, 35 | 'gap' => $gap, 36 | 'gradient' => $gradient, 37 | 'hollow' => $hollow, 38 | 'ring' => $ring, 39 | 'rounded' => $rounded, 40 | 'rows' => $rows, 41 | 'shadow' => $shadow, 42 | 'size' => $size, 43 | ], 44 | $theme, 45 | ); 46 | 47 | $this->classes = $classes; 48 | } 49 | 50 | public function render() 51 | { 52 | return view('turbine-ui::components.input-group'); 53 | } 54 | } -------------------------------------------------------------------------------- /src/View/Components/Label.php: -------------------------------------------------------------------------------- 1 | classBuilder( 33 | 'label', 34 | $variant, 35 | [ 36 | 'accent' => $accent, 37 | 'border' => $border, 38 | 'hollow' => $hollow, 39 | 'icon' => $icon, 40 | 'prefix' => $prefix, 41 | 'ring' => $ring, 42 | 'rounded' => $rounded, 43 | 'shadow' => $shadow, 44 | 'size' => $size, 45 | 'suffix' => $suffix, 46 | ], 47 | $theme, 48 | ); 49 | 50 | $this->classes = $classes; 51 | 52 | $elementClasses = $turbine->elementClasses( 53 | 'label', 54 | [ 55 | 'content', 56 | 'hint', 57 | 'icon', 58 | 'prefix', 59 | 'suffix', 60 | ], 61 | $size, 62 | ); 63 | 64 | foreach ($elementClasses as $key => $value) { 65 | $this->$key = $value; 66 | } 67 | } 68 | 69 | public function render() 70 | { 71 | return view('turbine-ui::components.label'); 72 | } 73 | } -------------------------------------------------------------------------------- /src/View/Components/Link.php: -------------------------------------------------------------------------------- 1 | classBuilder( 34 | 'link', 35 | $variant, 36 | [ 37 | 'accent' => $accent, 38 | 'active' => $active, 39 | 'border' => $border, 40 | 'divide' => $divide, 41 | 'gradient' => $gradient, 42 | 'hollow' => $hollow, 43 | 'hover' => $hover, 44 | 'ring' => $ring, 45 | 'rounded' => $rounded, 46 | 'shadow' => $shadow, 47 | 'size' => $size, 48 | ], 49 | $theme, 50 | ); 51 | 52 | $this->classes = $classes; 53 | 54 | $elementClasses = $turbine->elementClasses( 55 | 'link', 56 | [ 57 | 'content', 58 | 'prefix', 59 | 'suffix', 60 | ], 61 | $size, 62 | ); 63 | 64 | foreach ($elementClasses as $key => $value) { 65 | $this->$key = $value; 66 | } 67 | } 68 | 69 | public function render() 70 | { 71 | return view('turbine-ui::components.link'); 72 | } 73 | } -------------------------------------------------------------------------------- /src/View/Components/ListGroup.php: -------------------------------------------------------------------------------- 1 | classBuilder( 24 | 'list-group', 25 | $variant, 26 | [ 27 | 'accent' => $accent, 28 | 'border' => $border, 29 | 'divide' => $divide, 30 | 'hollow' => $hollow, 31 | 'ring' => $ring, 32 | 'rounded' => $rounded, 33 | 'shadow' => $shadow, 34 | ], 35 | $theme, 36 | ); 37 | 38 | $this->classes = $classes; 39 | } 40 | 41 | public function render() 42 | { 43 | return view('turbine-ui::components.list-group'); 44 | } 45 | } -------------------------------------------------------------------------------- /src/View/Components/Media.php: -------------------------------------------------------------------------------- 1 | classBuilder( 29 | 'media', 30 | $variant, 31 | [ 32 | 'accent' => $accent, 33 | 'border' => $border, 34 | 'full' => $full, 35 | 'hollow' => $hollow, 36 | 'ring' => $ring, 37 | 'rounded' => $rounded, 38 | 'shadow' => $shadow, 39 | 'size' => $size, 40 | ], 41 | $theme, 42 | ); 43 | 44 | $this->classes = $classes; 45 | 46 | $elementClasses = $turbine->elementClasses( 47 | 'media', 48 | [ 49 | 'body', 50 | 'thumbnail', 51 | 'title', 52 | 'description', 53 | ], 54 | $size, 55 | ); 56 | 57 | foreach ($elementClasses as $key => $value) { 58 | $this->$key = $value; 59 | } 60 | } 61 | 62 | public function render() 63 | { 64 | return view('turbine-ui::components.media'); 65 | } 66 | } -------------------------------------------------------------------------------- /src/View/Components/Menu.php: -------------------------------------------------------------------------------- 1 | classBuilder( 25 | 'menu', 26 | $variant, 27 | [ 28 | 'accent' => $accent, 29 | 'border' => $border, 30 | 'divide' => $divide, 31 | 'hollow' => $hollow, 32 | 'ring' => $ring, 33 | 'rounded' => $rounded, 34 | 'shadow' => $shadow, 35 | 'size' => $size, 36 | ], 37 | $theme, 38 | ); 39 | 40 | $this->classes = $classes; 41 | } 42 | 43 | public function render() 44 | { 45 | return view('turbine-ui::components.menu'); 46 | } 47 | } -------------------------------------------------------------------------------- /src/View/Components/Modal.php: -------------------------------------------------------------------------------- 1 | target = $target; 24 | 25 | $classes = $turbine->classBuilder( 26 | 'modal', 27 | $variant, 28 | [ 29 | 'size' => $size, 30 | ], 31 | $theme, 32 | ); 33 | 34 | $this->classes = $classes; 35 | 36 | $elementClasses = $turbine->elementClasses( 37 | 'modal', 38 | [ 39 | 'backdrop', 40 | 'content', 41 | 'dismissButton', 42 | 'dismissIcon', 43 | ], 44 | $size, 45 | ); 46 | 47 | foreach ($elementClasses as $key => $value) { 48 | $this->$key = $value; 49 | } 50 | } 51 | 52 | public function render() 53 | { 54 | return view('turbine-ui::components.modal'); 55 | } 56 | } -------------------------------------------------------------------------------- /src/View/Components/NavLink.php: -------------------------------------------------------------------------------- 1 | classBuilder( 35 | 'nav-link', 36 | $variant, 37 | [ 38 | 'accent' => $accent, 39 | 'active' => $active, 40 | 'animate' => $animate, 41 | 'border' => $border, 42 | 'divide' => $divide, 43 | 'gradient' => $gradient, 44 | 'hollow' => $hollow, 45 | 'hover' => $hover, 46 | 'ring' => $ring, 47 | 'rounded' => $rounded, 48 | 'shadow' => $shadow, 49 | 'size' => $size, 50 | ], 51 | $theme, 52 | ); 53 | 54 | $this->classes = $classes; 55 | 56 | $elementClasses = $turbine->elementClasses( 57 | 'nav-link', 58 | [ 59 | 'content', 60 | 'prefix', 61 | 'suffix', 62 | ], 63 | $size, 64 | ); 65 | 66 | if (!$divide) { 67 | if (isset($prefix)) { 68 | $elementClasses['contentClasses'] .= ' pl-0'; 69 | $elementClasses['prefixClasses'] .= ' pr-0'; 70 | } 71 | 72 | if (isset($suffix)) { 73 | $elementClasses['contentClasses'] .= ' pr-0'; 74 | $elementClasses['suffixClasses'] .= ' pl-0'; 75 | } 76 | } else { 77 | $this->classes .= ' gap-0'; 78 | } 79 | 80 | foreach ($elementClasses as $key => $value) { 81 | $this->$key = $value; 82 | } 83 | } 84 | 85 | public function render() 86 | { 87 | return view('turbine-ui::components.nav-link'); 88 | } 89 | } -------------------------------------------------------------------------------- /src/View/Components/Navbar.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'navbar', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'divide' => $divide, 33 | 'hollow' => $hollow, 34 | 'ring' => $ring, 35 | 'rounded' => $rounded, 36 | 'shadow' => $shadow, 37 | 'size' => $size, 38 | ], 39 | $theme, 40 | ); 41 | 42 | $this->classes = $classes; 43 | 44 | $elementClasses = $turbine->elementClasses( 45 | 'navbar', 46 | [ 47 | 'brand', 48 | 'content', 49 | ], 50 | $size, 51 | ); 52 | 53 | foreach ($elementClasses as $key => $value) { 54 | $this->$key = $value; 55 | } 56 | } 57 | 58 | public function render() 59 | { 60 | return view('turbine-ui::components.navbar'); 61 | } 62 | } -------------------------------------------------------------------------------- /src/View/Components/Progress.php: -------------------------------------------------------------------------------- 1 | classBuilder( 32 | 'progress', 33 | $variant, 34 | [ 35 | 'accent' => $accent, 36 | 'border' => $border, 37 | 'gradient' => $gradient, 38 | 'ring' => $ring, 39 | 'rounded' => $rounded, 40 | 'shadow' => $shadow, 41 | 'size' => $size, 42 | ], 43 | $theme, 44 | ); 45 | 46 | $this->classes = $classes; 47 | 48 | $elementClasses = $turbine->elementClasses( 49 | 'progress', 50 | [ 51 | 'bar', 52 | 'label', 53 | 'percentage', 54 | 'progress', 55 | 'progressWrapper', 56 | 'textWrapper', 57 | ], 58 | $size, 59 | ); 60 | 61 | foreach ($elementClasses as $key => $value) { 62 | $this->$key = $value; 63 | } 64 | } 65 | 66 | public function render() 67 | { 68 | return view('turbine-ui::components.progress'); 69 | } 70 | } -------------------------------------------------------------------------------- /src/View/Components/Section.php: -------------------------------------------------------------------------------- 1 | classBuilder( 20 | 'section', 21 | $variant, 22 | [ 23 | 'full' => $full, 24 | 'gradient' => $gradient, 25 | 'size' => $size, 26 | ], 27 | $theme, 28 | ); 29 | 30 | $this->classes = $classes; 31 | } 32 | 33 | public function render() 34 | { 35 | return view('turbine-ui::components.section'); 36 | } 37 | } -------------------------------------------------------------------------------- /src/View/Components/Select.php: -------------------------------------------------------------------------------- 1 | classBuilder( 35 | 'select', 36 | $variant, 37 | [ 38 | 'accent' => $accent, 39 | 'border' => $border, 40 | 'divide' => $divide, 41 | 'hollow' => $hollow, 42 | 'label' => $label, 43 | 'prefix' => $prefix, 44 | 'ring' => $ring, 45 | 'rounded' => $rounded, 46 | 'shadow' => $shadow, 47 | 'size' => $size, 48 | 'suffix' => $suffix, 49 | ], 50 | $theme, 51 | ); 52 | 53 | $this->classes = $classes; 54 | 55 | $elementClasses = $turbine->elementClasses( 56 | 'select', 57 | [ 58 | 'hint', 59 | 'label', 60 | 'prefix', 61 | 'select', 62 | 'selectWrapper', 63 | 'suffix', 64 | ], 65 | $size, 66 | ); 67 | 68 | foreach ($elementClasses as $key => $value) { 69 | $this->$key = $value; 70 | } 71 | } 72 | 73 | public function render() 74 | { 75 | return view('turbine-ui::components.select'); 76 | } 77 | } -------------------------------------------------------------------------------- /src/View/Components/Sidebar.php: -------------------------------------------------------------------------------- 1 | classBuilder( 27 | 'sidebar', 28 | $variant, 29 | [ 30 | 'accent' => $accent, 31 | 'border' => $border, 32 | 'hollow' => $hollow, 33 | 'ring' => $ring, 34 | 'rounded' => $rounded, 35 | 'shadow' => $shadow, 36 | 'size' => $size, 37 | ], 38 | $theme, 39 | ); 40 | 41 | $this->classes = $classes; 42 | 43 | $elementClasses = $turbine->elementClasses( 44 | 'modal', 45 | [ 46 | 'dismissButton', 47 | 'dismissIcon', 48 | ], 49 | $size, 50 | ); 51 | 52 | foreach ($elementClasses as $key => $value) { 53 | $this->$key = $value; 54 | } 55 | } 56 | 57 | public function render() 58 | { 59 | return view('turbine-ui::components.sidebar'); 60 | } 61 | } -------------------------------------------------------------------------------- /src/View/Components/Stat.php: -------------------------------------------------------------------------------- 1 | classBuilder( 30 | 'stat', 31 | $variant, 32 | [ 33 | 'accent' => $accent, 34 | 'border' => $border, 35 | 'divide' => $divide, 36 | 'hollow' => $hollow, 37 | 'ring' => $ring, 38 | 'rounded' => $rounded, 39 | 'shadow' => $shadow, 40 | 'size' => $size, 41 | ], 42 | $theme, 43 | ); 44 | 45 | $this->classes = $classes; 46 | 47 | $elementClasses = $turbine->elementClasses( 48 | 'stat', 49 | [ 50 | 'description', 51 | 'icon', 52 | 'title', 53 | 'value', 54 | ], 55 | $size, 56 | ); 57 | 58 | foreach ($elementClasses as $key => $value) { 59 | $this->$key = $value; 60 | } 61 | } 62 | 63 | public function render() 64 | { 65 | return view('turbine-ui::components.stat'); 66 | } 67 | } -------------------------------------------------------------------------------- /src/View/Components/Table.php: -------------------------------------------------------------------------------- 1 | classBuilder( 29 | 'table', 30 | $variant, 31 | [ 32 | 'accent' => $accent, 33 | 'border' => $border, 34 | 'divide' => $divide, 35 | 'hollow' => $hollow, 36 | 'ring' => $ring, 37 | 'rounded' => $rounded, 38 | 'shadow' => $shadow, 39 | 'size' => $size, 40 | 'striped' => $striped, 41 | ], 42 | $theme, 43 | ); 44 | 45 | $this->classes = $classes; 46 | 47 | $elementClasses = $turbine->elementClasses( 48 | 'table', 49 | [ 50 | 'tbody', 51 | 'tfoot', 52 | 'thead', 53 | ], 54 | $size, 55 | ); 56 | 57 | foreach ($elementClasses as $key => $value) { 58 | $this->$key = $value; 59 | } 60 | } 61 | 62 | public function render() 63 | { 64 | return view('turbine-ui::components.table'); 65 | } 66 | } -------------------------------------------------------------------------------- /src/View/Components/Text.php: -------------------------------------------------------------------------------- 1 | classBuilder( 21 | 'text', 22 | $variant, 23 | [ 24 | 'balance' => $balance, 25 | 'level' => $level, 26 | 'pretty' => $pretty, 27 | 'size' => $size, 28 | ], 29 | $theme, 30 | ); 31 | 32 | $this->classes = $classes; 33 | } 34 | 35 | public function render() 36 | { 37 | return view('turbine-ui::components.text'); 38 | } 39 | } -------------------------------------------------------------------------------- /src/View/Components/Textarea.php: -------------------------------------------------------------------------------- 1 | classBuilder( 31 | 'textarea', 32 | $variant, 33 | [ 34 | 'accent' => $accent, 35 | 'border' => $border, 36 | 'hollow' => $hollow, 37 | 'ring' => $ring, 38 | 'rounded' => $rounded, 39 | 'shadow' => $shadow, 40 | 'size' => $size, 41 | 'label' => $label, 42 | 'divide' => $divide, 43 | ], 44 | $theme, 45 | ); 46 | 47 | $this->classes = $classes; 48 | 49 | $elementClasses = $turbine->elementClasses( 50 | 'textarea', 51 | [ 52 | 'footer', 53 | 'header', 54 | 'label', 55 | 'textarea', 56 | 'textareaWrapper', 57 | ], 58 | $size, 59 | ); 60 | 61 | foreach ($elementClasses as $key => $value) { 62 | $this->$key = $value; 63 | } 64 | } 65 | 66 | public function render() 67 | { 68 | return view('turbine-ui::components.textarea'); 69 | } 70 | } -------------------------------------------------------------------------------- /src/View/Components/ThemeSwitcher.php: -------------------------------------------------------------------------------- 1 | classBuilder( 23 | 'theme-switcher', 24 | $variant, 25 | [ 26 | 'size' => $size, 27 | ], 28 | $theme, 29 | ); 30 | 31 | $this->classes = $classes; 32 | 33 | $elementClasses = $turbine->elementClasses( 34 | 'theme-switcher', 35 | [ 36 | 'darkButton', 37 | 'lightButton', 38 | 'listGroup', 39 | 'switchButton', 40 | 'systemButton', 41 | ], 42 | null 43 | ); 44 | 45 | foreach ($elementClasses as $key => $value) { 46 | $this->$key = $value; 47 | } 48 | } 49 | 50 | public function render() 51 | { 52 | return view('turbine-ui::components.theme-switcher'); 53 | } 54 | } -------------------------------------------------------------------------------- /src/View/Components/Toast.php: -------------------------------------------------------------------------------- 1 | classBuilder( 33 | 'toast', 34 | $variant, 35 | [ 36 | 'size' => $size, 37 | 'accent' => $accent, 38 | 'border' => $border, 39 | 'hollow' => $hollow, 40 | 'ring' => $ring, 41 | 'rounded' => $rounded, 42 | 'shadow' => $shadow, 43 | ], 44 | $theme, 45 | ); 46 | 47 | $this->classes = $classes; 48 | 49 | $elementClasses = $turbine->elementClasses( 50 | 'toast', 51 | [ 52 | 'content', 53 | 'dismissButton', 54 | 'dismissIcon', 55 | 'title', 56 | 'toast', 57 | ], 58 | $size, 59 | ); 60 | 61 | foreach ($elementClasses as $key => $value) { 62 | $this->$key = $value; 63 | } 64 | } 65 | 66 | public function render() 67 | { 68 | return view('turbine-ui::components.toast'); 69 | } 70 | } -------------------------------------------------------------------------------- /src/View/Components/Toggle.php: -------------------------------------------------------------------------------- 1 | classBuilder( 25 | 'toggle', 26 | $variant, 27 | [ 28 | 'size' => $size, 29 | 'border' => $border, 30 | 'ring' => $ring, 31 | 'rounded' => $rounded, 32 | 'shadow' => $shadow, 33 | 'label' => $label, 34 | ], 35 | $theme, 36 | ); 37 | 38 | $this->classes = $classes; 39 | 40 | $elementClasses = $turbine->elementClasses( 41 | 'toggle', 42 | [ 43 | 'input', 44 | 'label', 45 | ], 46 | $size, 47 | ); 48 | 49 | foreach ($elementClasses as $key => $value) { 50 | $this->$key = $value; 51 | } 52 | } 53 | 54 | public function render() 55 | { 56 | return view('turbine-ui::components.toggle'); 57 | } 58 | } --------------------------------------------------------------------------------