Git Product home page Git Product logo

frappe-ui's Introduction

Rapidly build modern frontends for Frappe apps

MIT License NPM Downloads

Frappe UI provides a set of components and utilities for rapid UI development. Components are built using Vue 3 and Tailwind. Along with components, there are directives and utilities that make UI development easier.

Links

Installation

npm install frappe-ui
# or
yarn add frappe-ui

Now, import the FrappeUI plugin and components in your Vue app's main.js:

import { createApp } from 'vue'
import { FrappeUI } from 'frappe-ui'
import App from './App.vue'
import './index.css'

let app = createApp(App)
app.use(FrappeUI)
app.mount('#app')

In your tailwind.config.js file, include the frappe-ui preset:

module.exports = {
  presets: [
    require('frappe-ui/src/utils/tailwind.config')
  ],
  ...
}

Now, you can import needed components and start using it:

<template>
  <button>Click me</button>
</template>
<script>
  import { Button } from 'frappe-ui'
  export default {
    components: {
      Button,
    },
  }
</script>

Used By

Frappe UI is being used in a lot of products by Frappe.

License

MIT

frappe-ui's People

Contributors

0x15f9 avatar 18alantom avatar akshayitzme avatar blaggacao avatar breadgenie avatar dj12djdjs avatar kamaljohnson avatar nagariahussain avatar netchampfaris avatar nextchamp-saqib avatar pateljannat avatar rutwikhdev avatar shariquerik avatar ssiyad avatar surajshetty3416 avatar uhrjun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frappe-ui's Issues

[bug] Preset blocks default config inconsistently

frappe-ui includes a preset config file to align tailwindcss's defaults to the frappe design language. That's great. At present, however, the logic of the file is a bit strange. It extends the defaults for some classes (spacing, width, height, minWidth, minHeight, borderColor, typography) but replaces them for others (colors, borderRadius, boxShadow, container, fontSize, screens).

It is not clear whether this was deliberate, but it can lead to a very confusing experience for users. Some tailwind classes are blocked, while others pass through. The fix is easy, and I'm happy to submit a PR, but I am posting an issue first in case the maintainers have any opinions.

Webshop remake

For a webshop remake, according to https://frappeui.com/story/docs-resources-document-resource-story-js , it appears that we need a local state proxy for frappe resources.

It should:

  • Set all mutations into a localstate representation
  • quietly sync those mutation to the backend doctype in the background, being tolerant to network interruptions, potentially accumulating mutations locally
  • instantly fetch from local state (quite like probably how cache is already implemented), while updating the state in the background from the current backend version, being tolerant to network interactions, and only on a diff "re-draw" the component in question
  • option to persist localstate across site visits (default?)

For a v1 of that functionality, I don't think we need to deal with sync conflict resolution as the doctypes involved would be specific and exclusively frontend driven.

Figma UI Kit

Is there any kit on figma or any free software?

Best Regards

Missing dependencies

I followed the installation guide from https://frappeui.com/getting-started.html, but when I tried to access the URL todo.test:8080/frontend, I encountered an error message that said:

Failed to resolve import '@tiptap/pm/state'
Failed to resolve import 'prosemirror-model'

However, I was able to fix the issue by installing @tiptap/pm and then reloading the /frontend URL, which resolved the problem.

Bug: Select with prefix

image
<FormControl
  type="select"
  :options="options"
  v-model="value"
>
  <template #prefix>
    <IndicatorIcon />
  </template>
</FormControl>

Error in package because of which whole app crashes.

When loading for the first time it throws the following error in my browser console: "Uncaught SyntaxError: The requested module '/node_modules/feather-icons/dist/feather.js?v=849b2485' does not provide an export named 'default'"

Any idea what is happening and could you help me fix this ?

feature request: add label property to Autocomplete, DatePicker, TextEditor, etc

Components like Autocomplete and Date Picker are styled to blend with the default Input component. This creates a nice user experience, but at present only the input component has a label property. It would be more semantically robust if other similar components had this property too.

I am happy to submit a PR if this is consistent with the maintainers' vision.

feat: use composables for resources

Right now, the $resources utility uses component mixins to expose Frappe resource apis. As of Vue 3, mixins are no longer the recommended approach for code reuse.

No Longer Recommended
In Vue 2, mixins were the primary mechanism for creating reusable chunks of component logic. While mixins continue to be supported in Vue 3, Composition API is now the preferred approach for code reuse between components.

https://vuejs.org/api/options-composition.html#mixins

I would propose that this library introduce a composables interface, exposing an importable method such as useResources() that would be available in Vue's composition API.

I believe it is possible for the library to offer both interfaces simultaneously, and I believe doing so would provide more flexibility in design patterning.

