├── .env.example ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── app.vue ├── assets ├── css │ └── tailwind.css └── presets │ └── lara │ ├── accordion │ └── index.js │ ├── autocomplete │ └── index.js │ ├── avatar │ └── index.js │ ├── badge │ └── index.js │ ├── badgedirective │ └── index.js │ ├── blockui │ └── index.js │ ├── breadcrumb │ └── index.js │ ├── button │ └── index.js │ ├── calendar │ └── index.js │ ├── card │ └── index.js │ ├── carousel │ └── index.js │ ├── cascadeselect │ └── index.js │ ├── checkbox │ └── index.js │ ├── chip │ └── index.js │ ├── chips │ └── index.js │ ├── colorpicker │ └── index.js │ ├── confirmpopup │ └── index.js │ ├── contextmenu │ └── index.js │ ├── datatable │ └── index.js │ ├── dataview │ └── index.js │ ├── dialog │ └── index.js │ ├── divider │ └── index.js │ ├── dock │ └── index.js │ ├── dropdown │ └── index.js │ ├── fieldset │ └── index.js │ ├── fileupload │ └── index.js │ ├── floatlabel │ └── index.js │ ├── galleria │ └── index.js │ ├── global.js │ ├── iconfield │ └── index.js │ ├── image │ └── index.js │ ├── index.js │ ├── inlinemessage │ └── index.js │ ├── inplace │ └── index.js │ ├── inputgroup │ └── index.js │ ├── inputgroupaddon │ └── index.js │ ├── inputmask │ └── index.js │ ├── inputnumber │ └── index.js │ ├── inputotp │ └── index.js │ ├── inputswitch │ └── index.js │ ├── inputtext │ └── index.js │ ├── knob │ └── index.js │ ├── listbox │ └── index.js │ ├── megamenu │ └── index.js │ ├── menu │ └── index.js │ ├── menubar │ └── index.js │ ├── message │ └── index.js │ ├── metergroup │ └── index.js │ ├── multiselect │ └── index.js │ ├── orderlist │ └── index.js │ ├── organizationchart │ └── index.js │ ├── overlaypanel │ └── index.js │ ├── paginator │ └── index.js │ ├── panel │ └── index.js │ ├── panelmenu │ └── index.js │ ├── password │ └── index.js │ ├── picklist │ └── index.js │ ├── progressbar │ └── index.js │ ├── progressspinner │ └── index.js │ ├── radiobutton │ └── index.js │ ├── rating │ └── index.js │ ├── ripple │ └── index.js │ ├── scrollpanel │ └── index.js │ ├── scrolltop │ └── index.js │ ├── selectbutton │ └── index.js │ ├── sidebar │ └── index.js │ ├── skeleton │ └── index.js │ ├── slider │ └── index.js │ ├── speeddial │ └── index.js │ ├── splitbutton │ └── index.js │ ├── splitter │ └── index.js │ ├── stepper │ └── index.js │ ├── steps │ └── index.js │ ├── tabmenu │ └── index.js │ ├── tabview │ └── index.js │ ├── tag │ └── index.js │ ├── terminal │ └── index.js │ ├── textarea │ └── index.js │ ├── tieredmenu │ └── index.js │ ├── timeline │ └── index.js │ ├── toast │ └── index.js │ ├── togglebutton │ └── index.js │ ├── toolbar │ └── index.js │ ├── tooltip │ └── index.js │ ├── tree │ └── index.js │ ├── treeselect │ └── index.js │ ├── treetable │ └── index.js │ └── tristatecheckbox │ └── index.js ├── components ├── Logo │ └── Logo.vue ├── MainContent │ └── MainContent.vue ├── OgImage │ ├── GistDetail.vue │ ├── Main.vue │ └── PublicProfile.vue ├── Splash │ └── Splash.vue └── Widget │ └── Default.vue ├── composables ├── useLogger │ └── useLogger.ts ├── useMarkdown │ └── useMarkdown.ts └── useServices │ └── useServices.ts ├── emails └── GistSale.vue ├── layouts ├── admin.vue ├── checkout.vue └── default.vue ├── libs ├── currency │ └── format.ts └── supabase │ └── schema.ts ├── middleware └── auth.ts ├── modules ├── auth │ ├── components │ │ ├── Header │ │ │ ├── Header.vue │ │ │ └── Loader.vue │ │ └── SocialForm │ │ │ └── SocialForm.vue │ ├── composables │ │ └── useSession │ │ │ └── useSession.ts │ ├── screens │ │ ├── Login │ │ │ └── Login.vue │ │ └── OAuthRedirect │ │ │ └── OAuthRedirect.vue │ └── services │ │ └── services.ts ├── gists │ ├── components │ │ ├── Card │ │ │ ├── Group │ │ │ │ ├── Group.vue │ │ │ │ └── Loader.vue │ │ │ └── Item │ │ │ │ └── Item.vue │ │ ├── CodeEdit │ │ │ └── CodeEdit.vue │ │ ├── CodeSnippet │ │ │ ├── CodeSnippet.vue │ │ │ └── Loader.vue │ │ ├── HeadlineEdit │ │ │ └── HeadlineEdit.vue │ │ └── PublicHeadline │ │ │ ├── Empty.vue │ │ │ ├── Loader.vue │ │ │ └── PublicHeadline.vue │ ├── composables │ │ ├── useGist │ │ │ └── useGist.ts │ │ ├── useGistContent │ │ │ └── useGistContent.ts │ │ ├── useGistCreate │ │ │ └── useGistCreate.ts │ │ ├── useGistDelete │ │ │ └── useGistDelete.ts │ │ ├── useGistList │ │ │ └── useGistList.ts │ │ └── useGistUpdate │ │ │ └── useGistUpdate.ts │ ├── entities │ │ └── Gist │ │ │ └── Gist.ts │ ├── screens │ │ ├── CreateNew │ │ │ └── CreateNew.vue │ │ ├── Edit │ │ │ └── Edit.vue │ │ └── MoreDetail │ │ │ └── MoreDetail.vue │ └── services │ │ ├── adapters.ts │ │ ├── services.ts │ │ └── types.ts ├── landing-page │ ├── components │ │ ├── Header │ │ │ └── Header.vue │ │ └── Hero │ │ │ └── Hero.vue │ └── screens │ │ └── Home │ │ └── Home.vue ├── payments │ ├── components │ │ ├── DialogPaymentError │ │ │ └── DialogPaymentError.vue │ │ ├── DialogPaymentSuccess │ │ │ └── DialogPaymentSuccess.vue │ │ ├── PaymentSetupAlert │ │ │ └── PaymentSetupAlert.vue │ │ └── Table │ │ │ └── Sales │ │ │ ├── Loader.vue │ │ │ └── Sales.vue │ ├── composables │ │ ├── useSalesList │ │ │ └── useSalesList.ts │ │ ├── useStripeAccountCreate │ │ │ └── useStripeAccountCreate.ts │ │ ├── useStripeAccountValidate │ │ │ └── useStripeAccountValidate.ts │ │ └── useStripeCheckout │ │ │ ├── types.ts │ │ │ └── useStripeCheckout.ts │ ├── entities │ │ └── Sale │ │ │ └── Sale.ts │ ├── screens │ │ └── Sales │ │ │ └── Sales.vue │ └── services │ │ ├── adapters.ts │ │ ├── services.ts │ │ └── types.ts ├── reports │ ├── components │ │ └── Widget │ │ │ ├── Condensed │ │ │ └── Condensed.vue │ │ │ └── Group │ │ │ ├── Group.vue │ │ │ └── Loader.vue │ ├── composables │ │ ├── useGistsReport │ │ │ └── useGistsReport.ts │ │ └── useSalesReport │ │ │ └── useSalesReport.ts │ ├── screens │ │ └── Panel │ │ │ └── Panel.vue │ └── services │ │ ├── adapters.ts │ │ └── services.ts └── users │ ├── components │ ├── AddressForm │ │ └── AddressForm.vue │ ├── BasicInfoForm │ │ └── BasicInfoForm.vue │ ├── HeadlineEdit │ │ ├── HeadlineEdit.vue │ │ └── Loader.vue │ └── PublicHeadline │ │ ├── Empty.vue │ │ └── PublicHeadline.vue │ ├── composables │ ├── useAddressUpdate │ │ └── useAddressUpdate.ts │ ├── useMyself │ │ ├── types.ts │ │ └── useMyself.ts │ ├── useUserProfileActions │ │ └── useUserProfileActions.ts │ └── useUserUpdate │ │ └── useUserUpdate.ts │ ├── entities │ ├── Address │ │ └── Address.ts │ └── User │ │ └── User.ts │ ├── screens │ ├── EditProfile │ │ └── EditProfile.vue │ └── PublicProfile │ │ └── PublicProfile.vue │ └── services │ ├── adapters.ts │ ├── services.ts │ └── types.ts ├── nuxt.config.ts ├── package.json ├── pages ├── [username] │ ├── gist │ │ └── [id].vue │ └── index.vue ├── app │ ├── gist │ │ ├── [id] │ │ │ └── edit.vue │ │ └── create.vue │ ├── panel.vue │ ├── profile │ │ └── edit.vue │ └── sales │ │ └── all.vue ├── auth │ ├── github.vue │ └── login.vue └── index.vue ├── plugins ├── maska.ts └── monaco.client.ts ├── public └── favicon.ico ├── server ├── api │ ├── payments │ │ ├── accounts │ │ │ ├── [accountid] │ │ │ │ └── valid.get.ts │ │ │ └── index.post.ts │ │ └── checkout │ │ │ └── index.post.ts │ └── webhooks │ │ └── payment.post.ts ├── middleware │ └── auth.ts └── tsconfig.json ├── supabase ├── .gitignore ├── config.toml ├── migrations │ ├── 20240303222730_create_profiles_table.sql │ ├── 20240303223419_create_function_add_user_to_profile.sql │ ├── 20240303224214_create_trigger_new_user_signup.sql │ ├── 20240303224635_create_gists_table.sql │ └── 20240303224638_create_sales_table.sql └── seed.sql ├── tailwind.config.js ├── tsconfig.json └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV=local 2 | SITE_URL=http://localhost:3000 3 | SUPABASE_URL=http://127.0.0.1:54321 4 | SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0 5 | STRIPE_CLIENT_KEY= 6 | STRIPE_SECRET_KEY= 7 | STRIPE_PRODUCT_ID_5BRL= 8 | STRIPE_PRODUCT_ID_10BRL= 9 | STRIPE_PRODUCT_ID_25BRL= 10 | STRIPE_WEBHOOK_SECRET= 11 | RESEND_KEY= 12 | GITHUB_CLIENT_ID= 13 | GITHUB_SECRET= 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | extends: [ 8 | "standard-with-typescript", 9 | "plugin:vue/vue3-recommended", 10 | "@nuxtjs/eslint-config-typescript", 11 | "plugin:prettier/recommended", 12 | ], 13 | overrides: [ 14 | { 15 | env: { 16 | node: true, 17 | }, 18 | files: [".eslintrc.{js,cjs}"], 19 | parserOptions: { 20 | sourceType: "script", 21 | }, 22 | }, 23 | ], 24 | parser: "vue-eslint-parser", 25 | parserOptions: { 26 | ecmaVersion: "latest", 27 | parser: "@typescript-eslint/parser", 28 | sourceType: "module", 29 | }, 30 | plugins: ["vue"], 31 | rules: {}, 32 | }; 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "printWidth": 120 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## `onlygists` 2 | 3 | Share and monetize code snippets. Earn extra income with the codes you make on a daily basis. 4 | This is the source code to my course called: [`NuxtExtreme`](https://luckyhackers.academy/course/nuxt-extreme) 5 | 6 | ### Setup 7 | 8 | First things first, rename `.env.example` to `.env` and put your keys 9 | 10 | ```sh 11 | # instal deps 12 | yarn install 13 | 14 | # run local 15 | yarn dev 16 | ``` 17 | 18 | ### Test payments locally 19 | 20 | You'll need to install [stripe-cli](https://docs.stripe.com/stripe-cli/overview) and run 21 | 22 | ```sh 23 | # to authenticate with your account 24 | stripe login 25 | 26 | # to bypass events to your local machine 27 | stripe listen --forward-to localhost:3000/api/webhooks/payment 28 | ``` -------------------------------------------------------------------------------- /app.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 26 | -------------------------------------------------------------------------------- /assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --primary-50: 255 204 166; 7 | --primary-100: 255 183 128; 8 | --primary-200: 255 158 92; 9 | --primary-300: 255 136 62; 10 | --primary-400: 247 123 50; 11 | --primary-500: 249 115 22; 12 | --primary-600: 232 98 0; 13 | --primary-700: 204 85 0; 14 | --primary-800: 178 73 0; 15 | --primary-900: 153 60 0; 16 | --primary-950: 115 40 0; 17 | --surface-0: 255 255 255; 18 | --surface-50: 248 250 252; 19 | --surface-100: 241 245 249; 20 | --surface-200: 226 232 240; 21 | --surface-300: 203 213 225; 22 | --surface-400: 148 163 184; 23 | --surface-500: 100 116 139; 24 | --surface-600: 71 85 105; 25 | --surface-700: 45 55 72; 26 | --surface-800: 30 41 59; 27 | --surface-900: 15 23 42; 28 | --surface-950: 3 6 23; 29 | } 30 | 31 | html, 32 | body, 33 | #__nuxt { 34 | @apply w-full h-full scroll-smooth; 35 | } 36 | -------------------------------------------------------------------------------- /assets/presets/lara/accordion/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | accordiontab: { 3 | root: { 4 | class: 'mb-1' 5 | }, 6 | header: ({ props }) => ({ 7 | class: [ 8 | // State 9 | { 'select-none pointer-events-none cursor-default opacity-60': props?.disabled } 10 | ] 11 | }), 12 | headerAction: ({ context }) => ({ 13 | class: [ 14 | //Font 15 | 'font-bold', 16 | 'leading-none', 17 | 18 | // Alignments 19 | 'flex items-center', 20 | 'relative', 21 | 22 | // Sizing 23 | 'p-5', 24 | 25 | // Shape 26 | 'rounded-t-md', 27 | { 'rounded-br-md rounded-bl-md': !context.active, 'rounded-br-0 rounded-bl-0': context.active }, 28 | 29 | // Color 30 | 'border border-surface-200 dark:border-surface-700', 31 | 'bg-surface-50 dark:bg-surface-800', 32 | 'text-surface-600 dark:text-surface-0/80', 33 | { 'text-surface-900': context.active }, 34 | 35 | // Transition 36 | 'transition duration-200 ease-in-out', 37 | 'transition-shadow duration-200', 38 | 39 | // States 40 | 'hover:bg-surface-100 dark:hover:bg-surface-700/40', 41 | 'hover:text-surface-900', 42 | 'focus:outline-none focus:outline-offset-0 focus-visible:ring focus-visible:ring-primary-400/50 ring-inset dark:focus-visible:ring-primary-300/50', // Focus 43 | 44 | // Misc 45 | 'cursor-pointer no-underline select-none' 46 | ] 47 | }), 48 | headerIcon: { 49 | class: 'inline-block mr-2' 50 | }, 51 | headerTitle: { 52 | class: 'leading-none' 53 | }, 54 | content: { 55 | class: [ 56 | // Spacing 57 | 'p-5', 58 | 59 | //Shape 60 | 'rounded-tl-none rounded-tr-none rounded-br-lg rounded-bl-lg', 61 | 'border-t-0', 62 | 63 | // Color 64 | 'bg-surface-0 dark:bg-surface-800', 65 | 'border border-surface-200 dark:border-surface-700', 66 | 'text-surface-700 dark:text-surface-0/80' 67 | ] 68 | }, 69 | transition: { 70 | enterFromClass: 'max-h-0', 71 | enterActiveClass: 'overflow-hidden transition-[max-height] duration-1000 ease-[cubic-bezier(0.42,0,0.58,1)]', 72 | enterToClass: 'max-h-[1000px]', 73 | leaveFromClass: 'max-h-[1000px]', 74 | leaveActiveClass: 'overflow-hidden transition-[max-height] duration-[450ms] ease-[cubic-bezier(0,1,0,1)]', 75 | leaveToClass: 'max-h-0' 76 | } 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /assets/presets/lara/avatar/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props, parent }) => ({ 3 | class: [ 4 | // Font 5 | { 6 | 'text-xl': props.size == 'large', 7 | 'text-2xl': props.size == 'xlarge' 8 | }, 9 | 10 | // Alignments 11 | 'inline-flex items-center justify-center', 12 | 'relative', 13 | 14 | // Sizes 15 | { 16 | 'h-8 w-8': props.size == null || props.size == 'normal', 17 | 'w-12 h-12': props.size == 'large', 18 | 'w-16 h-16': props.size == 'xlarge' 19 | }, 20 | { '-ml-4': parent.instance.$style?.name == 'avatargroup' }, 21 | 22 | // Shapes 23 | { 24 | 'rounded-lg': props.shape == 'square', 25 | 'rounded-full': props.shape == 'circle' 26 | }, 27 | { 'border-2': parent.instance.$style?.name == 'avatargroup' }, 28 | 29 | // Colors 30 | 'bg-surface-300 dark:bg-surface-700', 31 | { 'border-white dark:border-surface-800': parent.instance.$style?.name == 'avatargroup' } 32 | ] 33 | }), 34 | image: ({ props }) => ({ 35 | class: [ 36 | 'h-full w-full', 37 | { 38 | 'rounded-lg': props.shape == 'square', 39 | 'rounded-full': props.shape == 'circle' 40 | } 41 | ] 42 | }) 43 | }; 44 | -------------------------------------------------------------------------------- /assets/presets/lara/badge/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Font 5 | 'font-bold', 6 | 7 | { 8 | 'text-xs leading-[1.5rem]': props.size == null, 9 | 'text-lg leading-[2.25rem]': props.size == 'large', 10 | 'text-2xl leading-[3rem]': props.size == 'xlarge' 11 | }, 12 | 13 | // Alignment 14 | 'text-center inline-block', 15 | 16 | // Size 17 | 'p-0 px-1', 18 | { 19 | 'min-w-[1.5rem] h-[1.5rem]': props.size == null, 20 | 'min-w-[2.25rem] h-[2.25rem]': props.size == 'large', 21 | 'min-w-[3rem] h-[3rem]': props.size == 'xlarge' 22 | }, 23 | 24 | // Shape 25 | { 26 | 'rounded-full': props.value.length == 1, 27 | 'rounded-[0.71rem]': props.value.length !== 1 28 | }, 29 | 30 | // Color 31 | 'text-white dark:text-surface-900', 32 | { 33 | 'bg-primary-500 dark:bg-primary-400': props.severity == null || props.severity == 'primary', 34 | 'bg-surface-500 dark:bg-surface-400': props.severity == 'secondary', 35 | 'bg-green-500 dark:bg-green-400': props.severity == 'success', 36 | 'bg-blue-500 dark:bg-blue-400': props.severity == 'info', 37 | 'bg-orange-500 dark:bg-orange-400': props.severity == 'warning', 38 | 'bg-purple-500 dark:bg-purple-400': props.severity == 'help', 39 | 'bg-red-500 dark:bg-red-400': props.severity == 'danger' 40 | } 41 | ] 42 | }) 43 | }; 44 | -------------------------------------------------------------------------------- /assets/presets/lara/badgedirective/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ context }) => ({ 3 | class: [ 4 | // Font 5 | 'font-bold font-sans', 6 | 'text-xs leading-5', 7 | 8 | // Alignment 9 | 'flex items-center justify-center', 10 | 'text-center', 11 | 12 | // Position 13 | 'absolute top-0 right-0 transform translate-x-1/2 -translate-y-1/2 origin-top-right', 14 | 15 | // Size 16 | 'm-0', 17 | { 18 | 'p-0': context.nogutter || context.dot, 19 | 'px-2': !context.nogutter && !context.dot, 20 | 'min-w-[0.5rem] w-2 h-2': context.dot, 21 | 'min-w-[1.5rem] h-6': !context.dot 22 | }, 23 | 24 | // Shape 25 | { 26 | 'rounded-full': context.nogutter || context.dot, 27 | 'rounded-[10px]': !context.nogutter && !context.dot 28 | }, 29 | 30 | // Color 31 | 'text-white dark:text-surface-900', 32 | { 33 | 'bg-primary-500 dark:bg-primary-400': !context.info && !context.success && !context.warning && !context.danger && !context.help && !context.secondary, 34 | 'bg-surface-500 dark:bg-surface-400': context.secondary, 35 | 'bg-green-500 dark:bg-green-400': context.success, 36 | 'bg-blue-500 dark:bg-blue-400': context.info, 37 | 'bg-orange-500 dark:bg-orange-400': context.warning, 38 | 'bg-purple-500 dark:bg-purple-400': context.help, 39 | 'bg-red-500 dark:bg-red-400': context.danger 40 | } 41 | ] 42 | }) 43 | }; 44 | -------------------------------------------------------------------------------- /assets/presets/lara/blockui/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: 'relative' 4 | }, 5 | mask: { 6 | class: 'bg-black/40' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /assets/presets/lara/breadcrumb/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Shape 5 | 'rounded-md', 6 | 7 | // Spacing 8 | 'p-4', 9 | 10 | // Color 11 | 'bg-surface-0 dark:bg-surface-700', 12 | 'border border-surface-200 dark:border-surface-700', 13 | 14 | // Misc 15 | 'overflow-x-auto' 16 | ] 17 | }, 18 | menu: { 19 | class: [ 20 | // Flex & Alignment 21 | 'flex items-center flex-nowrap', 22 | 23 | // Spacing 24 | 'm-0 p-0 list-none leading-none' 25 | ] 26 | }, 27 | action: { 28 | class: [ 29 | // Flex & Alignment 30 | 'flex items-center', 31 | 32 | // Shape 33 | 'rounded-md', 34 | 35 | // Color 36 | 'text-surface-600 dark:text-white/70', 37 | 38 | // States 39 | 'focus-visible:outline-none focus-visible:outline-offset-0', 40 | 'focus-visible:ring focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', 41 | 42 | // Transitions 43 | 'transition-shadow duration-200', 44 | 45 | // Misc 46 | 'text-decoration-none' 47 | ] 48 | }, 49 | icon: { 50 | class: 'text-surface-600 dark:text-white/70' 51 | }, 52 | separator: { 53 | class: [ 54 | // Flex & Alignment 55 | 'flex items-center', 56 | 57 | // Spacing 58 | ' mx-2', 59 | 60 | // Color 61 | 'text-surface-600 dark:text-white/70' 62 | ] 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /assets/presets/lara/card/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | //Shape 5 | 'rounded-md', 6 | 'shadow-md', 7 | 8 | //Color 9 | 'bg-surface-0 dark:bg-surface-900', 10 | 'text-surface-700 dark:text-surface-0' 11 | ] 12 | }, 13 | body: { 14 | class: 'p-5' 15 | }, 16 | title: { 17 | class: 'text-2xl font-bold mb-2' 18 | }, 19 | subtitle: { 20 | class: [ 21 | //Font 22 | 'font-normal', 23 | 24 | //Spacing 25 | 'mb-2', 26 | 27 | //Color 28 | 'text-surface-600 dark:text-surface-0/60' 29 | ] 30 | }, 31 | content: { 32 | class: 'py-5' // Vertical padding. 33 | }, 34 | footer: { 35 | class: 'pt-5' // Top padding. 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /assets/presets/lara/checkbox/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | 'relative', 5 | 6 | // Alignment 7 | 'inline-flex', 8 | 'align-bottom', 9 | 10 | // Size 11 | 'w-6', 12 | 'h-6', 13 | 14 | // Misc 15 | 'cursor-pointer', 16 | 'select-none' 17 | ] 18 | }, 19 | box: ({ props, context }) => ({ 20 | class: [ 21 | // Alignment 22 | 'flex', 23 | 'items-center', 24 | 'justify-center', 25 | 26 | // Size 27 | 'w-6', 28 | 'h-6', 29 | 30 | // Shape 31 | 'rounded-md', 32 | 'border-2', 33 | 34 | // Colors 35 | { 36 | 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.checked && !props.invalid, 37 | 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.checked 38 | }, 39 | 40 | // Invalid State 41 | { 'border-red-500 dark:border-red-400': props.invalid }, 42 | 43 | // States 44 | { 45 | 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.checked && !props.invalid, 46 | 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.checked, 47 | 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, 48 | 'cursor-default opacity-60': props.disabled 49 | }, 50 | 51 | // Transitions 52 | 'transition-colors', 53 | 'duration-200' 54 | ] 55 | }), 56 | input: { 57 | class: [ 58 | 'peer', 59 | 60 | // Size 61 | 'w-full ', 62 | 'h-full', 63 | 64 | // Position 65 | 'absolute', 66 | 'top-0 left-0', 67 | 'z-10', 68 | 69 | // Spacing 70 | 'p-0', 71 | 'm-0', 72 | 73 | // Shape 74 | 'opacity-0', 75 | 'rounded-md', 76 | 'outline-none', 77 | 'border-2 border-surface-200 dark:border-surface-700', 78 | 79 | // Misc 80 | 'appearance-none', 81 | 'cursor-pointer' 82 | ] 83 | }, 84 | icon: { 85 | class: [ 86 | // Font 87 | 'text-base leading-none', 88 | 89 | // Size 90 | 'w-4', 91 | 'h-4', 92 | 93 | // Colors 94 | 'text-white dark:text-surface-900', 95 | 96 | // Transitions 97 | 'transition-all', 98 | 'duration-200' 99 | ] 100 | } 101 | }; 102 | -------------------------------------------------------------------------------- /assets/presets/lara/chip/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Flexbox 5 | 'inline-flex items-center', 6 | 7 | // Spacing 8 | 'px-3', 9 | 10 | // Shape 11 | 'rounded-[1.14rem]', 12 | 13 | // Colors 14 | 'text-surface-700 dark:text-white/70', 15 | 'bg-surface-200 dark:bg-surface-700' 16 | ] 17 | }, 18 | label: { 19 | class: 'leading-6 my-1.5 mx-0' 20 | }, 21 | icon: { 22 | class: 'leading-6 mr-2' 23 | }, 24 | image: { 25 | class: ['w-9 h-9 -ml-3 mr-2', 'rounded-full'] 26 | }, 27 | removeIcon: { 28 | class: [ 29 | // Shape 30 | 'rounded-md leading-6', 31 | 32 | // Spacing 33 | 'ml-2', 34 | 35 | // Size 36 | 'w-4 h-4', 37 | 38 | // Transition 39 | 'transition duration-200 ease-in-out', 40 | 41 | // Misc 42 | 'cursor-pointer' 43 | ] 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /assets/presets/lara/chips/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'flex', 5 | { 6 | 'opacity-60 select-none pointer-events-none cursor-default': props.disabled 7 | } 8 | ] 9 | }), 10 | container: ({ state, props }) => ({ 11 | class: [ 12 | // Font 13 | 'font-sans text-base leading-none', 14 | 15 | // Flex 16 | 'flex items-center flex-wrap gap-2', 17 | 18 | // Spacing 19 | 'm-0 py-1.5 px-3', 20 | 21 | // Size 22 | 'w-full', 23 | 'min-h-[2.877rem]', 24 | 25 | // Shape 26 | 'list-none', 27 | 'rounded-md', 28 | 29 | // Color 30 | 'text-surface-700 dark:text-white/80', 31 | 'bg-surface-0 dark:bg-surface-900', 32 | 'border', 33 | { 'border-surface-300 dark:border-surface-600': !props.invalid }, 34 | 35 | // Invalid State 36 | { 'border-red-500 dark:border-red-400': props.invalid }, 37 | 38 | // States 39 | { 'hover:border-primary-500 dark:hover:border-primary-400': !props.invalid }, 40 | 'focus:outline-none focus:outline-offset-0', 41 | { 'ring ring-primary-400/50 dark:ring-primary-300/50': state.focused }, 42 | { 'ring ring-primary-400/50 dark:ring-primary-300/50': state.hovered }, 43 | 44 | // Transition 45 | 'transition-colors duration-200', 46 | 47 | // Misc 48 | 'cursor-text overflow-hidden', 49 | 'appearance-none' 50 | ] 51 | }), 52 | 53 | inputtoken: { 54 | class: ['py-1.5 px-0', 'inline-flex flex-auto'] 55 | }, 56 | input: { 57 | class: [ 58 | // Font 59 | 'font-sans text-base leading-[1.2]', 60 | 61 | // Size 62 | 'w-full', 63 | 64 | // Spacing 65 | 'p-0 m-0', 66 | 67 | // Shape 68 | 'appearance-none rounded-none', 69 | 'border-0 outline-none', 70 | 'shadow-none', 71 | 72 | // Color 73 | 'text-surface-700 dark:text-white/80', 74 | 'bg-transparent' 75 | ] 76 | }, 77 | token: { 78 | class: [ 79 | // Flexbox 80 | 'inline-flex items-center', 81 | 82 | // Spacing 83 | 'py-1.5 px-3', 84 | 85 | // Shape 86 | 'rounded-[1.14rem]', 87 | 88 | // Colors 89 | 'text-surface-700 dark:text-white/70', 90 | 'bg-surface-200 dark:bg-surface-700' 91 | ] 92 | }, 93 | label: { 94 | class: 'leading-5' 95 | }, 96 | removeTokenIcon: { 97 | class: [ 98 | // Shape 99 | 'rounded-md leading-6', 100 | 101 | // Spacing 102 | 'ml-2', 103 | 104 | // Size 105 | 'w-4 h-4', 106 | 107 | // Transition 108 | 'transition duration-200 ease-in-out', 109 | 110 | // Misc 111 | 'cursor-pointer' 112 | ] 113 | } 114 | }; 115 | -------------------------------------------------------------------------------- /assets/presets/lara/dataview/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | content: { 3 | class: [ 4 | // Spacing 5 | 'p-0', 6 | 7 | // Shape 8 | 'border-0', 9 | 10 | // Color 11 | 'text-surface-700 dark:text-white/80', 12 | 'bg-surface-0 dark:bg-surface-800' 13 | ] 14 | }, 15 | grid: { 16 | class: [ 17 | // flex 18 | 'flex flex-wrap', 19 | 20 | // Spacing 21 | 'ml-0 mr-0 mt-0', 22 | 23 | // Color 24 | 'bg-surface-0 dark:bg-surface-800' 25 | ] 26 | }, 27 | header: { 28 | class: [ 29 | 'font-bold', 30 | 31 | // Spacing 32 | 'p-4', 33 | 34 | // Color 35 | 'text-surface-800 dark:text-white/80', 36 | 'bg-surface-50 dark:bg-surface-800', 37 | 'border-surface-200 dark:border-surface-700 border-y' 38 | ] 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /assets/presets/lara/divider/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Flex and Position 5 | 'flex relative', 6 | { 'justify-center': props.layout == 'vertical' }, 7 | { 'items-center': props.layout == 'vertical' }, 8 | { 9 | 'justify-start': props?.align == 'left' && props.layout == 'horizontal', 10 | 'justify-center': props?.align == 'center' && props.layout == 'horizontal', 11 | 'justify-end': props?.align == 'right' && props.layout == 'horizontal', 12 | 'items-center': props?.align == 'top' && props.layout == 'vertical', 13 | 'items-start': props?.align == 'center' && props.layout == 'vertical', 14 | 'items-end': props?.align == 'bottom' && props.layout == 'vertical' 15 | }, 16 | 17 | // Spacing 18 | { 19 | 'my-5 mx-0 py-0 px-5': props.layout == 'horizontal', 20 | 'mx-4 md:mx-5 py-5': props.layout == 'vertical' 21 | }, 22 | 23 | // Size 24 | { 25 | 'w-full': props.layout == 'horizontal', 26 | 'min-h-full': props.layout == 'vertical' 27 | }, 28 | 29 | // Before: Line 30 | 'before:block', 31 | 32 | // Position 33 | { 34 | 'before:absolute before:left-0 before:top-1/2': props.layout == 'horizontal', 35 | 'before:absolute before:left-1/2 before:top-0 before:transform before:-translate-x-1/2': props.layout == 'vertical' 36 | }, 37 | 38 | // Size 39 | { 40 | 'before:w-full': props.layout == 'horizontal', 41 | 'before:min-h-full': props.layout == 'vertical' 42 | }, 43 | 44 | // Shape 45 | { 46 | 'before:border-solid': props.type == 'solid', 47 | 'before:border-dotted': props.type == 'dotted', 48 | 'before:border-dashed': props.type == 'dashed' 49 | }, 50 | 51 | // Color 52 | { 53 | 'before:border-t before:border-surface-200 before:dark:border-surface-600': props.layout == 'horizontal', 54 | 'before:border-l before:border-surface-200 before:dark:border-surface-600': props.layout == 'vertical' 55 | } 56 | ] 57 | }), 58 | content: { 59 | class: [ 60 | // Space and Position 61 | 'px-1 z-10', 62 | 63 | // Color 64 | 'bg-surface-0 dark:bg-surface-800' 65 | ] 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /assets/presets/lara/dock/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Positioning 5 | 'absolute z-1', 6 | { 7 | 'left-0 bottom-0 w-full': props.position == 'bottom', 8 | 'left-0 top-0 w-full': props.position == 'top', 9 | 'left-0 top-0 h-full': props.position == 'left', 10 | 'right-0 top-0 h-full': props.position == 'right' 11 | }, 12 | 13 | // Flexbox & Alignment 14 | 'flex justify-center items-center', 15 | 16 | // Interactivity 17 | 'pointer-events-none' 18 | ] 19 | }), 20 | container: { 21 | class: [ 22 | // Flexbox 23 | 'flex', 24 | 25 | // Shape & Border 26 | 'rounded-md', 27 | 28 | // Color 29 | 'bg-surface-0/10 dark:bg-surface-900/20 border border-surface-0/20', 30 | 'backdrop-blur-sm', 31 | 32 | // Spacing 33 | 'p-2', 34 | 35 | // Misc 36 | 'pointer-events-auto' 37 | ] 38 | }, 39 | menu: ({ props }) => ({ 40 | class: [ 41 | // Flexbox & Alignment 42 | 'flex items-center justify-center', 43 | { 44 | 'flex-col': props.position == 'left' || props.position == 'right' 45 | }, 46 | 47 | // List Style 48 | 'm-0 p-0 list-none', 49 | 50 | // Shape 51 | 'outline-none' 52 | ] 53 | }), 54 | menuitem: ({ props, context, instance }) => ({ 55 | class: [ 56 | // Spacing & Shape 57 | 'p-2 rounded-md', 58 | 59 | // Conditional Scaling 60 | { 61 | 'hover:scale-150': instance.currentIndex === context.index, 62 | 'scale-125': instance.currentIndex - 1 === context.index || instance.currentIndex + 1 === context.index, 63 | 'scale-110': instance.currentIndex - 2 === context.index || instance.currentIndex + 2 === context.index 64 | }, 65 | 66 | // Positioning & Hover States 67 | { 68 | 'origin-bottom hover:mx-6': props.position == 'bottom', 69 | 'origin-top hover:mx-6': props.position == 'top', 70 | 'origin-left hover:my-6': props.position == 'left', 71 | 'origin-right hover:my-6': props.position == 'right' 72 | }, 73 | 74 | // Transitions & Transform 75 | 'transition-all duration-200 ease-cubic-bezier-will-change-transform transform' 76 | ] 77 | }), 78 | action: { 79 | class: [ 80 | // Flexbox & Alignment 81 | 'flex flex-col items-center justify-center', 82 | 83 | // Position 84 | 'relative', 85 | 86 | // Size 87 | 'w-16 h-16', 88 | 89 | // Misc 90 | 'cursor-default overflow-hidden' 91 | ] 92 | } 93 | }; 94 | -------------------------------------------------------------------------------- /assets/presets/lara/fieldset/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | 'block', 5 | 6 | // Spacing 7 | 'px-4 pt-2 py-3', 8 | 'inline-size-min', 9 | 10 | // Shape 11 | 'rounded-md', 12 | // Color 13 | 'border border-surface-200 dark:border-surface-700', 14 | 'bg-surface-0 dark:bg-surface-900', 15 | 'text-surface-700 dark:text-surface-0/80' 16 | ] 17 | }, 18 | legend: ({ props }) => ({ 19 | class: [ 20 | // Font 21 | 'font-bold', 22 | 'leading-none', 23 | 24 | //Spacing 25 | { 'p-0': props.toggleable, 'p-5': !props.toggleable }, 26 | 27 | // Shape 28 | 'rounded-md', 29 | 30 | // Color 31 | 'text-surface-700 dark:text-surface-0/80', 32 | 'border border-surface-200 dark:border-surface-700', 33 | 'bg-surface-50 dark:bg-surface-900', 34 | 35 | // Transition 36 | 'transition-none', 37 | 38 | // States 39 | { 'hover:bg-surface-100 hover:border-surface-200 hover:text-surface-900 dark:hover:text-surface-0/80 dark:hover:bg-surface-800/80': props.toggleable } 40 | ] 41 | }), 42 | toggler: ({ props }) => ({ 43 | class: [ 44 | // Alignments 45 | 'flex items-center justify-center', 46 | 'relative', 47 | 48 | //Spacing 49 | { 'p-5': props.toggleable }, 50 | 51 | // Shape 52 | { 'rounded-md': props.toggleable }, 53 | 54 | // Color 55 | { 'text-surface-700 dark:text-surface-200 hover:text-surface-900': props.toggleable }, 56 | 57 | // States 58 | { 'hover:text-surface-900 dark:hover:text-surface-100': props.toggleable }, 59 | { 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-inset focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50': props.toggleable }, 60 | 61 | // Misc 62 | { 63 | 'transition-none cursor-pointer overflow-hidden select-none': props.toggleable 64 | } 65 | ] 66 | }), 67 | togglerIcon: { 68 | class: 'mr-2 inline-block' 69 | }, 70 | legendTitle: { 71 | class: 'flex items-center justify-center leading-none' 72 | }, 73 | content: { 74 | class: 'p-5' 75 | }, 76 | transition: { 77 | enterFromClass: 'max-h-0', 78 | enterActiveClass: 'overflow-hidden transition-[max-height] duration-1000 ease-[cubic-bezier(0.42,0,0.58,1)]', 79 | enterToClass: 'max-h-[1000px]', 80 | leaveFromClass: 'max-h-[1000px]', 81 | leaveActiveClass: 'overflow-hidden transition-[max-height] duration-[450ms] ease-[cubic-bezier(0,1,0,1)]', 82 | leaveToClass: 'max-h-0' 83 | } 84 | }; 85 | -------------------------------------------------------------------------------- /assets/presets/lara/floatlabel/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | 'block relative', 5 | 6 | // Base Label Appearance 7 | '[&>*:last-child]:text-surface-900/60 dark:[&>*:last-child]:text-white/60', 8 | '[&>*:last-child]:absolute', 9 | '[&>*:last-child]:top-1/2', 10 | '[&>*:last-child]:-translate-y-1/2', 11 | '[&>*:last-child]:left-3', 12 | '[&>*:last-child]:pointer-events-none', 13 | '[&>*:last-child]:transition-all', 14 | '[&>*:last-child]:duration-200', 15 | '[&>*:last-child]:ease', 16 | 17 | // Focus Label Appearance 18 | '[&>*:last-child]:has-[:focus]:-top-3', 19 | '[&>*:last-child]:has-[:focus]:text-sm', 20 | 21 | // Filled Input Label Appearance 22 | '[&>*:last-child]:has-[.filled]:-top-3', 23 | '[&>*:last-child]:has-[.filled]:text-sm' 24 | ] 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /assets/presets/lara/global.js: -------------------------------------------------------------------------------- 1 | export default { 2 | css: ` 3 | *[data-pd-ripple="true"]{ 4 | overflow: hidden; 5 | position: relative; 6 | } 7 | span[data-p-ink-active="true"]{ 8 | animation: ripple 0.4s linear; 9 | } 10 | @keyframes ripple { 11 | 100% { 12 | opacity: 0; 13 | transform: scale(2.5); 14 | } 15 | } 16 | 17 | .progress-spinner-circle { 18 | stroke-dasharray: 89, 200; 19 | stroke-dashoffset: 0; 20 | animation: p-progress-spinner-dash 1.5s ease-in-out infinite, p-progress-spinner-color 6s ease-in-out infinite; 21 | stroke-linecap: round; 22 | } 23 | 24 | @keyframes p-progress-spinner-dash{ 25 | 0% { 26 | stroke-dasharray: 1, 200; 27 | stroke-dashoffset: 0; 28 | } 29 | 30 | 50% { 31 | stroke-dasharray: 89, 200; 32 | stroke-dashoffset: -35px; 33 | } 34 | 100% { 35 | stroke-dasharray: 89, 200; 36 | stroke-dashoffset: -124px; 37 | } 38 | } 39 | @keyframes p-progress-spinner-color { 40 | 100%, 0% { 41 | stroke: #ff5757; 42 | } 43 | 40% { 44 | stroke: #696cff; 45 | } 46 | 66% { 47 | stroke: #1ea97c; 48 | } 49 | 80%, 90% { 50 | stroke: #cc8925; 51 | } 52 | } 53 | 54 | .progressbar-value-animate::after { 55 | will-change: left, right; 56 | animation: p-progressbar-indeterminate-anim-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; 57 | } 58 | .progressbar-value-animate::before { 59 | will-change: left, right; 60 | animation: p-progressbar-indeterminate-anim 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; 61 | } 62 | @keyframes p-progressbar-indeterminate-anim { 63 | 0% { 64 | left: -35%; 65 | right: 100%; 66 | } 67 | 60% { 68 | left: 100%; 69 | right: -90%; 70 | } 71 | 100% { 72 | left: 100%; 73 | right: -90%; 74 | } 75 | } 76 | 77 | .p-fadein { 78 | animation: p-fadein 250ms linear; 79 | } 80 | 81 | @keyframes p-fadein { 82 | 0% { 83 | opacity: 0; 84 | } 85 | 100% { 86 | opacity: 1; 87 | } 88 | } 89 | ` 90 | }; 91 | -------------------------------------------------------------------------------- /assets/presets/lara/iconfield/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'relative', 5 | '[&>input]:w-full', 6 | 7 | '[&>*:first-child]:absolute', 8 | '[&>*:first-child]:top-1/2', 9 | '[&>*:first-child]:-mt-2', 10 | '[&>*:first-child]:leading-none', 11 | '[&>*:first-child]:text-surface-900/60 dark:[&>*:first-child]:text-white/60', 12 | { 13 | '[&>*:first-child]:right-3': props.iconPosition === 'right', 14 | '[&>*:first-child]:left-3': props.iconPosition === 'left' 15 | }, 16 | { 17 | '[&>*:last-child]:pr-10': props.iconPosition === 'right', 18 | '[&>*:last-child]:pl-10': props.iconPosition === 'left' 19 | } 20 | ] 21 | }) 22 | }; 23 | -------------------------------------------------------------------------------- /assets/presets/lara/inlinemessage/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'inline-flex items-center justify-center align-top gap-2', 5 | 'p-3 m-0 rounded-md dark:border', 6 | { 7 | 'bg-blue-100/70 dark:bg-blue-500/20': props.severity == 'info', 8 | 'bg-green-100/70 dark:bg-green-500/20': props.severity == 'success', 9 | 'bg-orange-100/70 dark:bg-orange-500/20': props.severity == 'warn', 10 | 'bg-red-100/70 dark:bg-red-500/20': props.severity == 'error' 11 | }, 12 | { 13 | 'dark:border-blue-400': props.severity == 'info', 14 | 'dark:border-green-400': props.severity == 'success', 15 | 'dark:border-orange-400': props.severity == 'warn', 16 | 'dark:border-red-400': props.severity == 'error' 17 | }, 18 | { 19 | 'text-blue-700 dark:text-blue-300': props.severity == 'info', 20 | 'text-green-700 dark:text-green-300': props.severity == 'success', 21 | 'text-orange-700 dark:text-orange-300': props.severity == 'warn', 22 | 'text-red-700 dark:text-red-300': props.severity == 'error' 23 | } 24 | ] 25 | }), 26 | icon: { 27 | class: 'text-base' 28 | }, 29 | text: { 30 | class: [ 31 | // Font and Text 32 | 'text-base leading-none', 33 | 'font-medium' 34 | ] 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /assets/presets/lara/inplace/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | display: { 3 | class: [ 4 | // Display 5 | 'inline', 6 | 7 | // Spacing 8 | 'p-3', 9 | 10 | // Shape 11 | 'rounded-md', 12 | 13 | // Colors 14 | 'text-surface-700 dark:text-white/80', 15 | 16 | // States 17 | 'hover:bg-surface-100 hover:text-surface-700 dark:hover:bg-surface-700/80 dark:hover:text-white/80', 18 | 19 | // Transitions 20 | 'transition', 21 | 'duration-200', 22 | 23 | // Misc 24 | 'cursor-pointer' 25 | ] 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /assets/presets/lara/inputgroup/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: ['flex items-stretch', 'w-full'] 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /assets/presets/lara/inputgroupaddon/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Flex 5 | 'flex items-center justify-center', 6 | 7 | // Shape 8 | 'first:rounded-l-md', 9 | 'last:rounded-r-md', 10 | 'border-y', 11 | 12 | 'last:border-r', 13 | 'border-l', 14 | 'border-r-0', 15 | 16 | // Space 17 | 'p-3', 18 | 19 | // Size 20 | 'min-w-[3rem]', 21 | 22 | // Color 23 | 'bg-surface-50 dark:bg-surface-800', 24 | 'text-surface-600 dark:text-surface-400', 25 | 'border-surface-300 dark:border-surface-600' 26 | ] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /assets/presets/lara/inputmask/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ context, props }) => ({ 3 | class: [ 4 | // Font 5 | 'font-sans leading-none', 6 | 7 | // Spacing 8 | 'm-0 p-3', 9 | 10 | // Colors 11 | 'text-surface-600 dark:text-surface-200', 12 | 'placeholder:text-surface-400 dark:placeholder:text-surface-500', 13 | 'bg-surface-0 dark:bg-surface-900', 14 | 15 | 'border', 16 | { 'border-surface-300 dark:border-surface-600': !props.invalid }, 17 | 18 | // Invalid State 19 | { 'border-red-500 dark:border-red-400': props.invalid }, 20 | 21 | // States 22 | { 23 | 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, 24 | 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50': !context.disabled, 25 | 'opacity-60 select-none pointer-events-none cursor-default': context.disabled 26 | }, 27 | 28 | // Misc 29 | 'rounded-md', 30 | 'appearance-none', 31 | 'transition-colors duration-200' 32 | ] 33 | }) 34 | }; 35 | -------------------------------------------------------------------------------- /assets/presets/lara/inputotp/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Alignment 5 | 'flex items-center', 6 | 'gap-2' 7 | ] 8 | }, 9 | input: { 10 | root: ({ props, context, parent }) => ({ 11 | class: [ 12 | // Font 13 | 'font-sans leading-none', 14 | 15 | // Flex & Alignment 16 | { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, 17 | 'text-center', 18 | 19 | // Spacing 20 | 'm-0', 21 | { 22 | 'p-3': props.size == null 23 | }, 24 | 25 | // Size 26 | 'w-10', 27 | 28 | // Shape 29 | { 'rounded-md': parent.instance.$name !== 'InputGroup' }, 30 | { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' }, 31 | { 'border-0 border-y border-l last:border-r': parent.instance.$name == 'InputGroup' }, 32 | { 'first:ml-0 ml-[-1px]': parent.instance.$name == 'InputGroup' && !props.showButtons }, 33 | 34 | // Colors 35 | 'text-surface-600 dark:text-surface-200', 36 | 'placeholder:text-surface-400 dark:placeholder:text-surface-500', 37 | 'bg-surface-0 dark:bg-surface-900', 38 | 'border', 39 | { 'border-surface-300 dark:border-surface-600': !props.invalid }, 40 | 41 | // Invalid State 42 | { 'border-red-500 dark:border-red-400': props.invalid }, 43 | 44 | // States 45 | { 46 | 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, 47 | 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10': !context.disabled, 48 | 'opacity-60 select-none pointer-events-none cursor-default': context.disabled 49 | }, 50 | 51 | // Filled State *for FloatLabel 52 | { filled: parent.instance?.$name == 'FloatLabel' && context.filled }, 53 | 54 | // Misc 55 | 'appearance-none', 56 | 'transition-colors duration-200' 57 | ] 58 | }) 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /assets/presets/lara/inputswitch/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'inline-block relative', 5 | 'w-12 h-7', 6 | 'rounded-2xl', 7 | { 8 | 'opacity-60 select-none pointer-events-none cursor-default': props.disabled 9 | } 10 | ] 11 | }), 12 | slider: ({ props }) => ({ 13 | class: [ 14 | // Position 15 | 'absolute top-0 left-0 right-0 bottom-0', 16 | { 'before:transform before:translate-x-5': props.modelValue == props.trueValue }, 17 | 18 | // Shape 19 | 'rounded-2xl', 20 | 21 | // Before: 22 | 'before:absolute before:top-1/2 before:left-1', 23 | 'before:-mt-2.5', 24 | 'before:h-5 before:w-5', 25 | 'before:rounded-full', 26 | 'before:duration-200', 27 | 'before:bg-surface-0 before:dark:bg-surface-900', 28 | 29 | // Colors 30 | 'border', 31 | { 32 | 'bg-surface-200 dark:bg-surface-700': !(props.modelValue == props.trueValue), 33 | 'bg-primary-500 dark:bg-primary-400': props.modelValue == props.trueValue 34 | }, 35 | 36 | { 'border-transparent': !props.invalid }, 37 | 38 | // Invalid State 39 | { 'border-red-500 dark:border-red-400': props.invalid }, 40 | 41 | // States 42 | { 'peer-hover:bg-surface-300 dark:peer-hover:bg-surface-600 ': !(props.modelValue == props.trueValue) && !props.disabled }, 43 | { 'peer-hover:bg-primary-600 dark:peer-hover:bg-surface-300 ': props.modelValue == props.trueValue && !props.disabled }, 44 | 'peer-focus-visible:ring peer-focus-visible:ring-primary-400/50 dark:peer-focus-visible:ring-primary-300/50', 45 | 46 | // Transition 47 | 'transition-colors duration-200', 48 | 49 | // Misc 50 | 'cursor-pointer' 51 | ] 52 | }), 53 | input: { 54 | class: [ 55 | 'peer', 56 | 57 | // Size 58 | 'w-full ', 59 | 'h-full', 60 | 61 | // Position 62 | 'absolute', 63 | 'top-0 left-0', 64 | 'z-10', 65 | 66 | // Spacing 67 | 'p-0', 68 | 'm-0', 69 | 70 | // Shape 71 | 'opacity-0', 72 | 'rounded-[2.5rem]', 73 | 'outline-none', 74 | 75 | // Misc 76 | 'appearance-none', 77 | 'cursor-pointer' 78 | ] 79 | } 80 | }; 81 | -------------------------------------------------------------------------------- /assets/presets/lara/inputtext/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props, context, parent }) => ({ 3 | class: [ 4 | // Font 5 | 'font-sans leading-none', 6 | 7 | // Flex 8 | { 'flex-1 w-[1%]': parent.instance.$name == 'InputGroup' }, 9 | 10 | // Spacing 11 | 'm-0', 12 | { 13 | 'px-4 py-4': props.size == 'large', 14 | 'px-2 py-2': props.size == 'small', 15 | 'p-3': props.size == null 16 | }, 17 | 18 | // Shape 19 | { 'rounded-md': parent.instance.$name !== 'InputGroup' }, 20 | { 'first:rounded-l-md rounded-none last:rounded-r-md': parent.instance.$name == 'InputGroup' }, 21 | { 'border-0 border-y border-l last:border-r': parent.instance.$name == 'InputGroup' }, 22 | { 'first:ml-0 -ml-px': parent.instance.$name == 'InputGroup' && !props.showButtons }, 23 | 24 | // Colors 25 | 'text-surface-600 dark:text-surface-200', 26 | 'placeholder:text-surface-400 dark:placeholder:text-surface-500', 27 | 'bg-surface-0 dark:bg-surface-900', 28 | 'border', 29 | { 'border-surface-300 dark:border-surface-600': !props.invalid }, 30 | 31 | // Invalid State 32 | { 'border-red-500 dark:border-red-400': props.invalid }, 33 | 34 | // States 35 | { 36 | 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, 37 | 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50 focus:z-10': !context.disabled, 38 | 'opacity-60 select-none pointer-events-none cursor-default': context.disabled 39 | }, 40 | 41 | // Filled State *for FloatLabel 42 | { filled: parent.instance?.$name == 'FloatLabel' && context.filled }, 43 | 44 | // Misc 45 | 'appearance-none', 46 | 'transition-colors duration-200' 47 | ] 48 | }) 49 | }; 50 | -------------------------------------------------------------------------------- /assets/presets/lara/knob/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Misc 5 | { 'opacity-60 select-none pointer-events-none cursor-default': props.disabled } 6 | ] 7 | }), 8 | range: { 9 | class: [ 10 | // Stroke 11 | 'stroke-current', 12 | 13 | // Color 14 | 'stroke-surface-200 dark:stroke-surface-700', 15 | 16 | // Fill 17 | 'fill-none', 18 | 19 | // Transition 20 | 'transition duration-100 ease-in' 21 | ] 22 | }, 23 | value: { 24 | class: [ 25 | // Animation 26 | 'animate-dash-frame', 27 | 28 | // Color 29 | 'stroke-primary-500 dark:stroke-primary-400', 30 | 31 | // Fill 32 | 'fill-none' 33 | ] 34 | }, 35 | label: { 36 | class: [ 37 | // Text Style 38 | 'text-center text-xl', 39 | 40 | // Color 41 | 'fill-surface-600 dark:fill-surface-200' 42 | ] 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /assets/presets/lara/menu/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Sizing and Shape 5 | 'min-w-[12rem]', 6 | 'rounded-md', 7 | // Spacing 8 | 'py-2', 9 | // Colors 10 | 'bg-surface-0 dark:bg-surface-700', 11 | 'text-surface-700 dark:text-white/80', 12 | 'border border-surface-200 dark:border-surface-700' 13 | ] 14 | }, 15 | menu: { 16 | class: [ 17 | // Spacings and Shape 18 | 'list-none', 19 | 'm-0', 20 | 'p-0', 21 | 'outline-none' 22 | ] 23 | }, 24 | content: ({ context }) => ({ 25 | class: [ 26 | //Shape 27 | 'rounded-none', 28 | // Colors 29 | 'text-surface-700 dark:text-white/80', 30 | { 31 | 'bg-surface-200 text-surface-700 dark:bg-surface-300/10 dark:text-white': context.focused 32 | }, 33 | // Transitions 34 | 'transition-shadow', 35 | 'duration-200', 36 | // States 37 | 'hover:text-surface-700 dark:hover:text-white/80', 38 | 'hover:bg-surface-100 dark:bg-surface-700 dark:hover:bg-surface-400/10' 39 | ] 40 | }), 41 | action: { 42 | class: [ 43 | 'relative', 44 | // Flexbox 45 | 46 | 'flex', 47 | 'items-center', 48 | 49 | // Spacing 50 | 'py-3', 51 | 'px-5', 52 | 53 | // Color 54 | 'text-surface-700 dark:text-white/80', 55 | 56 | // Misc 57 | 'no-underline', 58 | 'overflow-hidden', 59 | 'cursor-pointer', 60 | 'select-none' 61 | ] 62 | }, 63 | icon: { 64 | class: [ 65 | // Spacing 66 | 'mr-2', 67 | 68 | // Color 69 | 'text-surface-600 dark:text-white/70' 70 | ] 71 | }, 72 | label: { 73 | class: ['leading-none'] 74 | }, 75 | submenuheader: { 76 | class: [ 77 | // Font 78 | 'font-bold', 79 | // Spacing 80 | 'm-0', 81 | 'py-3 px-5', 82 | // Shape 83 | 'rounded-tl-none', 84 | 'rounded-tr-none', 85 | // Colors 86 | 'bg-surface-0 dark:bg-surface-700', 87 | 'text-surface-700 dark:text-white' 88 | ] 89 | }, 90 | transition: { 91 | enterFromClass: 'opacity-0 scale-y-[0.8]', 92 | enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', 93 | leaveActiveClass: 'transition-opacity duration-100 ease-linear', 94 | leaveToClass: 'opacity-0' 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /assets/presets/lara/message/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Spacing and Shape 5 | 'my-4 mx-0', 6 | 'rounded-md', 7 | 'border-solid border-0 border-l-[6px]', 8 | 9 | // Colors 10 | { 11 | 'bg-blue-100/70 dark:bg-blue-500/20': props.severity == 'info', 12 | 'bg-green-100/70 dark:bg-green-500/20': props.severity == 'success', 13 | 'bg-orange-100/70 dark:bg-orange-500/20': props.severity == 'warn', 14 | 'bg-red-100/70 dark:bg-red-500/20': props.severity == 'error' 15 | }, 16 | { 17 | 'border-blue-500 dark:border-blue-400': props.severity == 'info', 18 | 'border-green-500 dark:border-green-400': props.severity == 'success', 19 | 'border-orange-500 dark:border-orange-400': props.severity == 'warn', 20 | 'border-red-500 dark:border-red-400': props.severity == 'error' 21 | }, 22 | { 23 | 'text-blue-700 dark:text-blue-300': props.severity == 'info', 24 | 'text-green-700 dark:text-green-300': props.severity == 'success', 25 | 'text-orange-700 dark:text-orange-300': props.severity == 'warn', 26 | 'text-red-700 dark:text-red-300': props.severity == 'error' 27 | } 28 | ] 29 | }), 30 | wrapper: { 31 | class: [ 32 | // Flexbox 33 | 'flex items-center', 34 | 35 | // Spacing 36 | 'py-5 px-7' 37 | ] 38 | }, 39 | icon: { 40 | class: [ 41 | // Sizing and Spacing 42 | 'w-6 h-6', 43 | 'text-lg leading-none mr-2 shrink-0' 44 | ] 45 | }, 46 | text: { 47 | class: [ 48 | // Font and Text 49 | 'text-base leading-none', 50 | 'font-medium' 51 | ] 52 | }, 53 | button: { 54 | class: [ 55 | // Flexbox 56 | 'flex items-center justify-center', 57 | 58 | // Size 59 | 'w-8 h-8', 60 | 61 | // Spacing and Misc 62 | 'ml-auto relative', 63 | 64 | // Shape 65 | 'rounded-full', 66 | 67 | // Colors 68 | 'bg-transparent', 69 | 70 | // Transitions 71 | 'transition duration-200 ease-in-out', 72 | 73 | // States 74 | 'hover:bg-surface-0/50 dark:hover:bg-surface-0/10', 75 | 76 | // Misc 77 | 'overflow-hidden' 78 | ] 79 | }, 80 | transition: { 81 | enterFromClass: 'opacity-0', 82 | enterActiveClass: 'transition-opacity duration-300', 83 | leaveFromClass: 'max-h-40', 84 | leaveActiveClass: 'overflow-hidden transition-all duration-300 ease-in', 85 | leaveToClass: 'max-h-0 opacity-0 !m-0' 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /assets/presets/lara/metergroup/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Flexbox 5 | 'flex gap-4', 6 | 7 | { 'flex-col': props.orientation == 'horizontal', 'flex-row': props.orientation == 'vertical' } 8 | ] 9 | }), 10 | metercontainer: ({ props }) => ({ 11 | class: [ 12 | // Flexbox 13 | 'flex', 14 | 15 | { 'flex-col': props.orientation === 'vertical' }, 16 | 17 | // Sizing 18 | { 'w-2 h-full': props.orientation === 'vertical' }, 19 | { 'h-2': props.orientation === 'horizontal' }, 20 | 21 | // Colors 22 | 'bg-gray-200 dark:bg-gray-700', 23 | 24 | // Border Radius 25 | 'rounded-lg' 26 | ] 27 | }), 28 | meter: ({ props }) => ({ 29 | class: [ 30 | // Shape 31 | 'border-0', 32 | 33 | // Rounded Corners - Horizontal 34 | { 35 | 'first:rounded-l-lg last:rounded-r-lg': props.orientation === 'horizontal' 36 | }, 37 | 38 | // Rounded Corners - Vertical 39 | { 40 | 'first:rounded-t-lg last:rounded-b-lg': props.orientation === 'vertical' 41 | }, 42 | 43 | // Colors 44 | 'bg-primary-500 dark:bg-primary-400' 45 | ] 46 | }), 47 | labellist: ({ props }) => ({ 48 | class: [ 49 | // Display & Flexbox 50 | 'flex flex-wrap', 51 | 52 | { 'gap-4': props.labelOrientation === 'horizontal' }, 53 | 54 | { 'gap-2': props.labelOrientation === 'vertical' }, 55 | 56 | { 'flex-col': props.labelOrientation === 'vertical' }, 57 | 58 | // Conditional Alignment - Horizontal 59 | { 60 | 'align-end': props.labelOrientation === 'horizontal' && props.labelPosition === 'end', 61 | 'align-start': props.labelOrientation === 'horizontal' && props.labelPosition === 'start' 62 | }, 63 | 64 | // Conditional Alignment - Vertical 65 | { 66 | 'justify-end': props.labelOrientation === 'vertical' && props.labelPosition === 'end', 67 | 'justify-start': props.labelOrientation === 'vertical' && props.labelPosition === 'start' 68 | }, 69 | 70 | // List Styling 71 | 'm-0 p-0 list-none' 72 | ] 73 | }), 74 | labellistitem: { 75 | class: [ 76 | // Flexbox 77 | 'inline-flex', 78 | 'items-center', 79 | 'gap-2' 80 | ] 81 | }, 82 | labellisttype: { 83 | class: [ 84 | // Display 85 | 'inline-flex', 86 | 87 | // Background Color 88 | 'bg-primary-500 dark:bg-primary-400', 89 | 90 | // Size 91 | 'w-2 h-2', 92 | 93 | // Rounded Shape 94 | 'rounded-full' 95 | ] 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /assets/presets/lara/overlaypanel/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Shape 5 | 'rounded-md shadow-lg', 6 | 'border-0 dark:border', 7 | 8 | // Position 9 | 'absolute left-0 top-0 mt-2', 10 | 'z-40 transform origin-center', 11 | 12 | // Color 13 | 'bg-surface-0 dark:bg-surface-800', 14 | 'text-surface-700 dark:text-surface-0/80', 15 | 'dark:border-surface-700', 16 | 17 | // Before: Triangle 18 | 'before:absolute before:-top-[9px] before:-ml-[9px] before:left-[calc(var(--overlayArrowLeft,0)+1.25rem)] z-0', 19 | 'before:w-0 before:h-0', 20 | 'before:border-transparent before:border-solid', 21 | 'before:border-x-[8px] before:border-[8px]', 22 | 'before:border-t-0 before:border-b-surface-300/10 dark:before:border-b-surface-700', 23 | 24 | 'after:absolute after:-top-2 after:-ml-[8px] after:left-[calc(var(--overlayArrowLeft,0)+1.25rem)]', 25 | 'after:w-0 after:h-0', 26 | 'after:border-transparent after:border-solid', 27 | 'after:border-x-[0.5rem] after:border-[0.5rem]', 28 | 'after:border-t-0 after:border-b-surface-0 dark:after:border-b-surface-800' 29 | ] 30 | }, 31 | content: { 32 | class: 'p-5 items-center flex' 33 | }, 34 | transition: { 35 | enterFromClass: 'opacity-0 scale-y-[0.8]', 36 | enterActiveClass: 'transition-[transform,opacity] duration-[120ms] ease-[cubic-bezier(0,0,0.2,1)]', 37 | leaveActiveClass: 'transition-opacity duration-100 ease-linear', 38 | leaveToClass: 'opacity-0' 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /assets/presets/lara/panel/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | header: ({ props }) => ({ 3 | class: [ 4 | // Flex 5 | 'flex items-center justify-between', 6 | 7 | // Colors 8 | 'text-surface-700 dark:text-surface-0/80', 9 | 'bg-surface-50 dark:bg-surface-900', 10 | 'border border-surface-200 dark:border-surface-700', 11 | 12 | //Shape 13 | 'rounded-tl-lg rounded-tr-lg', 14 | 15 | // Conditional Spacing 16 | { 'p-5': !props.toggleable, 'py-3 px-5': props.toggleable } 17 | ] 18 | }), 19 | title: { 20 | class: 'leading-none font-bold' 21 | }, 22 | toggler: { 23 | class: [ 24 | // Alignments 25 | 'inline-flex items-center justify-center', 26 | 'relative', 27 | 28 | // Sized 29 | 'w-8 h-8', 30 | 'm-0 p-0', 31 | 32 | //Shape 33 | 'border-0 rounded-full', 34 | 35 | //Color 36 | 'bg-transparent', 37 | 'text-surface-600 dark:text-surface-0/80', 38 | 39 | // States 40 | 'hover:text-surface-800 dark:hover:text-surface-0/80', 41 | 'hover:bg-surface-100 dark:hover:bg-surface-800/80', 42 | 'focus:outline-none focus:outline-offset-0 focus-visible:ring focus-visible:ring-primary-400/50 focus-visible:ring-inset dark:focus-visible:ring-primary-300/50', 43 | 44 | // Transitions 45 | 'transition-all duration-200 ease-in-out', 46 | 47 | // Misc 48 | 'overflow-hidden no-underline', 49 | 'cursor-pointer' 50 | ] 51 | }, 52 | togglerIcon: { 53 | class: 'inline-block' 54 | }, 55 | content: { 56 | class: [ 57 | // Spacing 58 | 'p-5', 59 | 60 | // Shape 61 | 'border border-t-0 last:rounded-br-lg last:rounded-bl-lg', 62 | 63 | //Color 64 | 'border-surface-200 dark:border-surface-700', 65 | 'bg-surface-0 dark:bg-surface-900', 66 | 'text-surface-700 dark:text-surface-0/80' 67 | ] 68 | }, 69 | footer: { 70 | class: [ 71 | // Spacing 72 | 'py-3 p-5', 73 | 74 | // Shape 75 | 'border border-t-0 rounded-br-lg rounded-bl-lg', 76 | 77 | //Color 78 | 'border-surface-200 dark:border-surface-700', 79 | 'bg-surface-0 dark:bg-surface-900', 80 | 'text-surface-700 dark:text-surface-0/80' 81 | ] 82 | }, 83 | transition: { 84 | enterFromClass: 'max-h-0', 85 | enterActiveClass: 'overflow-hidden transition-[max-height] duration-1000 ease-[cubic-bezier(0.42,0,0.58,1)]', 86 | enterToClass: 'max-h-[1000px]', 87 | leaveFromClass: 'max-h-[1000px]', 88 | leaveActiveClass: 'overflow-hidden transition-[max-height] duration-[450ms] ease-[cubic-bezier(0,1,0,1)]', 89 | leaveToClass: 'max-h-0' 90 | } 91 | }; 92 | -------------------------------------------------------------------------------- /assets/presets/lara/progressbar/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Position and Overflow 5 | 'overflow-hidden', 6 | 'relative', 7 | 8 | // Shape and Size 9 | 'border-0', 10 | 'h-6', 11 | 'rounded-md', 12 | 13 | // Colors 14 | 'bg-surface-100 dark:bg-surface-700' 15 | ] 16 | }, 17 | value: ({ props }) => ({ 18 | class: [ 19 | // Flexbox & Overflow & Position 20 | { 'absolute flex items-center justify-center overflow-hidden': props.mode !== 'indeterminate' }, 21 | 22 | // Colors 23 | 'bg-primary-500 dark:bg-primary-400', 24 | 25 | // Spacing & Sizing 26 | 'm-0', 27 | { 'h-full w-0': props.mode !== 'indeterminate' }, 28 | 29 | // Shape 30 | 'border-0', 31 | 32 | // Transitions 33 | { 34 | 'transition-width duration-1000 ease-in-out': props.mode !== 'indeterminate', 35 | 'progressbar-value-animate': props.mode == 'indeterminate' 36 | }, 37 | 38 | // Before & After (indeterminate) 39 | { 40 | 'before:absolute before:top-0 before:left-0 before:bottom-0 before:bg-inherit ': props.mode == 'indeterminate', 41 | 'after:absolute after:top-0 after:left-0 after:bottom-0 after:bg-inherit after:delay-1000': props.mode == 'indeterminate' 42 | } 43 | ] 44 | }), 45 | label: { 46 | class: [ 47 | // Flexbox 48 | 'inline-flex', 49 | 50 | // Font and Text 51 | 'text-white dark:text-surface-900', 52 | 'leading-6' 53 | ] 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /assets/presets/lara/progressspinner/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Position 5 | 'relative', 6 | 'mx-auto', 7 | 8 | // Sizing 9 | 'w-28', 10 | 'h-28', 11 | 12 | // Flexbox 13 | 'inline-block', 14 | 15 | // Pseudo-Elements 16 | 'before:block', 17 | 'before:pt-full' 18 | ] 19 | }, 20 | spinner: { 21 | class: [ 22 | // Position 23 | 'absolute', 24 | 'top-0', 25 | 'bottom-0', 26 | 'left-0', 27 | 'right-0', 28 | 'm-auto', 29 | 30 | // Sizing 31 | 'w-full', 32 | 'h-full', 33 | 34 | // Transformations 35 | 'transform', 36 | 'origin-center', 37 | 38 | // Animations 39 | 'animate-spin' 40 | ] 41 | }, 42 | circle: { 43 | class: [ 44 | // Colors 45 | 'text-red-500', 46 | 47 | // Misc 48 | 'progress-spinner-circle' 49 | ] 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /assets/presets/lara/rating/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'relative', 5 | 6 | // Flex & Alignment 7 | 'flex items-center', 8 | 'gap-2', 9 | 10 | // Misc 11 | { 12 | 'opacity-60 select-none pointer-events-none cursor-default': props.disabled 13 | } 14 | ] 15 | }), 16 | cancelitem: ({ context }) => ({ 17 | class: [ 18 | // Flex & Alignment 19 | 'inline-flex items-center', 20 | 21 | //State 22 | { 23 | 'outline-none ring ring-primary-500/50 dark:ring-primary-400/50': context.focused 24 | }, 25 | 26 | // Misc 27 | 'cursor-pointer' 28 | ] 29 | }), 30 | cancelicon: { 31 | class: [ 32 | // Size 33 | 'w-5 h-5', 34 | 35 | // Color 36 | 'text-red-500 dark:text-red-400', 37 | 38 | // State 39 | 'hover:text-red-600 dark:hover:text-red-300', 40 | 41 | // Transition 42 | 'transition duration-200 ease-in' 43 | ] 44 | }, 45 | item: ({ props, context }) => ({ 46 | class: [ 47 | // Flex & Alignment 48 | 'inline-flex items-center', 49 | 50 | // State 51 | { 52 | 'outline-none ring ring-primary-500/50 dark:ring-primary-400/50': context.focused 53 | }, 54 | 55 | // Misc 56 | { 57 | 'cursor-pointer': !props.readonly, 58 | 'cursor-default': props.readonly 59 | } 60 | ] 61 | }), 62 | officon: ({ props }) => ({ 63 | class: [ 64 | // Size 65 | 'w-5 h-5', 66 | 67 | // Color 68 | 'text-surface-700 dark:text-surface-0/80', 69 | 70 | // State 71 | { 'hover:text-primary-500 dark:hover:text-primary-400': !props.readonly }, 72 | 73 | // Transition 74 | 'transition duration-200 ease-in' 75 | ] 76 | }), 77 | onicon: ({ props }) => ({ 78 | class: [ 79 | // Size 80 | 'w-5 h-5', 81 | 82 | // Color 83 | 'text-primary-500 dark:text-primary-400', 84 | 85 | // State 86 | { 'hover:text-primary-600 dark:hover:text-primary-300': !props.readonly }, 87 | 88 | // Transition 89 | 'transition duration-200 ease-in' 90 | ] 91 | }) 92 | }; 93 | -------------------------------------------------------------------------------- /assets/presets/lara/ripple/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: ['block absolute bg-surface-0/50 rounded-full pointer-events-none'], 4 | style: 'transform: scale(0)' 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /assets/presets/lara/scrollpanel/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | wrapper: { 3 | class: [ 4 | // Size & Position 5 | 'h-full w-full', 6 | 7 | // Layering 8 | 'z-[1]', 9 | 10 | // Spacing 11 | 'overflow-hidden', 12 | 13 | // Misc 14 | 'relative float-left' 15 | ] 16 | }, 17 | content: { 18 | class: [ 19 | // Size & Spacing 20 | 'h-[calc(100%+18px)] w-[calc(100%+18px)] pr-[18px] pb-[18px] pl-0 pt-0', 21 | 22 | // Overflow & Scrollbar 23 | 'overflow-scroll scrollbar-none', 24 | 25 | // Box Model 26 | 'box-border', 27 | 28 | // Position 29 | 'relative', 30 | 31 | // Webkit Specific 32 | '[&::-webkit-scrollbar]:hidden' 33 | ] 34 | }, 35 | barX: { 36 | class: [ 37 | // Size & Position 38 | 'h-[9px] bottom-0', 39 | 40 | // Appearance 41 | 'bg-surface-50 dark:bg-surface-700 rounded', 42 | 43 | // Interactivity 44 | 'cursor-pointer', 45 | 46 | // Visibility & Layering 47 | 'invisible z-20', 48 | 49 | // Transition 50 | 'transition duration-[250ms] ease-linear', 51 | 52 | // Misc 53 | 'relative' 54 | ] 55 | }, 56 | barY: { 57 | class: [ 58 | // Size & Position 59 | 'w-[9px] top-0', 60 | 61 | // Appearance 62 | 'bg-surface-50 dark:bg-surface-700 rounded', 63 | 64 | // Interactivity 65 | 'cursor-pointer', 66 | 67 | // Visibility & Layering 68 | 'z-20', 69 | 70 | // Transition 71 | 'transition duration-[250ms] ease-linear', 72 | 73 | // Misc 74 | 'relative' 75 | ] 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /assets/presets/lara/scrolltop/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | // Flex & Alignment 5 | 'flex items-center justify-center', 6 | 7 | // Positioning 8 | { 9 | sticky: props.target === 'parent', 10 | fixed: props.target === 'window' 11 | }, 12 | 'bottom-[20px] right-[20px]', 13 | 'ml-auto', 14 | 15 | // Shape & Size 16 | { 17 | 'rounded-md h-8 w-8': props.target === 'parent', 18 | 'h-12 w-12 rounded-full shadow-md': props.target === 'window' 19 | }, 20 | 21 | // Color 22 | 'text-white dark:text-surface-900', 23 | { 24 | 'bg-primary-500 dark:bg-primary-400 hover:bg-primary-600 dark:hover:bg-primary-300': props.target === 'parent', 25 | 'bg-surface-500 dark:bg-surface-400 hover:bg-surface-600 dark:hover:bg-surface-300': props.target === 'window' 26 | }, 27 | 28 | // States 29 | { 30 | 'hover:bg-primary-600 dark:hover:bg-primary-300': props.target === 'parent', 31 | 'hover:bg-surface-600 dark:hover:bg-surface-300': props.target === 'window' 32 | } 33 | ] 34 | }), 35 | transition: { 36 | enterFromClass: 'opacity-0', 37 | enterActiveClass: 'transition-opacity duration-150', 38 | leaveActiveClass: 'transition-opacity duration-150', 39 | leaveToClass: 'opacity-0' 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /assets/presets/lara/selectbutton/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [{ 'opacity-60 select-none pointer-events-none cursor-default': props.disabled }] 4 | }), 5 | button: ({ context, props }) => ({ 6 | class: [ 7 | 'relative', 8 | // Font 9 | 'leading-none', 10 | 11 | // Flex Alignment 12 | 'inline-flex items-center align-bottom text-center', 13 | 14 | // Spacing 15 | 'px-4 py-3', 16 | 17 | // Shape 18 | 'border border-r-0', 19 | 'first:rounded-l-md first:rounded-tr-none first:rounded-br-none', 20 | 'last:border-r last:rounded-tl-none last:rounded-bl-none last:rounded-r-md', 21 | 22 | // Color 23 | { 24 | 'bg-surface-0 dark:bg-surface-900': !context.active, 25 | 'text-surface-700 dark:text-white/80': !context.active, 26 | 'border-surface-200 dark:border-surface-700': !context.active && !props.invalid, 27 | 'bg-primary-500 dark:bg-primary-400 border-primary-500 dark:border-primary-400 text-white dark:text-surface-900': context.active 28 | }, 29 | // Invalid State 30 | { 'border-red-500 dark:border-red-400': props.invalid }, 31 | 32 | // States 33 | 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-400/50 dark:focus:ring-primary-300/50 focus:z-10', 34 | { 35 | 'hover:bg-surface-50 dark:hover:bg-surface-800/80': !context.active && !props.invalid, 36 | 'hover:bg-primary-600 dark:hover:bg-primary-300': context.active 37 | }, 38 | { 'opacity-60 select-none pointer-events-none cursor-default': context.disabled }, 39 | // Transition 40 | 'transition duration-200', 41 | 42 | // Misc 43 | 'cursor-pointer select-none overflow-hidden' 44 | ] 45 | }), 46 | label: { 47 | class: 'font-bold' 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /assets/presets/lara/skeleton/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'overflow-hidden', 5 | { 6 | 'animate-pulse': props.animation !== 'none' 7 | }, 8 | 9 | // Round 10 | { 'rounded-full': props.shape === 'circle', 'rounded-md': props.shape !== 'circle' }, 11 | 12 | // Colors 13 | 'bg-surface-200 dark:bg-surface-700' 14 | ] 15 | }) 16 | }; 17 | -------------------------------------------------------------------------------- /assets/presets/lara/splitter/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ context }) => ({ 3 | class: [ 4 | // Colors 5 | 'bg-surface-0', 6 | 'dark:bg-surface-900', 7 | 'text-surface-700', 8 | 'dark:text-surface-0/80', 9 | 10 | // Shape 11 | 'rounded-lg', 12 | 13 | // Borders (Conditional) 14 | { 'border border-solid border-surface-50 dark:border-surface-700': !context.nested }, 15 | 16 | // Nested 17 | { 'flex grow border-0': context.nested } 18 | ] 19 | }), 20 | 21 | gutter: ({ props }) => ({ 22 | class: [ 23 | // Flexbox 24 | 'flex', 25 | 'items-center', 26 | 'justify-center', 27 | 'shrink-0', 28 | 29 | // Colors 30 | 'bg-surface-50', 31 | 'dark:bg-surface-800', 32 | 33 | // Transitions 34 | 'transition-all', 35 | 'duration-200', 36 | 37 | // Misc 38 | { 39 | 'cursor-col-resize': props.layout == 'horizontal', 40 | 'cursor-row-resize': props.layout !== 'horizontal' 41 | } 42 | ] 43 | }), 44 | gutterhandler: ({ props }) => ({ 45 | class: [ 46 | // Colors 47 | 'bg-surface-100', 48 | 'dark:bg-surface-600', 49 | 50 | // Transitions 51 | 'transition-all', 52 | 'duration-200', 53 | 54 | // Sizing (Conditional) 55 | { 56 | 'h-7': props.layout == 'horizontal', 57 | 'w-7 h-2': props.layout !== 'horizontal' 58 | } 59 | ] 60 | }) 61 | }; 62 | -------------------------------------------------------------------------------- /assets/presets/lara/tabmenu/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: 'overflow-x-auto' 4 | }, 5 | menu: { 6 | class: [ 7 | // Flexbox 8 | 'flex flex-1', 9 | 10 | // Spacing 11 | 'list-none', 12 | 'p-0 m-0', 13 | 14 | // Colors 15 | 'bg-surface-0 dark:bg-surface-800', 16 | 'border-b-2 border-surface-200 dark:border-surface-700', 17 | 'text-surface-900 dark:text-surface-0/80' 18 | ] 19 | }, 20 | menuitem: { 21 | class: 'mr-0' 22 | }, 23 | action: ({ context, state }) => ({ 24 | class: [ 25 | 'relative', 26 | 27 | // Font 28 | 'font-bold', 29 | 30 | // Flexbox and Alignment 31 | 'flex items-center', 32 | 33 | // Spacing 34 | 'p-5', 35 | '-mb-[2px]', 36 | 37 | // Shape 38 | 'border-b-2', 39 | 'rounded-t-md', 40 | 41 | // Colors and Conditions 42 | { 43 | 'border-surface-200 dark:border-surface-700': state.d_activeIndex !== context.index, 44 | 'bg-surface-0 dark:bg-surface-800': state.d_activeIndex !== context.index, 45 | 'text-surface-700 dark:text-surface-0/80': state.d_activeIndex !== context.index, 46 | 47 | 'bg-surface-0 dark:bg-surface-800': state.d_activeIndex === context.index, 48 | 'border-primary-500 dark:border-primary-400': state.d_activeIndex === context.index, 49 | 'text-primary-500 dark:text-primary-400': state.d_activeIndex === context.index 50 | }, 51 | 52 | // States 53 | 'focus-visible:outline-none focus-visible:outline-offset-0 focus-visible:ring focus-visible:ring-inset', 54 | 'focus-visible:ring-primary-400/50 dark:focus-visible:ring-primary-300/50', 55 | { 56 | 'hover:bg-surface-0 dark:hover:bg-surface-800/80': state.d_activeIndex !== context.index, 57 | 'hover:border-surface-400 dark:hover:border-primary-400': state.d_activeIndex !== context.index, 58 | 'hover:text-surface-900 dark:hover:text-surface-0': state.d_activeIndex !== context.index 59 | }, 60 | 61 | // Transitions 62 | 'transition-all duration-200', 63 | 64 | // Misc 65 | 'cursor-pointer select-none text-decoration-none', 66 | 'overflow-hidden', 67 | 'user-select-none' 68 | ] 69 | }), 70 | icon: { 71 | class: 'mr-2' 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /assets/presets/lara/tag/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | //Font 5 | 'text-xs font-bold', 6 | 7 | //Alignments 8 | 'inline-flex items-center justify-center', 9 | 10 | //Spacing 11 | 'px-2 py-1', 12 | 13 | //Shape 14 | { 15 | 'rounded-md': !props.rounded, 16 | 'rounded-full': props.rounded 17 | }, 18 | 19 | //Colors 20 | 'text-white dark:text-surface-900', 21 | { 22 | 'bg-primary-500 dark:bg-primary-400': props.severity == null || props.severity == 'primary', 23 | 'bg-green-500 dark:bg-green-400': props.severity == 'success', 24 | 'bg-blue-500 dark:bg-blue-400': props.severity == 'info', 25 | 'bg-orange-500 dark:bg-orange-400': props.severity == 'warning', 26 | 'bg-red-500 dark:bg-red-400': props.severity == 'danger' 27 | } 28 | ] 29 | }), 30 | value: { 31 | class: 'leading-normal' 32 | }, 33 | icon: { 34 | class: 'mr-1 text-sm' 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /assets/presets/lara/terminal/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Spacing 5 | 'p-5', 6 | 7 | // Shape 8 | 'rounded-md', 9 | 10 | // Color 11 | 'bg-surface-900 text-white', 12 | 'border border-surface-700', 13 | 14 | // Sizing & Overflow 15 | 'h-72 overflow-auto' 16 | ] 17 | }, 18 | container: { 19 | class: [ 20 | // Flexbox 21 | 'flex items-center' 22 | ] 23 | }, 24 | prompt: { 25 | class: [ 26 | // Color 27 | 'text-surface-400' 28 | ] 29 | }, 30 | response: { 31 | class: [ 32 | // Color 33 | 'text-primary-400' 34 | ] 35 | }, 36 | command: { 37 | class: [ 38 | // Color 39 | 'text-primary-400' 40 | ] 41 | }, 42 | commandtext: { 43 | class: [ 44 | // Flexbox 45 | 'flex-1 shrink grow-0', 46 | 47 | // Shape 48 | 'border-0', 49 | 50 | // Spacing 51 | 'p-0', 52 | 53 | // Color 54 | 'bg-transparent text-inherit', 55 | 56 | // Outline 57 | 'outline-none' 58 | ] 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /assets/presets/lara/textarea/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ context, props }) => ({ 3 | class: [ 4 | // Font 5 | 'font-sans leading-none', 6 | 7 | // Spacing 8 | 'm-0', 9 | 'p-3', 10 | 11 | // Shape 12 | 'rounded-md', 13 | 14 | // Colors 15 | 'text-surface-600 dark:text-surface-200', 16 | 'placeholder:text-surface-400 dark:placeholder:text-surface-500', 17 | 'bg-surface-0 dark:bg-surface-900', 18 | 'border', 19 | { 'border-surface-300 dark:border-surface-600': !props.invalid }, 20 | 21 | // Invalid State 22 | { 'border-red-500 dark:border-red-400': props.invalid }, 23 | 24 | // States 25 | { 26 | 'hover:border-primary-500 dark:hover:border-primary-400': !context.disabled && !props.invalid, 27 | 'focus:outline-none focus:outline-offset-0 focus:ring focus:ring-primary-500/50 dark:focus:ring-primary-400/50': !context.disabled, 28 | 'opacity-60 select-none pointer-events-none cursor-default': context.disabled 29 | }, 30 | 31 | // Misc 32 | 'appearance-none', 33 | 'transition-colors duration-200' 34 | ] 35 | }) 36 | }; 37 | -------------------------------------------------------------------------------- /assets/presets/lara/timeline/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | 'flex grow', 5 | { 6 | 'flex-col': props.layout === 'vertical', 7 | 'flex-row flex-1': props.layout === 'horizontal' 8 | } 9 | ] 10 | }), 11 | event: ({ props, context }) => ({ 12 | class: [ 13 | 'flex relative min-h-[70px]', 14 | { 15 | 'flex-row-reverse': props.align === 'right' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 1), 16 | 'flex-col flex-1': props.layout === 'horizontal', 17 | 'flex-col-reverse ': props.align === 'bottom' || (props.layout === 'horizontal' && props.align === 'alternate' && context.index % 2 === 1) 18 | } 19 | ] 20 | }), 21 | opposite: ({ props, context }) => ({ 22 | class: [ 23 | 'flex-1', 24 | { 25 | 'px-4': props.layout === 'vertical', 26 | 'py-4': props.layout === 'horizontal' 27 | }, 28 | { 29 | 'text-right': props.align === 'left' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 0), 30 | 'text-left': props.align === 'right' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 1) 31 | } 32 | ] 33 | }), 34 | separator: ({ props }) => ({ 35 | class: [ 36 | 'flex items-center flex-initial', 37 | { 38 | 'flex-col': props.layout === 'vertical', 39 | 'flex-row': props.layout === 'horizontal' 40 | } 41 | ] 42 | }), 43 | marker: { 44 | class: [ 45 | // Display & Flexbox 46 | 'flex self-baseline', 47 | 48 | // Size 49 | 'w-4 h-4', 50 | 51 | // Appearance 52 | 'rounded-full border-2 border-primary-500 bg-surface-0 dark:border-primary-300 dark:bg-surface-900/40' 53 | ] 54 | }, 55 | connector: ({ props }) => ({ 56 | class: [ 57 | 'grow bg-surface-300 dark:bg-surface-700', 58 | { 59 | 'w-[2px]': props.layout === 'vertical', 60 | 'w-full h-[2px]': props.layout === 'horizontal' 61 | } 62 | ] 63 | }), 64 | content: ({ props, context }) => ({ 65 | class: [ 66 | 'flex-1', 67 | { 68 | 'px-4': props.layout === 'vertical', 69 | 'py-4': props.layout === 'horizontal' 70 | }, 71 | { 72 | 'text-left': props.align === 'left' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 0), 73 | 'text-right': props.align === 'right' || (props.layout === 'vertical' && props.align === 'alternate' && context.index % 2 === 1) 74 | }, 75 | { 76 | 'min-h-0': props.layout === 'vertical' && context.index === context.count, 77 | 'grow-0': props.layout === 'horizontal' && context.index === context.count 78 | } 79 | ] 80 | }) 81 | }; 82 | -------------------------------------------------------------------------------- /assets/presets/lara/toast/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ props }) => ({ 3 | class: [ 4 | //Size and Shape 5 | 'w-96 rounded-md', 6 | 7 | // Positioning 8 | { '-translate-x-2/4': props.position == 'top-center' || props.position == 'bottom-center' } 9 | ] 10 | }), 11 | container: ({ props }) => ({ 12 | class: [ 13 | 'my-4 rounded-md w-full', 14 | 'border-solid border-0 border-l-[6px]', 15 | 'backdrop-blur-[10px] shadow-md', 16 | 17 | // Colors 18 | { 19 | 'bg-blue-100/70 dark:bg-blue-500/20': props.message.severity == 'info', 20 | 'bg-green-100/70 dark:bg-green-500/20': props.message.severity == 'success', 21 | 'bg-orange-100/70 dark:bg-orange-500/20': props.message.severity == 'warn', 22 | 'bg-red-100/70 dark:bg-red-500/20': props.message.severity == 'error' 23 | }, 24 | { 25 | 'border-blue-500 dark:border-blue-400': props.message.severity == 'info', 26 | 'border-green-500 dark:border-green-400': props.message.severity == 'success', 27 | 'border-orange-500 dark:border-orange-400': props.message.severity == 'warn', 28 | 'border-red-500 dark:border-red-400': props.message.severity == 'error' 29 | }, 30 | { 31 | 'text-blue-700 dark:text-blue-300': props.message.severity == 'info', 32 | 'text-green-700 dark:text-green-300': props.message.severity == 'success', 33 | 'text-orange-700 dark:text-orange-300': props.message.severity == 'warn', 34 | 'text-red-700 dark:text-red-300': props.message.severity == 'error' 35 | } 36 | ] 37 | }), 38 | content: { 39 | class: 'flex items-start p-4' 40 | }, 41 | icon: { 42 | class: [ 43 | // Sizing and Spacing 44 | 'w-6 h-6', 45 | 'text-lg leading-none mr-2 shrink-0' 46 | ] 47 | }, 48 | text: { 49 | class: [ 50 | // Font and Text 51 | 'text-base leading-none', 52 | 'ml-2', 53 | 'flex-1' 54 | ] 55 | }, 56 | summary: { 57 | class: 'font-bold block' 58 | }, 59 | detail: { 60 | class: 'mt-2 block' 61 | }, 62 | closebutton: { 63 | class: [ 64 | // Flexbox 65 | 'flex items-center justify-center', 66 | 67 | // Size 68 | 'w-8 h-8', 69 | 70 | // Spacing and Misc 71 | 'ml-auto relative', 72 | 73 | // Shape 74 | 'rounded-full', 75 | 76 | // Colors 77 | 'bg-transparent', 78 | 79 | // Transitions 80 | 'transition duration-200 ease-in-out', 81 | 82 | // States 83 | 'hover:bg-surface-0/50 dark:hover:bg-surface-0/10', 84 | 85 | // Misc 86 | 'overflow-hidden' 87 | ] 88 | }, 89 | transition: { 90 | enterFromClass: 'opacity-0 translate-y-2/4', 91 | enterActiveClass: 'transition-[transform,opacity] duration-300', 92 | leaveFromClass: 'max-h-[1000px]', 93 | leaveActiveClass: '!transition-[max-height_.45s_cubic-bezier(0,1,0,1),opacity_.3s,margin-bottom_.3s] overflow-hidden', 94 | leaveToClass: 'max-h-0 opacity-0 mb-0' 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /assets/presets/lara/togglebutton/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | 'relative', 5 | 6 | // Alignment 7 | 'inline-flex', 8 | 'align-bottom', 9 | 10 | // Misc 11 | 'cursor-pointer', 12 | 'select-none' 13 | ] 14 | }, 15 | box: ({ props }) => ({ 16 | class: [ 17 | // Alignments 18 | 'items-center inline-flex flex-1 text-center align-bottom justify-center', 19 | 20 | // Sizes & Spacing 21 | 'px-4 py-3 leading-none', 22 | 23 | // Shapes 24 | 'rounded-md border', 25 | 26 | // Colors 27 | { 28 | 'bg-surface-0 dark:bg-surface-900 ': !props.modelValue, 29 | 'border-surface-200 dark:border-surface-700 ': !props.modelValue && !props.invalid, 30 | 'text-surface-700 dark:text-white/80': !props.modelValue, 31 | 'bg-primary-500 dark:bg-primary-400 border-primary-500 dark:border-primary-400 text-white dark:text-surface-900': props.modelValue 32 | }, 33 | 34 | // Invalid State 35 | { 'border-red-500 dark:border-red-400': props.invalid }, 36 | 37 | // States 38 | { 39 | 'peer-hover:bg-surface-50 dark:peer-hover:bg-surface-800/80 peer-hover:border-surface-200 dark:peer-hover:bg-surface-700 peer-hover:text-surface-700 dark:peer-hover:text-white/80': !props.modelValue && !props.invalid, 40 | 'peer-hover:bg-primary-600 peer-hover:border-primary-600 dark:peer-hover:bg-primary-300 dark:peer-hover:border-primary-300': props.modelValue, 41 | 'peer-focus-visible:ring peer-focus-visible:ring-primary-400/50 dark:peer-focus-visible:ring-primary-300/50': !props.disabled 42 | }, 43 | 44 | // Transitions 45 | 'transition-all duration-200', 46 | 47 | // Misc 48 | { 'cursor-pointer': !props.disabled, 'opacity-60 select-none pointer-events-none cursor-default': props.disabled } 49 | ] 50 | }), 51 | label: { 52 | class: 'font-bold text-center w-full' 53 | }, 54 | input: { 55 | class: [ 56 | 'peer', 57 | 58 | // Size 59 | 'w-full ', 60 | 'h-full', 61 | 62 | // Position 63 | 'absolute', 64 | 'top-0 left-0', 65 | 'z-10', 66 | 67 | // Spacing 68 | 'p-0', 69 | 'm-0', 70 | 71 | // Shape 72 | 'opacity-0', 73 | 'rounded-md', 74 | 'outline-none', 75 | 'border border-surface-200 dark:border-surface-700', 76 | 77 | // Misc 78 | 'appearance-none', 79 | 'cursor-pointer' 80 | ] 81 | }, 82 | icon: ({ props }) => ({ 83 | class: [ 84 | ' mr-2', 85 | { 86 | 'text-surface-600 dark:text-white/70': !props.modelValue, 87 | 'text-white dark:text-surface-900': props.modelValue 88 | } 89 | ] 90 | }) 91 | }; 92 | -------------------------------------------------------------------------------- /assets/presets/lara/toolbar/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: [ 4 | // Flex & Alignment 5 | 'flex items-center justify-between flex-wrap', 6 | 'gap-2', 7 | 8 | // Spacing 9 | 'p-5', 10 | 11 | // Shape 12 | 'rounded-md', 13 | 14 | // Color 15 | 'bg-surface-50 dark:bg-surface-800', 16 | 'border border-surface-200 dark:border-surface-700' 17 | ] 18 | }, 19 | start: { 20 | class: 'flex items-center' 21 | }, 22 | center: { 23 | class: 'flex items-center' 24 | }, 25 | end: { 26 | class: 'flex items-center' 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /assets/presets/lara/tooltip/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: ({ context, props }) => ({ 3 | class: [ 4 | // Position and Shadows 5 | 'absolute', 6 | 'shadow-md', 7 | 'p-fadein', 8 | // Spacing 9 | { 10 | 'py-0 px-1': context?.right || context?.left || (!context?.right && !context?.left && !context?.top && !context?.bottom), 11 | 'py-1 px-0': context?.top || context?.bottom 12 | } 13 | ] 14 | }), 15 | arrow: ({ context, props }) => ({ 16 | class: [ 17 | // Position 18 | 19 | 'absolute', 20 | 21 | // Size 22 | 'w-0', 23 | 'h-0', 24 | 25 | // Shape 26 | 'border-transparent', 27 | 'border-solid', 28 | { 29 | 'border-y-[0.25rem] border-r-[0.25rem] border-l-0 border-r-surface-600': context?.right || (!context?.right && !context?.left && !context?.top && !context?.bottom), 30 | 'border-y-[0.25rem] border-l-[0.25rem] border-r-0 border-l-surface-600': context?.left, 31 | 'border-x-[0.25rem] border-t-[0.25rem] border-b-0 border-t-surface-600': context?.top, 32 | 'border-x-[0.25rem] border-b-[0.25rem] border-t-0 border-b-surface-600': context?.bottom 33 | }, 34 | 35 | // Spacing 36 | { 37 | '-mt-1 ': context?.right || (!context?.right && !context?.left && !context?.top && !context?.bottom), 38 | '-mt-1': context?.left, 39 | '-ml-1': context?.top || context?.bottom 40 | } 41 | ] 42 | }), 43 | text: { 44 | class: ['p-3', 'bg-surface-600 dark:bg-surface-700', 'text-white', 'leading-none', 'rounded-md', 'whitespace-pre-line', 'break-words'] 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /assets/presets/lara/tristatecheckbox/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | root: { 3 | class: ['cursor-pointer inline-flex relative select-none align-bottom', 'w-6 h-6'] 4 | }, 5 | input: { 6 | class: [ 7 | 'peer', 8 | 9 | // Size 10 | 'w-full ', 11 | 'h-full', 12 | 13 | // Position 14 | 'absolute', 15 | 'top-0 left-0', 16 | 'z-10', 17 | 18 | // Spacing 19 | 'p-0', 20 | 'm-0', 21 | 22 | // Shape 23 | 'opacity-0', 24 | 'rounded-md', 25 | 'outline-none', 26 | 'border-2 border-surface-200 dark:border-surface-700', 27 | 28 | // Misc 29 | 'appearance-none', 30 | 'cursor-pointer' 31 | ] 32 | }, 33 | box: ({ props, context }) => ({ 34 | class: [ 35 | // Alignment 36 | 'flex', 37 | 'items-center', 38 | 'justify-center', 39 | 40 | // Size 41 | 'w-6', 42 | 'h-6', 43 | 44 | // Shape 45 | 'rounded-md', 46 | 'border-2', 47 | 48 | // Colors 49 | { 50 | 'border-surface-200 bg-surface-0 dark:border-surface-700 dark:bg-surface-900': !context.active && !props.invalid, 51 | 'border-primary-500 bg-primary-500 dark:border-primary-400 dark:bg-primary-400': context.active 52 | }, 53 | 54 | // Invalid State 55 | { 'border-red-500 dark:border-red-400': props.invalid }, 56 | 57 | // States 58 | { 59 | 'peer-hover:border-primary-500 dark:peer-hover:border-primary-400': !props.disabled && !context.active && !props.invalid, 60 | 'peer-hover:bg-primary-600 dark:peer-hover:bg-primary-300 peer-hover:border-primary-700 dark:peer-hover:border-primary-300': !props.disabled && context.active, 61 | 'peer-focus-visible:border-primary-500 dark:peer-focus-visible:border-primary-400 peer-focus-visible:ring-2 peer-focus-visible:ring-primary-400/20 dark:peer-focus-visible:ring-primary-300/20': !props.disabled, 62 | 'cursor-default opacity-60': props.disabled 63 | }, 64 | 65 | // Transitions 66 | 'transition-colors', 67 | 'duration-200' 68 | ] 69 | }), 70 | checkicon: { 71 | class: [ 72 | // Font 73 | 'text-base leading-none', 74 | 75 | // Size 76 | 'w-4', 77 | 'h-4', 78 | 79 | // Colors 80 | 'text-white dark:text-surface-900', 81 | 82 | // Transitions 83 | 'transition-all', 84 | 'duration-200' 85 | ] 86 | }, 87 | uncheckicon: { 88 | class: [ 89 | // Font 90 | 'text-base leading-none', 91 | 92 | // Size 93 | 'w-4', 94 | 'h-4', 95 | 96 | // Colors 97 | 'text-white dark:text-surface-900', 98 | 99 | // Transitions 100 | 'transition-all', 101 | 'duration-200' 102 | ] 103 | } 104 | }; 105 | -------------------------------------------------------------------------------- /components/Logo/Logo.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /components/MainContent/MainContent.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /components/OgImage/GistDetail.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /components/OgImage/Main.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /components/OgImage/PublicProfile.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /components/Splash/Splash.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /components/Widget/Default.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 24 | -------------------------------------------------------------------------------- /composables/useLogger/useLogger.ts: -------------------------------------------------------------------------------- 1 | export function useLogger() { 2 | const config = useRuntimeConfig() 3 | 4 | const isProd = config.public.nodeEnv === 'production' 5 | 6 | const logAndTrack = (...args: any[]) => { 7 | if (isProd) { 8 | // @TODO: send to sentry 9 | return 10 | } 11 | 12 | console.log(...args) 13 | } 14 | 15 | return { 16 | logAndTrack, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /composables/useMarkdown/useMarkdown.ts: -------------------------------------------------------------------------------- 1 | import { marked } from 'marked' 2 | 3 | export function useMarkdown() { 4 | const render = (text: string) => { 5 | return marked.parse(text) 6 | } 7 | 8 | return { render } 9 | } 10 | -------------------------------------------------------------------------------- /composables/useServices/useServices.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import AuthService from '@/modules/auth/services/services' 3 | import UserService from '@/modules/users/services/services' 4 | import GistService from '@/modules/gists/services/services' 5 | import ReportService from '@/modules/reports/services/services' 6 | import PaymentService from '@/modules/payments/services/services' 7 | import type { Database } from '@/libs/supabase/schema' 8 | 9 | export function useServices() { 10 | const supabaseClient = useSupabaseClient() 11 | const config = useRuntimeConfig() 12 | const cepHttpClient = axios.create() 13 | const paymentHttpClient = axios.create({ 14 | baseURL: '/api', 15 | }) 16 | 17 | return { 18 | auth: AuthService(supabaseClient, { 19 | redirectToUrl: `${config.public.siteUrl}/auth/github`, 20 | }), 21 | users: UserService(supabaseClient, cepHttpClient), 22 | gists: GistService(supabaseClient), 23 | reports: ReportService(supabaseClient), 24 | payments: PaymentService(supabaseClient, paymentHttpClient), 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /emails/GistSale.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 33 | -------------------------------------------------------------------------------- /layouts/admin.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 58 | -------------------------------------------------------------------------------- /layouts/checkout.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 65 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /libs/currency/format.ts: -------------------------------------------------------------------------------- 1 | export const currencyFormatBRL = (value: number) => { 2 | return Intl.NumberFormat('pt-br', { style: 'currency', currency: 'BRL' }).format(value) 3 | } 4 | -------------------------------------------------------------------------------- /middleware/auth.ts: -------------------------------------------------------------------------------- 1 | import { useSession } from '@/modules/auth/composables/useSession/useSession' 2 | 3 | export default defineNuxtRouteMiddleware(async (to) => { 4 | const session = useSession() 5 | const isLogged = await session.isLogged() 6 | 7 | if (!isLogged) { 8 | console.log('* user not authenticated') 9 | 10 | if (to.path === '/auth/login') { 11 | return 12 | } 13 | 14 | return navigateTo({ path: '/auth/login' }) 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /modules/auth/components/Header/Header.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 76 | -------------------------------------------------------------------------------- /modules/auth/components/Header/Loader.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 27 | -------------------------------------------------------------------------------- /modules/auth/components/SocialForm/SocialForm.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | -------------------------------------------------------------------------------- /modules/auth/composables/useSession/useSession.ts: -------------------------------------------------------------------------------- 1 | export function useSession() { 2 | const user = useSupabaseUser() 3 | const services = useServices() 4 | 5 | const isLogged = () => { 6 | const hasUserLogged = Boolean(user.value) 7 | return hasUserLogged 8 | } 9 | 10 | const logout = async () => { 11 | const response = await services.auth.signOut() 12 | return response 13 | } 14 | 15 | return { 16 | user, 17 | logout, 18 | isLogged, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /modules/auth/screens/Login/Login.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /modules/auth/screens/OAuthRedirect/OAuthRedirect.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /modules/auth/services/services.ts: -------------------------------------------------------------------------------- 1 | import type { SupabaseClient } from '@supabase/supabase-js' 2 | import type { Database } from '@/libs/supabase/schema' 3 | 4 | interface ServiceOptions { 5 | redirectToUrl: string 6 | } 7 | 8 | export default (client: SupabaseClient, options: ServiceOptions) => ({ 9 | async signInWithGithub() { 10 | const response = await client.auth.signInWithOAuth({ 11 | provider: 'github', 12 | options: { 13 | redirectTo: options.redirectToUrl, 14 | }, 15 | }) 16 | return response 17 | }, 18 | 19 | async signOut() { 20 | const response = await client.auth.signOut() 21 | return response 22 | }, 23 | }) 24 | -------------------------------------------------------------------------------- /modules/gists/components/Card/Group/Group.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /modules/gists/components/Card/Group/Loader.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | -------------------------------------------------------------------------------- /modules/gists/components/Card/Item/Item.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 77 | -------------------------------------------------------------------------------- /modules/gists/components/CodeEdit/CodeEdit.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 61 | -------------------------------------------------------------------------------- /modules/gists/components/CodeSnippet/CodeSnippet.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 67 | -------------------------------------------------------------------------------- /modules/gists/components/CodeSnippet/Loader.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /modules/gists/components/HeadlineEdit/HeadlineEdit.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 |