Skip to content

Commit

Permalink
add vue stack
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamona-WD committed Oct 10, 2021
1 parent 188cbf6 commit 335e52f
Show file tree
Hide file tree
Showing 41 changed files with 2,360 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/Console/ReplaceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,52 @@ public function replaceBlade()
// Icons
$this->requireComposerPackages('blade-ui-kit/blade-heroicons:^1.2');

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

public function replaceVue()
{
$this->comment('Vue stack will be avilable soon.');
// NPM Packages...
$this->updateNodePackages(function ($packages) {
return [
'@heroicons/vue' => '^1.0.4',
'@vueuse/core' => '^6.5.3',
'@vue/babel-plugin-jsx' => '^1.1.0',
'autoprefixer' => '^10.3.7',
'postcss' => '^8.3.9',
'tailwindcss' => '^2.2.16',
'perfect-scrollbar' => '^1.5.2'
] + $packages;
});

// 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/Composables'));
(new Filesystem)->ensureDirectoryExists(resource_path('js/Layouts'));
(new Filesystem)->ensureDirectoryExists(resource_path('js/Pages'));

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

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

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

public function replaceReact()
{
$this->comment('React stack will be avilable soon.');
$this->warn('React stack will be avilable soon.');
}

/**
Expand Down
3 changes: 3 additions & 0 deletions stubs/vue/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["@vue/babel-plugin-jsx"]
}
9 changes: 9 additions & 0 deletions stubs/vue/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;
}
16 changes: 16 additions & 0 deletions stubs/vue/js/Components/ApplicationLogo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<template>
<svg 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>
</template>
138 changes: 138 additions & 0 deletions stubs/vue/js/Components/Button.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<template>
<component :is="Tag" v-if="href" :href="!disabled ? href : null" :class="classes" :aria-disabled="disabled.toString()">
<span v-if="srText" class="sr-only">{{ srText }}</span>
<slot :iconSizeClasses="iconSizeClasses" />
</component>
<button v-else :type="type" :class="classes" @click="handleClick" :disabled="disabled">
<span v-if="srText" class="sr-only">{{ srText }}</span>
<slot :iconSizeClasses="iconSizeClasses" />
</button>
</template>

<script>
import { toRefs, computed } from 'vue'
import { Link } from '@inertiajs/inertia-vue3'
export default {
props: {
variant: {
type: String,
default: 'primary',
validator(value) {
return ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'black'].includes(value)
},
},
type: {
type: String,
default: 'submit',
},
size: {
type: String,
default: 'base',
validator(value) {
return ['sm', 'base', 'lg'].includes(value)
},
},
squared: {
type: Boolean,
default: false,
},
pill: {
type: Boolean,
default: false,
},
href: {
type: String,
},
disabled: {
type: Boolean,
default: false,
},
iconOnly: {
type: Boolean,
default: false,
},
srText: {
type: String || undefined,
default: undefined,
},
external: {
type: Boolean,
default: false,
},
},
emits: ['click'],
setup(props, { emit }) {
const { type, variant, size, squared, pill, href, iconOnly, srText, external } = props
const { disabled } = toRefs(props)
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',
]
const variantClasses = (variant) => ({
'bg-purple-500 text-white hover:bg-purple-600 focus:ring-purple-500': variant == 'primary',
'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':
variant == 'secondary',
'bg-green-500 text-white hover:bg-green-600 focus:ring-green-500': variant == 'success',
'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500': variant == 'danger',
'bg-yellow-500 text-white hover:bg-yellow-600 focus:ring-yellow-500': variant == 'warning',
'bg-cyan-500 text-white hover:bg-cyan-600 focus:ring-cyan-500': variant == 'info',
'bg-black text-gray-300 hover:text-white hover:bg-gray-800 focus:ring-black dark:hover:bg-dark-eval-3':
variant == 'black',
})
const classes = computed(() => [
...baseClasses,
iconOnly
? {
'p-1.5': size == 'sm',
'p-2': size == 'base',
'p-3': size == 'lg',
}
: {
'px-2.5 py-1.5 text-sm': size == 'sm',
'px-4 py-2 text-base': size == 'base',
'px-5 py-2 text-xl': size == 'lg',
},
variantClasses(variant),
{
'rounded-md': !squared && !pill,
'rounded-full': pill,
},
{
'pointer-events-none opacity-50': href && disabled.value,
},
])
const iconSizeClasses = [
{
'w-5 h-5': size == 'sm',
'w-6 h-6': size == 'base',
'w-7 h-7': size == 'lg',
},
]
const handleClick = (e) => {
if (disabled.value) {
e.preventDefault()
e.stopPropagation()
return
}
emit('click')
}
const Tag = external ? 'a' : Link
return {
classes,
handleClick,
Tag,
iconSizeClasses,
}
}
}
</script>
32 changes: 32 additions & 0 deletions stubs/vue/js/Components/Checkbox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<input type="checkbox" :value="value" v-model="proxyChecked"
class="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">
</template>

<script>
export default {
emits: ['update:checked'],
props: {
checked: {
type: [Array, Boolean],
default: false,
},
value: {
default: null,
},
},
computed: {
proxyChecked: {
get() {
return this.checked;
},
set(val) {
this.$emit("update:checked", val);
},
},
},
}
</script>
81 changes: 81 additions & 0 deletions stubs/vue/js/Components/Dropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<template>
<div class="relative">
<div @click="open = ! open">
<slot name="trigger" />
</div>

<!-- Full Screen Dropdown Overlay -->
<div v-show="open" class="fixed inset-0 z-40" @click="open = false"></div>

<transition
enter-active-class="transition ease-out duration-200"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95">
<div v-show="open"
class="absolute z-50 mt-2 rounded-md shadow-lg"
:class="[widthClass, alignmentClasses]"
style="display: none;"
@click="open = false">
<div class="rounded-md ring-1 ring-black ring-opacity-5" :class="contentClasses">
<slot name="content" />
</div>
</div>
</transition>
</div>
</template>

<script>
import { onMounted, onUnmounted, ref } from 'vue'
export default {
props: {
align: {
default: 'right'
},
width: {
default: '48'
},
contentClasses: {
default: () => ['py-1', 'bg-white dark:bg-dark-eval-1']
}
},
setup() {
let open = ref(false)
const closeOnEscape = (e) => {
if (open.value && e.keyCode === 27) {
open.value = false
}
}
onMounted(() => document.addEventListener('keydown', closeOnEscape))
onUnmounted(() => document.removeEventListener('keydown', closeOnEscape))
return {
open,
}
},
computed: {
widthClass() {
return {
'48': 'w-48',
}[this.width.toString()]
},
alignmentClasses() {
if (this.align === 'left') {
return 'origin-top-left left-0'
} else if (this.align === 'right') {
return 'origin-top-right right-0'
} else {
return 'origin-top'
}
},
}
}
</script>
17 changes: 17 additions & 0 deletions stubs/vue/js/Components/DropdownLink.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<Link
class="block w-full px-4 py-2 text-sm leading-5 text-left text-gray-700 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus:bg-gray-100 dark:focus:text-white dark:focus:bg-dark-eval-3 dark:text-gray-400 dark:hover:text-gray-200 dark:hover:bg-dark-eval-3"
>
<slot />
</Link>
</template>

<script>
import { Link } from '@inertiajs/inertia-vue3'
export default {
components: {
Link,
},
}
</script>
Loading

0 comments on commit 335e52f

Please sign in to comment.