bug: inconsistent application of class attributes to different components

There is significant inconsistency in how various components apply class attributes. For example, consider the following code:

<div class="grid grid-12 gap-2">
  <Input label="Input" class="col-span-12" />
  <Input label="Input 2" class="col-span-6" />
  <Input label="Input 3" class="col-span-6" />
  <Autocomplete
    label="Autocomplete"
    :options="[
      { label: 'One', value: '1' },
      { label: 'Two', value: '2' },
    ]"
    class="col-span-6"
  />
  <DatePicker label="Date Picker" :formatValue="(val) => val" class="col-span-6" />
</div>

This produces a layout that looks like this:
Screenshot 2023-05-24 at 10 25 10 AM

The expected behavior would be for the Autocomplete and DatePicker components to behave the same way that Input components do.

Resource component causing crash

Hello,

I am encountering a build failure when attempting to use the Resource component. Using exactly the code displayed here:
https://frappeui.com/components/resource.html

I get the following error:

[Vue warn]: Property "$resources" was accessed during render but is not defined on instance.                                                            15:22:29
[Vue warn]: Unhandled error during execution of render function                                                                                         15:22:29
  at <Resource options= { url: 'https://jsonplaceholder.typicode.com/users/1' } >
[nitro] [dev] [unhandledRejection] TypeError: Cannot read properties of undefined (reading 'resource')                                                  15:22:29
    at Proxy.render (/Users/petergraif/Sites/oi2/node_modules/frappe-ui/src/components/Resource.vue:12:33)
    at renderComponentRoot (/Users/petergraif/Sites/oi2/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:891:44)
    at renderComponentSubTree (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:263:51)
    at renderComponentVNode (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:188:16)
    at Module.ssrRenderComponent (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:624:12)
    at _sfc_ssrRender (/Users/petergraif/Sites/oi2/pages/index2.vue:22:31)
    at renderComponentSubTree (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:254:17)
    at renderComponentVNode (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:188:16)
    at renderVNode (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:299:22)
    at renderComponentSubTree (/Users/petergraif/Sites/oi2/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:263:13)

More Alert Types

Currently Alert component has only one default type i.e Warning. It would be better to have more Alert types such as Danger.

Serial resource requests?

Is there a standard way to define resource requests that depend on prior resource requests for parameters? I may be thinking about this the wrong way, but I find myself writing a lot of code that looks like this:

<template>
  <ul>
    <li v-for="invoice in invoices.data">{{ invoice.name }}</li>
  </ul>
</template>

<script setup>
import { createResource, createListResource } from 'frappe-ui'

const user = createResource({
  url: 'frappe.auth.get_logged_user',
})
const invoices = createListResource({
  doctype: 'Sales Invoice',
  filters: { owner: user.data },
  auto: true,
})
</script>

The problem is that the user is still undefined when the createListResource is called, and the invoices object isn't responsive to changes in user.data. I know I can accomplish this with onMounted hooks, but I'm hoping there's a more declarative approach out there.

Error in documentation

Hi there,

I believe there's a bug in the documentation. In the following section:

<Button>Default</Button>
<Button type="primary">Primary</Button>
<Button type="danger">Danger</Button>
<Button type="white">White</Button>
<Button icon="x" />
<Button icon-left="menu">Menu</Button>
<Button icon-right="external-link">Link</Button>
<Button :loading="true">Loading</Button>

All instances of <Button type= should perhaps be <Button appearance=?

bug: Autocomplete v-model binds object rather than value

The v-model property is currently not working correctly on the Autocomplete component. Instead of binding to the value of the label/value object, it binds to the entire object.

See the following example, taken directly from the documentation:

<template>
  <div class="max-w-screen-md m-auto p-12">
    <Autocomplete
      :options="[
        { label: 'Apple', value: 'apple' },
        { label: 'Banana', value: 'banana' },
        { label: 'Orange', value: 'orange' },
      ]"
      v-model="fruit"
      placeholder="Select a fruit"
    />
    <pre>{{ fruit }}</pre>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { Autocomplete } from 'frappe-ui'
const fruit = ref('')
</script>

The following output is produced:
Screenshot 2023-05-24 at 2 02 11 PM

Resources problem with array arg

Hi,

When the arg is an array, only the first element is present in server side method.

Exemple of call in vue component :

resources: {
     todos: {
            method: 'custom_app.getStock',
            params: {
                fruits: ['Apple', 'Banana']
            },
            auto: true,
        }
  },

The payload is well sent :
{"fruits":["Apple","Banana"]}

But in server side function getStock(fruits), print(fruits) gives :
Apple

