Skip to content

Commit

Permalink
Merge pull request #10 from Kamona-WD/react-stack
Browse files Browse the repository at this point in the history
add react stack
  • Loading branch information
Kamona-WD authored Feb 11, 2022
2 parents dc76206 + 279af31 commit e0490b6
Show file tree
Hide file tree
Showing 39 changed files with 2,402 additions and 10 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Different UI for [larave/breeze](https://github.com/laravel/breeze).
[![Total Downloads](https://img.shields.io/packagist/dt/kamona/kui-laravel-breeze.svg)](https://packagist.org/packages/kamona/kui-laravel-breeze)

#### [Figma file](https://www.figma.com/community/file/1019844542917981418/)

#### [Jetstream Version](https://github.com/Kamona-WD/kui-laravel-jetstream)

#### Note
Expand Down Expand Up @@ -35,8 +36,8 @@ composer require kamona/kui-laravel-breeze --dev
# after finish run this command

php artisan kui-breeze:replace blade
# available stacks (blade,vue). react will be added soon.
# So if you run `php artisan breeze:install vue` you can run `php artisan kui-breeze:replace vue`
# available stacks (blade,vue,react).
# So if you run `php artisan breeze:install vue` you can run `php artisan kui-breeze:replace vue` and the same for react.

# then
npm install && npm run dev # or yarn && yarn dev
Expand All @@ -52,6 +53,7 @@ You will found sidebar links in:

- blade: `resources/views/components/sidebar/content.blade.php`.
- vue: `resources/js/Components/Sidebar/SidebarContent.vue`
- react: `resources/js/Components/Sidebar/SidebarContent.jsx`

#### Screens

Expand Down
56 changes: 55 additions & 1 deletion src/Console/ReplaceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public function __construct()
*/
public function handle()
{
$this->writeLogo();

if ($this->argument('stack') === 'blade') {
return $this->replaceBlade();
}
Expand Down Expand Up @@ -147,7 +149,45 @@ protected function replaceVue()

protected function replaceReact()
{
$this->warn('React stack will be avilable soon.');
// NPM Packages...
$this->updateNodePackages(function ($packages) {
return [
'@headlessui/react' => '^1.4.2',
'@heroicons/react' => '^1.0.5',
'@tailwindcss/forms' => '^0.4.0',
'autoprefixer' => '^10.3.7',
'postcss' => '^8.3.9',
'postcss-import' => '^14.0.2',
'tailwindcss' => '^3.0.7',
'react-transition-group' => '^4.4.2',
'perfect-scrollbar' => '^1.5.5'
] + $packages;
});

// Favicon
$this->replaceFavIcon();

// Views...
copy(__DIR__ . '/../../stubs/vue/views/app.blade.php', resource_path('views/app.blade.php'));

// Components + Pages...
(new Filesystem)->ensureDirectoryExists(resource_path('js/Components'));
(new Filesystem)->ensureDirectoryExists(resource_path('js/Hooks'));
(new Filesystem)->ensureDirectoryExists(resource_path('js/Layouts'));
(new Filesystem)->ensureDirectoryExists(resource_path('js/Pages'));

(new Filesystem)->copyDirectory(__DIR__ . '/../../stubs/react/js/Components', resource_path('js/Components'));
(new Filesystem)->copyDirectory(__DIR__ . '/../../stubs/react/js/Hooks', resource_path('js/Hooks'));
(new Filesystem)->copyDirectory(__DIR__ . '/../../stubs/react/js/Layouts', resource_path('js/Layouts'));
(new Filesystem)->copyDirectory(__DIR__ . '/../../stubs/react/js/Pages', resource_path('js/Pages'));

// Tailwind / Webpack...
copy(__DIR__ . '/../../stubs/react/tailwind.config.js', base_path('tailwind.config.js'));
copy(__DIR__ . '/../../stubs/react/css/app.css', resource_path('css/app.css'));
copy(__DIR__ . '/../../stubs/react/js/app.js', resource_path('js/app.js'));

$this->info('Breeze scaffolding replaced successfully.');
$this->comment('Please execute the "npm install && npm run dev" command to build your assets.');
}

protected function replaceFavIcon()
Expand Down Expand Up @@ -243,4 +283,18 @@ protected function replaceInFile($search, $replace, $path)
{
file_put_contents($path, str_replace($search, $replace, file_get_contents($path)));
}

protected function writeLogo()
{
$logo = PHP_EOL . '<fg=bright-blue>
██╗ ██╗ ██╗ ██╗██╗
██║ ██╔╝ ██║ ██║██║
█████╔╝█████╗██║ ██║██║
██╔═██╗╚════╝██║ ██║██║
██║ ██╗ ╚██████╔╝██║
╚═╝ ╚═╝ ╚═════╝ ╚═╝
</>' . PHP_EOL;

return $this->line($logo);
}
}
9 changes: 9 additions & 0 deletions stubs/react/css/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'perfect-scrollbar/css/perfect-scrollbar.css';
@import 'tailwindcss/utilities';

.dark .ps__rail-y,
.dark .ps__rail-x {
background-color: transparent !important;
}
15 changes: 15 additions & 0 deletions stubs/react/js/Components/ApplicationLogo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default (props) => {
return (
<svg
{...props}
viewBox="0 0 40 40"
fill="#A855F7"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M20 3L40 8L39.5207 9.91704L20 5.03685L0.479258 9.91704L0 8L20 3Z" />
<path d="M20 37.1475L40 32.1475L39.5207 30.2304L20 35.1106L0.479258 30.2304L0 32.1475L20 37.1475Z" />
<path d="M1.16589 11.7373L5.17972 10.8111V18.1675L11.9723 10.1935L11.3548 8.95852L15.6774 8.03225L13.8249 9.88479V11.1198L6.7235 19.4562L15.0599 30.8802L16.6037 32.1152L15.9862 32.424L12.8986 31.1889L5.17972 21.095V28.4101L7.34101 29.9539L1.16589 28.4101L3.32718 27.4839V13.2811L1.16589 11.7373Z" />
<path d="M16.9124 7.7235L20 7.10598L22.47 7.7235L20.9263 9.26727C20.9263 9.26727 20.7204 27.4839 20.9263 28.1014C21.1321 28.7189 21.729 30.0774 22.47 30.5714C23.3963 31.1889 27.9489 31.2883 29.1729 28.8823C29.556 28.1293 29.5872 27.9014 29.7171 26.9514C29.7393 26.7894 29.7643 26.6064 29.7945 26.3962C29.8955 25.6912 29.8895 24.8909 29.8832 24.0704C29.8817 23.8711 29.8802 23.6706 29.8802 23.47V12.3548L28.0277 9.57603V9.26727L38.8341 11.4286V12.3548L37.2903 12.9723V26.8664L38.8341 28.1014L34.2028 29.3725L35.4378 27.4839V12.9723L33.2765 11.4286L31.424 12.9723L31.1152 25.0138C31.1152 25.8618 31.017 27.1791 30.7193 28.3251C30.6106 28.7435 30.1101 29.5467 30.1101 29.5467C30.1101 29.5467 29.6731 30.2533 29.2627 30.5714C28.8853 30.8639 28.1871 31.1541 28.1871 31.1541C28.1871 31.1541 26.0347 32.0258 24.0721 32.4043C23.08 32.5957 22.1571 32.4413 21.5645 32.2043C21.541 32.1912 21.5168 32.1778 21.492 32.1641C20.9896 31.8865 20.243 31.4739 19.6681 30.5714C19.1558 29.767 18.765 28.7318 18.765 27.4839V9.57603L16.9124 7.7235Z" />
</svg>
);
};
88 changes: 88 additions & 0 deletions stubs/react/js/Components/Button.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Link } from '@inertiajs/inertia-react';

export default ({
type = 'submit',
className = '',
processing,
children,
href,
target,
external,
variant = 'primary',
size = 'base',
iconOnly,
squared = false,
pill = false,
srText,
onClick,
}) => {
const baseClasses = `inline-flex items-center transition-colors font-medium select-none disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-dark-eval-2`;

let variantClasses = ``;

switch (variant) {
case 'secondary':
variantClasses = `bg-white text-gray-500 hover:bg-gray-100 focus:ring-purple-500 dark:text-gray-400 dark:bg-dark-eval-1 dark:hover:bg-dark-eval-2 dark:hover:text-gray-200`;
break;
case 'success':
variantClasses = `bg-green-500 text-white hover:bg-green-600 focus:ring-green-500`;
break;
case 'danger':
variantClasses = `bg-red-500 text-white hover:bg-red-600 focus:ring-red-500`;
break;
case 'warning':
variantClasses = `bg-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500`;
break;
case 'info':
variantClasses = `bg-cyan-500 text-white hover:bg-cyan-600 focus:ring-cyan-500`;
break;
case 'black':
variantClasses = `bg-black text-gray-300 hover:text-white hover:bg-gray-800 focus:ring-black dark:hover:bg-dark-eval-3`;
break;
default:
variantClasses = `bg-purple-500 text-white hover:bg-purple-600 focus:ring-purple-500`;
}

const sizeClasses = `${
size == 'base' ? (iconOnly ? 'p-2' : 'px-4 py-2 text-base') : ''
} ${size == 'sm' ? (iconOnly ? 'p-1.5' : 'px-2.5 py-1.5 text-sm') : ''} ${
size == 'lg' ? (iconOnly ? 'p-3' : 'px-5 py-2 text-xl') : ''
}`;

const roundedClasses = `${!squared && !pill ? 'rounded-md' : ''} ${
pill ? 'rounded-full' : ''
}`;

const iconSizeClasses = `${size == 'sm' ? 'w-5 h-5' : ''} ${
size == 'base' ? 'w-6 h-6' : ''
} ${size == 'lg' ? 'w-7 h-7' : ''}`;

if (href) {
const Tag = external ? 'a' : Link;

return (
<Tag
target={target}
href={href}
className={`${baseClasses} ${sizeClasses} ${variantClasses} ${roundedClasses} ${className} ${
processing ? 'pointer-events-none opacity-50' : ''
}`}
>
{children}
{iconOnly && <span className="sr-only">{srText ?? ''}</span>}
</Tag>
);
}

return (
<button
type={type}
className={`${baseClasses} ${sizeClasses} ${variantClasses} ${roundedClasses} ${className}`}
disabled={processing}
onClick={onClick}
>
{children}
{iconOnly && <span className="sr-only">{srText ?? ''}</span>}
</button>
);
};
11 changes: 11 additions & 0 deletions stubs/react/js/Components/Checkbox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default ({ name, value, handleChange }) => {
return (
<input
type="checkbox"
name={name}
value={value}
className="text-purple-500 border-gray-300 rounded focus:border-purple-300 focus:ring focus:ring-purple-500 dark:border-gray-600 dark:bg-dark-eval-1 dark:focus:ring-offset-dark-eval-1"
onChange={(e) => handleChange(e)}
/>
);
};
75 changes: 75 additions & 0 deletions stubs/react/js/Components/Dropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Link } from "@inertiajs/inertia-react";
import { Transition } from "@headlessui/react";
import { Menu } from "@headlessui/react";

const Item = ({ href, title, method = "GET", as }) => {
const baseClasses = `block w-full px-4 py-2 text-sm leading-5 text-left text-gray-700 transition duration-150 ease-in-out focus:outline-none dark:focus:text-white dark:focus:bg-dark-eval-3 dark:text-gray-400`;

return (
<Menu.Item>
{({ active, disabled }) => (
<Link
href={href}
method={method}
as={as}
className={`${baseClasses} ${
active &&
"bg-gray-100 dark:text-gray-200 dark:bg-dark-eval-3"
} ${disabled && "pointer-events-none"}`}
>
{title}
</Link>
)}
</Menu.Item>
);
};

const Dropdown = ({
children,
trigger,
align = "right",
width = "48",
contentClasses = "py-1 bg-white",
}) => {
let alignmentClasses = "origin-top";

if (align === "left") {
alignmentClasses = "origin-top-left left-0";
} else if (align === "right") {
alignmentClasses = "origin-top-right right-0";
}

let widthClasses = "";

if (width === "48") {
widthClasses = "w-48";
}

return (
<Menu as="div" className="relative">
<Menu.Button as="span">{trigger}</Menu.Button>

<Transition
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leaveActive="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
className={`absolute z-50 mt-2 rounded-md shadow-lg ${alignmentClasses} ${widthClasses}`}
>
<div
className={`rounded-md ring-1 ring-black ring-opacity-5 ${contentClasses}`}
>
{children}
</div>
</Menu.Items>
</Transition>
</Menu>
);
};

Dropdown.Item = Item;
export default Dropdown;
47 changes: 47 additions & 0 deletions stubs/react/js/Components/Icons/brands.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Boxicons
export const GithubIcon = (props) => {
return (
<svg
{...props}
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M12.026 2C6.517 2 2.052 6.465 2.052 11.974C2.052 16.38 4.909 20.119 8.873 21.439C9.372 21.529 9.552 21.222 9.552 20.958C9.552 20.721 9.544 20.093 9.541 19.262C6.766 19.864 6.18 17.924 6.18 17.924C5.728 16.772 5.073 16.465 5.073 16.465C4.168 15.846 5.142 15.86 5.142 15.86C6.144 15.93 6.669 16.888 6.669 16.888C7.559 18.412 9.005 17.972 9.571 17.717C9.662 17.072 9.922 16.632 10.206 16.383C7.992 16.132 5.664 15.276 5.664 11.453C5.664 10.366 6.053 9.474 6.688 8.778C6.587 8.525 6.242 7.51 6.787 6.138C6.787 6.138 7.624 5.869 9.529 7.159C10.3426 6.93767 11.1818 6.8247 12.025 6.823C12.8682 6.82437 13.7075 6.93735 14.521 7.159C16.427 5.868 17.263 6.138 17.263 6.138C17.808 7.51 17.466 8.525 17.362 8.778C18.002 9.474 18.386 10.365 18.386 11.453C18.386 15.286 16.056 16.128 13.834 16.375C14.189 16.683 14.509 17.291 14.509 18.221C14.509 19.555 14.497 20.631 14.497 20.958C14.497 21.225 14.675 21.535 15.184 21.437C19.146 20.115 22 16.379 22 11.974C22 6.465 17.535 2 12.026 2Z"
/>
</svg>
);
};

export const TwitterIcon = (props) => {
return (
<svg
{...props}
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M19.633 7.99704C19.646 8.17204 19.646 8.34604 19.646 8.52004C19.646 13.845 15.593 19.981 8.186 19.981C5.904 19.981 3.784 19.32 2 18.172C2.324 18.209 2.636 18.222 2.973 18.222C4.78599 18.2264 6.54765 17.6202 7.974 16.501C7.13342 16.4858 6.31858 16.2085 5.64324 15.7078C4.9679 15.2071 4.46578 14.5079 4.207 13.708C4.456 13.745 4.706 13.77 4.968 13.77C5.329 13.77 5.692 13.72 6.029 13.633C5.11676 13.4489 4.29647 12.9544 3.70762 12.2337C3.11876 11.5131 2.79769 10.6107 2.799 9.68004V9.63004C3.336 9.92904 3.959 10.116 4.619 10.141C4.06609 9.77363 3.61272 9.27507 3.29934 8.68983C2.98596 8.1046 2.82231 7.4509 2.823 6.78704C2.823 6.03904 3.022 5.35304 3.371 4.75504C4.38314 6.00006 5.6455 7.01861 7.07634 7.7447C8.50717 8.4708 10.0746 8.88826 11.677 8.97004C11.615 8.67004 11.577 8.35904 11.577 8.04704C11.5767 7.518 11.6807 6.9941 11.8831 6.50528C12.0854 6.01647 12.3821 5.57232 12.7562 5.19823C13.1303 4.82414 13.5744 4.52745 14.0632 4.32512C14.5521 4.12279 15.076 4.01878 15.605 4.01904C16.765 4.01904 17.812 4.50504 18.548 5.29104C19.4498 5.11666 20.3145 4.78747 21.104 4.31804C20.8034 5.24886 20.1738 6.03815 19.333 6.53804C20.1328 6.44682 20.9144 6.2365 21.652 5.91404C21.1011 6.71714 20.4185 7.42139 19.633 7.99704V7.99704Z" />
</svg>
);
};

export const FigmaIcon = (props) => {
return (
<svg
{...props}
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M17.6239 7.65767C17.0203 8.27961 16.1982 8.64201 15.332 8.668H12V18.664C11.9997 19.5477 11.6486 20.3952 11.0238 21.0201C10.399 21.6451 9.55168 21.9965 8.66797 21.997C7.7984 21.9757 6.97162 21.6153 6.36413 20.9927C5.75665 20.3702 5.41661 19.5348 5.41661 18.665C5.41661 17.7952 5.75665 16.9598 6.36413 16.3373C6.97162 15.7147 7.7984 15.3543 8.66797 15.333C7.79413 15.3179 6.9612 14.9601 6.34859 14.3368C5.73598 13.7135 5.3927 12.8745 5.3927 12.0005C5.3927 11.1265 5.73598 10.2875 6.34859 9.66422C6.9612 9.0409 7.79413 8.68314 8.66797 8.668C7.80171 8.64201 6.97963 8.27961 6.37608 7.65767C5.77252 7.03573 5.43495 6.20316 5.43495 5.3365C5.43495 4.46985 5.77252 3.63728 6.37608 3.01534C6.97963 2.3934 7.80171 2.031 8.66797 2.005H15.332C16.1982 2.031 17.0203 2.3934 17.6239 3.01534C18.2274 3.63728 18.565 4.46985 18.565 5.3365C18.565 6.20316 18.2274 7.03573 17.6239 7.65767ZM18.664 12C18.664 13.8402 17.1722 15.332 15.332 15.332C13.4918 15.332 12 13.8402 12 12C12 10.1598 13.4918 8.66803 15.332 8.66803C17.1722 8.66803 18.664 10.1598 18.664 12Z"
/>
</svg>
);
};
Loading

0 comments on commit e0490b6

Please sign in to comment.