Since I moved to FLutter & Dart ecosystem, I found awesome package Jaspr which syntax and approach very similar to what I was trying to achieve in this package. So because of that it makes no sense to maintain or develop this project - and now it's archived:) Hope you find something useful or inspiration in this package:)
Please notice: this project was renamed from vuefer to independent name: vuefer
Please notice: this project is a work in progress and completely experimental!
Please notice: vue-provider
now is maintained as standalone package. Please see it in packages/vue-provider
The reason & motivation why this project have been started is a question: Flutter & Dart awesome! Vue3 & Typescript awesome too!
But...
html+css or jsx are not providing a strong enough typing way to write widgets/components.
So, what if we will write Vue3 TS in style of Flutter, because it's just simplier and faster?
Purpose: fast prototyping and fast MVP development
Please notice:
Add this package to your package.json file:
"dependencies": {
"@xsoulspace/vuefer": "next"
}
add styling to your main.ts
import '@xsoulspace/vuefer/dist/vft.css'
add styling to app div (temporary and will be removed during Scaffold widget refactoring)
<div id="app" class="absolute left-0 right-0 top-0 bottom-0"></div>
export const wrapperApp = () => {
const text = ref('Hello world!')
const text2 = ref(2)
const padding = EdgeInsets.all(EdgeInsetsStep.s3)
const textCard = Padding({
child: Text({
text,
}),
padding,
})
const btn = ElevatedButton({
child: Text({ text: ref('Hello Button') }),
onPressed: () => {
text2.value++
text.value = `Hello Wolrd! Counter: ${text2.value}`
},
})
return Scaffold({
body: Align({
overlay: true,
alignment: Alignment.bottom,
child: Container({
padding,
decoration: new BoxDecoration({
boxShadow: BoxShadow.xl,
borderRadius: BorderRadius.vertical({ bottom: BorderRadiusStep.xxl }),
}),
child: Row({
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
MouseRegion({
child: btn,
cursor: SystemMouseCursor.use({
cursor: SystemMouseCursors.click,
}),
}),
textCard,
],
}),
}),
}),
})
}
Let's suppose we have a model:
export class Hero {
constructor(public name: string) {}
}
export class HeroesModel {
heroes = reactive<Maybe<Hero>[]>([])
add(hero: Hero) {
this.heroes.push(hero)
}
get count() {
return this.heroes.length
}
}
Create Provider on top of tree
MultiProvider.create({
models: [HeroesModel],
child: wrapperApp(),
})
And somewhere in tree just call
const heroModel = MultiProvider.get<HeroesModel>(HeroesModel)
First - get NavigationController in setup
Be sure that you have Navigation widget on top of tree
const navigationController =
MultiProvider.get<NavigationController>(NavigationController)
Second call a function from for example Button.onTap:
ElevatedButton({
child: Text({
text: ref('Show dialog'),
}),
onTap: () => {
showDialog({
builder: Dialog({
child: Text({ text: ref('Hello World') }),
}),
navigationController,
})
},
}),
To close, just use navigationController.pop()
Usage:
Create controller in setup or anywehere and give generic type to use
const IndexedText {
id: string
text: string
}
const multiDropdownController = new MultiDropdownFieldController<IndexedText>(
{ keyofValue: 'id' }
)
Then use MultiDropdownButton with DropdownMenuItem in items to make it work
MultiDropdownButton({
controller: multiDropdownController,
items: dropdownItems.map((el) =>
DropdownMenuItem({
child: Text({
text: ref(el.text),
}),
value: el,
key: el.id,
title: el.text,
})
),
}),
To get or change selected values use:
controller.value
Navigation & NavigationController
Add controller into MultiPorvider and Navigation widget below:
MultiProvider.create({
models: [NavigationController, ...],
child: Navigation({
child: ...,
}),
})
DropdownButton, DropdownButtonItem [x] functionality [] decoration
[] Visibility [x] functionality [] animation
[] TextField [x] Basic properties [x] TextEditingController [] InputDecoration (partially) [] TextStyle
Checkbox [x] Basic [] Style
ReordableListView
[] GestureDetecture [x] click [] tap [] swipes [] hover
[] Container [x] Border [x] BorderRadius [x] Color [x] Shadow [] Margin [x] Padding [] Color Opacity ? Border Color Opacity [] Shape [] Gradient [] Alignment [] Image [x] Height [x] Width
[] Material
[] InkWell
[] Colors [x] White, black [] Color palette
[] Scaffold [x] Drawer [x] AppBar
[] Drawer [x] basic [] animation
[] AppBar [x] basic
Changelog can be found in Releases
VSCode + Vetur. Make sure to enable vetur.experimental.templateInterpolationService
in settings!
<script setup>
<script setup>
is a feature that is currently in RFC stage. To get proper IDE support for the syntax, use Volar instead of Vetur (and disable Vetur).
.vue
Imports in TSSince TypeScript cannot handle type information for .vue
imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in .vue
imports (for example to get props validation when using manual h(...)
calls), you can use the following:
Run Volar: Switch TS Plugin on/off
from VSCode command palette.
@vuedx/typescript-plugin-vue
to the plugins section in tsconfig.json
src/shims-vue.d.ts
as it is no longer needed to provide module info to Typescriptsrc/main.ts
in VSCode