If I change the arg to dict {fruit1: 'Apple', fruit2: 'Banana'}, it works and fruits arg is fully transmitted server side.

Thanks

Is it possible to disable socket calls ?

Hi ,
we have developed an UI from scratch from our but currently not using socket functionality and want to disable the calls from the client. Is there a flag by which we can disable it ?

Vite hot reload on Windows with WSL

Add hot reload in windows with the following code in ./vite.js for Users developing on Windows.

I've added the watch:{usePolling:true}, after this, hot reload on windows (Docker on WSL2) works.

return {
    name: 'frappeui-vite-plugin',
    config: () => ({
      server: {
        watch: {
          usePolling: true
        },
        port: port,
        proxy: {
          '^/(app|login|api|assets|files)': {
            target: `http://127.0.0.1:${webserver_port}`,
            ws: true,
            router: function (req) {
              const site_name = req.headers.host.split(':')[0]
              return `http://${site_name}:${webserver_port}`
            },
          },
        },
      },
    }),
  }

Is it possible to add this to the code?

feat: Type Declaration files

In the absence of project-wide usage of TypeScript, type declaration files would be nice.

(was about to use this for a thing, but for now I'll be resorting to shamelessly copying blocks of required code, adding types and using it)

feat: required attribute for FormControl

I cannot find a way to make the FormControl elements be marked as required.
It would be nice if there was a way to pass a prop to make the field as required, with cosmetics of red asterisk.

permission error for the frappe ui

{ "doctype": "Fees", "start": 0, "pageLength": 20, "debug": 0, "originalData": null, "data": null, "hasPreviousPage": false, "hasNextPage": true, "list": { "url": "frappe.client.get_list", "data": null, "previousData": null, "loading": false, "fetched": false, "error": "Error: /api/method/frappe.client.get_list Insufficient Permission for Fees", "promise": "[object Promise]", "params": { "doctype": "Fees", "start": 0, "limit": 20, "limit_start": 0, "limit_page_length": 20, "debug": 0 } }, "fetchOne": { "url": "frappe.client.get_list", "data": null, "previousData": null, "loading": false, "fetched": false, "error": null, "promise": null, "params": null }, "insert": { "url": "frappe.client.insert", "data": null, "previousData": null, "loading": false, "fetched": false, "error": null, "promise": null, "params": null }, "setValue": { "url": "frappe.client.set_value", "data": null, "previousData": null, "loading": false, "fetched": false, "error": null, "promise": null, "params": null }, "delete": { "url": "frappe.client.delete", "data": null, "previousData": null, "loading": false, "fetched": false, "error": null, "promise": null, "params": null }, "runDocMethod": { "url": "run_doc_method", "data": null, "previousData": null, "loading": false, "fetched": false, "error": null, "promise": null, "params": null } }

feat: dark mode

image

I use dark reader but not everyone uses extensions also auto-generated dark color palettes aren't generally "great" ๐Ÿ˜ฌ

bug: `onError` in resource is getting called twice

Sample code

createResource({
  url: "https://example.com",
  auto: true,
  validate() {
    return "Sample error";
  },
  onError(error) {
    alert(error);
  },
});

Expected

One alert with 'Sample error'

Result

Gets two alerts with 'Sample error'

Possible cause

handleError is getting called twice from here. The second call might be due to error thrown from handleError

Possible fix

Remove error thrown from handleError?

SyntaxError: frappe-ui does not provide an export named 'frappeRequest'

Describe the bug
When trying to use the frappeRequest export from the frappe-ui package in my Vue 3 project, Vite throws a SyntaxError stating that the requested module does not provide an export named 'frappeRequest'.

To Reproduce
Steps to reproduce the behavior:

  1. Install frappe-ui package in a Vue 3 project.
  2. Import frappeRequest from the frappe-ui package in main.js: import { frappeRequest } from 'frappe-ui';
  3. Run the project using npm run dev or yarn dev.
  4. See the following error in the console:
    SyntaxError: The requested module '/node_modules/.vite/frappe-ui.js?v=7a3651e8' does not provide an export named 'frappeRequest'

Expected behavior
I expect the frappeRequest export to be available for use in my project without any errors.

Environment:

OS: [Linux]
Browser: [Chrome ]
Node.js version: [v16.19.1]
frappe-ui version: [0.0.89]
Vite version: [2.7.2]

Additional context
Please let me know if there is a workaround or if I am missing something in my setup.

Globally handle MacOS scrollbars with mouse

MacOS has this weird issue where if you are using a mouse it will show these block scrollbars - it can be handled with CSS - I see this everywhere in our new products.

Only appears when using a mouse, not trackpad.

Screenshot 2023-07-10 at 11 40 01 AM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.