From 2bfe5b0cfc512bfb4d926e08ae7d5bbcd11364cf Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Thu, 6 Nov 2025 21:58:33 +0530 Subject: [PATCH 01/14] refactor: tree shaking by adding subpath exports --- package.json | 28 +++++++++ src/components/Charts/index.ts | 6 ++ src/components/DatePicker/index.ts | 6 ++ src/icons.ts | 9 +++ src/index.ts | 93 ++++++++++++---------------- src/resources/{index.js => index.ts} | 3 +- src/resources/{local.js => local.ts} | 8 +-- tsconfig.json | 3 +- tsconfig.node.json | 2 +- 9 files changed, 97 insertions(+), 61 deletions(-) create mode 100644 src/components/Charts/index.ts create mode 100644 src/components/DatePicker/index.ts create mode 100644 src/icons.ts rename src/resources/{index.js => index.ts} (92%) rename src/resources/{local.js => local.ts} (63%) diff --git a/package.json b/package.json index 0a816bd3e..834760c34 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "A set of components and utilities for rapid UI development", "main": "./src/index.ts", "type": "module", + "sideEffects": false, "scripts": { "test": "vitest --run", "type-check": "tsc --noEmit", @@ -17,6 +18,33 @@ "story:build": "histoire build && cp 404.html .histoire/dist", "story:preview": "histoire preview" }, + "exports": { + ".": { + "import": "./src/index.ts", + "types": "./src/index.ts" + }, + "./src/tailwind/preset": { + "import": "./src/tailwind/preset.js" + }, + "./vite": { + "import": "./vite/index.js" + }, + "./style.css": { + "import": "./src/style.css" + }, + "./src/*": { + "import": "./src/*" + }, + "./charts": { + "import": "./src/components/Charts/index.ts" + }, + "./frappe": { + "import": "./frappe/index.js" + }, + "./icons": { + "import": "./src/icons.ts" + } + }, "files": [ "frappe", "src", diff --git a/src/components/Charts/index.ts b/src/components/Charts/index.ts new file mode 100644 index 000000000..e01df8db3 --- /dev/null +++ b/src/components/Charts/index.ts @@ -0,0 +1,6 @@ +// chart components +export { default as AxisChart } from './AxisChart.vue' +export { default as DonutChart } from './DonutChart.vue' +export { default as ECharts } from './ECharts.vue' +export { default as FunnelChart } from './FunnelChart.vue' +export { default as NumberChart } from './NumberChart.vue' diff --git a/src/components/DatePicker/index.ts b/src/components/DatePicker/index.ts new file mode 100644 index 000000000..a5561c8b9 --- /dev/null +++ b/src/components/DatePicker/index.ts @@ -0,0 +1,6 @@ +export { default as DatePicker } from './DatePicker.vue' +export { default as DateRangePicker } from './DateRangePicker.vue' +export { default as DateTimePicker } from './DateTimePicker.vue' +export * from './types' +export { useDatePicker } from './useDatePicker' +export * from './utils' diff --git a/src/icons.ts b/src/icons.ts new file mode 100644 index 000000000..3891f422d --- /dev/null +++ b/src/icons.ts @@ -0,0 +1,9 @@ +export { default as CircleCheck } from './icons/CircleCheck.vue' +export { default as DownSolid } from './icons/DownSolid.vue' + +// Frappe Icons +export { default as HelpIcon } from '../frappe/Icons/HelpIcon.vue' +export { default as LightningIcon } from '../frappe/Icons/LightningIcon.vue' +export { default as MaximizeIcon } from '../frappe/Icons/MaximizeIcon.vue' +export { default as MinimizeIcon } from '../frappe/Icons/MinimizeIcon.vue' +export { default as StepsIcon } from '../frappe/Icons/StepsIcon.vue' diff --git a/src/index.ts b/src/index.ts index b74d13c73..ba30fafed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,12 +5,14 @@ export * from './components/Avatar' export * from './components/Badge' export * from './components/Breadcrumbs' export * from './components/Button' +export * from './components/Calendar' export { default as Card } from './components/Card.vue' -export * from './components/Combobox' export * from './components/Checkbox' -export { default as DatePicker } from './components/DatePicker/DatePicker.vue' -export { default as DateTimePicker } from './components/DatePicker/DateTimePicker.vue' -export { default as DateRangePicker } from './components/DatePicker/DateRangePicker.vue' +export * from './components/CircularProgressBar' +export * from './components/Combobox' +export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' +export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' +export * from './components/DatePicker' export * from './components/Dialog' export { default as Dialogs } from './components/Dialogs.vue' export * from './components/Divider' @@ -22,102 +24,85 @@ export * from './components/FormControl' export { default as FormLabel } from './components/FormLabel.vue' export { default as GreenCheckIcon } from './components/GreenCheckIcon.vue' export { default as Input } from './components/Input.vue' +export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' +export { default as ListFilter } from './components/ListFilter/ListFilter.vue' +export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' export { default as ListItem } from './components/ListItem.vue' +export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' +export { default as ListFooter } from './components/ListView/ListFooter.vue' +export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' +export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' +export { default as ListGroups } from './components/ListView/ListGroups.vue' +export { default as ListHeader } from './components/ListView/ListHeader.vue' +export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' +export { default as ListRow } from './components/ListView/ListRow.vue' +export { default as ListRowItem } from './components/ListView/ListRowItem.vue' +export { default as ListRows } from './components/ListView/ListRows.vue' +export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' +export { + default as List, + default as ListView, +} from './components/ListView/ListView.vue' export { default as LoadingIndicator } from './components/LoadingIndicator.vue' export { default as LoadingText } from './components/LoadingText.vue' -export * from './components/Progress' +export * from './components/Password' export * from './components/Popover' +export * from './components/Progress' +export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' export * from './components/Rating' export { default as Resource } from './components/Resource.vue' export * from './components/Select' -export * from './components/Password' +export { default as Sidebar } from './components/Sidebar/Sidebar.vue' export * from './components/Spinner' export * from './components/Switch' export * from './components/TabButtons' -export { default as Tabs } from './components/Tabs/Tabs.vue' export { default as TabList } from './components/Tabs/TabList.vue' export { default as TabPanel } from './components/Tabs/TabPanel.vue' -export * from './components/TextInput' +export { default as Tabs } from './components/Tabs/Tabs.vue' export * from './components/Textarea' export * from './components/TextEditor' +export * from './components/TextInput' export * from './components/TimePicker' -export { default as ListView } from './components/ListView/ListView.vue' -export { default as List } from './components/ListView/ListView.vue' -export { default as ListHeader } from './components/ListView/ListHeader.vue' -export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' -export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' -export { default as ListRows } from './components/ListView/ListRows.vue' -export { default as ListRow } from './components/ListView/ListRow.vue' -export { default as ListRowItem } from './components/ListView/ListRowItem.vue' -export { default as ListGroups } from './components/ListView/ListGroups.vue' -export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' -export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' -export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' -export { default as ListFooter } from './components/ListView/ListFooter.vue' -export { default as Toast } from './components/Toast/Toast.vue' export { toast } from './components/Toast/index' +export { default as Toast } from './components/Toast/Toast.vue' export * from './components/Tooltip' -export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' -export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' -export { default as ListFilter } from './components/ListFilter/ListFilter.vue' -export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' -export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' -export * from './components/Calendar' -export * from './components/CircularProgressBar' export * from './components/Tree' -export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' -export { default as Sidebar } from './components/Sidebar/Sidebar.vue' // grid layout export { default as GridLayout } from './components/VueGridLayout/Layout.vue' -// chart components -export { default as AxisChart } from './components/Charts/AxisChart.vue' -export { default as NumberChart } from './components/Charts/NumberChart.vue' -export { default as DonutChart } from './components/Charts/DonutChart.vue' -export { default as FunnelChart } from './components/Charts/FunnelChart.vue' -export { default as ECharts } from './components/Charts/ECharts.vue' - // directives export { default as onOutsideClickDirective } from './directives/onOutsideClick' export { default as visibilityDirective } from './directives/visibility' // utilities export { default as call, createCall } from './utils/call.js' +export { dayjs, dayjsLocal } from './utils/dayjs' export { default as debounce } from './utils/debounce' export { default as fileToBase64 } from './utils/file-to-base64' export { default as FileUploadHandler } from './utils/fileUploadHandler' export { usePageMeta } from './utils/pageMeta' -export { dayjsLocal, dayjs } from './utils/dayjs' -export * from './utils/useFileUpload' export * from './utils/theme' +export * from './utils/useFileUpload' // old data-fetching: resources -export { - createResource, - createDocumentResource, - createListResource, - getCachedResource, - getCachedDocumentResource, - getCachedListResource, - resourcesPlugin, -} from './resources/index.js' -export { request } from './utils/request.js' +export * from './resources/index.ts' +export { getConfig, setConfig } from './utils/config' export { frappeRequest } from './utils/frappeRequest.js' +export { request } from './utils/request.js' export { default as initSocket } from './utils/socketio.js' -export { setConfig, getConfig } from './utils/config' // new data-fetching composables export { useCall, - useList, useDoc, - useNewDoc, useDoctype, useFrappeFetch, + useList, + useNewDoc, } from './data-fetching' // plugin +export { confirmDialog } from './utils/confirmDialog.js' export { default as pageMetaPlugin } from './utils/pageMeta.js' export { default as FrappeUI } from './utils/plugin.js' -export { confirmDialog } from './utils/confirmDialog.js' diff --git a/src/resources/index.js b/src/resources/index.ts similarity index 92% rename from src/resources/index.js rename to src/resources/index.ts index 58ca6cd2e..9f57b734e 100644 --- a/src/resources/index.js +++ b/src/resources/index.ts @@ -1,7 +1,8 @@ -export { createResource, getCachedResource } from './resources' export { createDocumentResource, getCachedDocumentResource, } from './documentResource' export { createListResource, getCachedListResource } from './listResource' +export * from './local' export { default as resourcesPlugin } from './plugin' +export { createResource, getCachedResource } from './resources' diff --git a/src/resources/local.js b/src/resources/local.ts similarity index 63% rename from src/resources/local.js rename to src/resources/local.ts index d01597baa..6e6a4160f 100644 --- a/src/resources/local.js +++ b/src/resources/local.ts @@ -1,6 +1,6 @@ -import { get, set, del } from 'idb-keyval' +import { del, get, set } from 'idb-keyval' -export function saveLocal(key, data) { +export function saveLocal(key: string, data: T): Promise { if (typeof indexedDB === 'undefined') { return Promise.resolve(null) } @@ -8,7 +8,7 @@ export function saveLocal(key, data) { return set(key, JSON.stringify(data)) } -export function deleteLocal(key) { +export function deleteLocal(key: string): Promise { if (typeof indexedDB === 'undefined') { return Promise.resolve(null) } @@ -16,7 +16,7 @@ export function deleteLocal(key) { return del(key) } -export function getLocal(key) { +export function getLocal(key: string): Promise { if (typeof indexedDB === 'undefined') { return Promise.resolve(null) } diff --git a/tsconfig.json b/tsconfig.json index ba89ee82d..c7c5e2d4f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,8 @@ "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, "strict": true, "jsx": "preserve", "resolveJsonModule": true, diff --git a/tsconfig.node.json b/tsconfig.node.json index 5c7da27d2..a41676015 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -2,7 +2,7 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "allowSyntheticDefaultImports": true }, "include": [ From 1bc0aa0f1091aba737f75f46cff877bff7b13a1d Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Thu, 6 Nov 2025 22:20:35 +0530 Subject: [PATCH 02/14] chore: code cleanup --- src/index.ts | 80 +++++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/src/index.ts b/src/index.ts index ba30fafed..238d4917e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,14 +5,12 @@ export * from './components/Avatar' export * from './components/Badge' export * from './components/Breadcrumbs' export * from './components/Button' -export * from './components/Calendar' export { default as Card } from './components/Card.vue' -export * from './components/Checkbox' -export * from './components/CircularProgressBar' export * from './components/Combobox' -export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' -export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' -export * from './components/DatePicker' +export * from './components/Checkbox' +export { default as DatePicker } from './components/DatePicker/DatePicker.vue' +export { default as DateTimePicker } from './components/DatePicker/DateTimePicker.vue' +export { default as DateRangePicker } from './components/DatePicker/DateRangePicker.vue' export * from './components/Dialog' export { default as Dialogs } from './components/Dialogs.vue' export * from './components/Divider' @@ -24,49 +22,49 @@ export * from './components/FormControl' export { default as FormLabel } from './components/FormLabel.vue' export { default as GreenCheckIcon } from './components/GreenCheckIcon.vue' export { default as Input } from './components/Input.vue' -export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' -export { default as ListFilter } from './components/ListFilter/ListFilter.vue' -export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' export { default as ListItem } from './components/ListItem.vue' -export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' -export { default as ListFooter } from './components/ListView/ListFooter.vue' -export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' -export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' -export { default as ListGroups } from './components/ListView/ListGroups.vue' -export { default as ListHeader } from './components/ListView/ListHeader.vue' -export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' -export { default as ListRow } from './components/ListView/ListRow.vue' -export { default as ListRowItem } from './components/ListView/ListRowItem.vue' -export { default as ListRows } from './components/ListView/ListRows.vue' -export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' -export { - default as List, - default as ListView, -} from './components/ListView/ListView.vue' export { default as LoadingIndicator } from './components/LoadingIndicator.vue' export { default as LoadingText } from './components/LoadingText.vue' -export * from './components/Password' -export * from './components/Popover' export * from './components/Progress' -export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' +export * from './components/Popover' export * from './components/Rating' export { default as Resource } from './components/Resource.vue' export * from './components/Select' -export { default as Sidebar } from './components/Sidebar/Sidebar.vue' +export * from './components/Password' export * from './components/Spinner' export * from './components/Switch' export * from './components/TabButtons' -export { default as TabList } from './components/Tabs/TabList.vue' -export { default as TabPanel } from './components/Tabs/TabPanel.vue' -export { default as Tabs } from './components/Tabs/Tabs.vue' +export * from './components/DatePicker' +export * from './components/TextInput' export * from './components/Textarea' export * from './components/TextEditor' -export * from './components/TextInput' export * from './components/TimePicker' -export { toast } from './components/Toast/index' +export { default as ListView } from './components/ListView/ListView.vue' +export { default as List } from './components/ListView/ListView.vue' +export { default as ListHeader } from './components/ListView/ListHeader.vue' +export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' +export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' +export { default as ListRows } from './components/ListView/ListRows.vue' +export { default as ListRow } from './components/ListView/ListRow.vue' +export { default as ListRowItem } from './components/ListView/ListRowItem.vue' +export { default as ListGroups } from './components/ListView/ListGroups.vue' +export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' +export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' +export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' +export { default as ListFooter } from './components/ListView/ListFooter.vue' export { default as Toast } from './components/Toast/Toast.vue' +export { toast } from './components/Toast/index' export * from './components/Tooltip' +export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' +export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' +export { default as ListFilter } from './components/ListFilter/ListFilter.vue' +export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' +export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' +export * from './components/Calendar' +export * from './components/CircularProgressBar' export * from './components/Tree' +export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' +export { default as Sidebar } from './components/Sidebar/Sidebar.vue' // grid layout export { default as GridLayout } from './components/VueGridLayout/Layout.vue' @@ -77,32 +75,32 @@ export { default as visibilityDirective } from './directives/visibility' // utilities export { default as call, createCall } from './utils/call.js' -export { dayjs, dayjsLocal } from './utils/dayjs' export { default as debounce } from './utils/debounce' export { default as fileToBase64 } from './utils/file-to-base64' export { default as FileUploadHandler } from './utils/fileUploadHandler' export { usePageMeta } from './utils/pageMeta' -export * from './utils/theme' +export { dayjsLocal, dayjs } from './utils/dayjs' export * from './utils/useFileUpload' +export * from './utils/theme' // old data-fetching: resources -export * from './resources/index.ts' -export { getConfig, setConfig } from './utils/config' -export { frappeRequest } from './utils/frappeRequest.js' +export * from './resources/index.js' export { request } from './utils/request.js' +export { frappeRequest } from './utils/frappeRequest.js' export { default as initSocket } from './utils/socketio.js' +export { setConfig, getConfig } from './utils/config' // new data-fetching composables export { useCall, + useList, useDoc, + useNewDoc, useDoctype, useFrappeFetch, - useList, - useNewDoc, } from './data-fetching' // plugin -export { confirmDialog } from './utils/confirmDialog.js' export { default as pageMetaPlugin } from './utils/pageMeta.js' export { default as FrappeUI } from './utils/plugin.js' +export { confirmDialog } from './utils/confirmDialog.js' \ No newline at end of file From 69f2de971f66946c357981d1bbc2b4349034488d Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Thu, 6 Nov 2025 22:52:03 +0530 Subject: [PATCH 03/14] fix: export stylesheet properly --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 834760c34..5414ed129 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "types": "./src/index.ts" }, "./src/tailwind/preset": { - "import": "./src/tailwind/preset.js" + "import": "./src/tailwind/preset.js", + "default": "./src/tailwind/preset.js" }, "./vite": { "import": "./vite/index.js" From 172d6f5257b44caa2d72c6d6defefe15617ac736 Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Thu, 6 Nov 2025 22:58:52 +0530 Subject: [PATCH 04/14] chore: restore tab component export --- src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 238d4917e..bca1ebe8f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,9 +8,7 @@ export * from './components/Button' export { default as Card } from './components/Card.vue' export * from './components/Combobox' export * from './components/Checkbox' -export { default as DatePicker } from './components/DatePicker/DatePicker.vue' -export { default as DateTimePicker } from './components/DatePicker/DateTimePicker.vue' -export { default as DateRangePicker } from './components/DatePicker/DateRangePicker.vue' +export * from './components/DatePicker' export * from './components/Dialog' export { default as Dialogs } from './components/Dialogs.vue' export * from './components/Divider' @@ -34,7 +32,9 @@ export * from './components/Password' export * from './components/Spinner' export * from './components/Switch' export * from './components/TabButtons' -export * from './components/DatePicker' +export { default as Tabs } from './components/Tabs/Tabs.vue' +export { default as TabList } from './components/Tabs/TabList.vue' +export { default as TabPanel } from './components/Tabs/TabPanel.vue' export * from './components/TextInput' export * from './components/Textarea' export * from './components/TextEditor' From e9c6497c5e7acb454c40389313bcb4087762e642 Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Tue, 11 Nov 2025 02:16:43 +0530 Subject: [PATCH 05/14] fix: remove internal files from package exports --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index 5414ed129..161b53778 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,6 @@ "./style.css": { "import": "./src/style.css" }, - "./src/*": { - "import": "./src/*" - }, "./charts": { "import": "./src/components/Charts/index.ts" }, From e195e1b86975c8380d03ab9662cce9b0cad53ba9 Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Tue, 11 Nov 2025 02:17:05 +0530 Subject: [PATCH 06/14] fix: add module for frappe folder --- frappe/index.d.ts | 53 +++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 1 + 2 files changed, 54 insertions(+) create mode 100644 frappe/index.d.ts diff --git a/frappe/index.d.ts b/frappe/index.d.ts new file mode 100644 index 000000000..ca8579a74 --- /dev/null +++ b/frappe/index.d.ts @@ -0,0 +1,53 @@ +// Since the export is via JS file, we need to declare the module here +declare module 'frappe-ui/frappe' { + import type { Component, ComputedRef, Ref } from 'vue' + + // Onboarding + export interface OnboardingStep { + name: string + completed: boolean + [key: string]: any + } + + export function useOnboarding(appName: string): + | { + steps: OnboardingStep[] + stepsCompleted: ComputedRef + totalSteps: ComputedRef + completedPercentage: ComputedRef + isOnboardingStepsCompleted: Ref + updateOnboardingStep: ( + step: string, + value?: boolean, + skipped?: boolean, + callback?: ((step: string, skipped: boolean) => void) | null, + ) => void + skip: ( + step: string, + callback?: ((step: string, skipped: boolean) => void) | null, + ) => void + skipAll: (callback?: ((value: boolean) => void) | null) => void + reset: ( + step: string, + callback?: ((step: string, skipped: boolean) => void) | null, + ) => void + resetAll: (callback?: ((value: boolean) => void) | null) => void + setUp: (steps: OnboardingStep[]) => void + syncStatus: () => void + } + | undefined + + // Help Modal + export const showHelpModal: Ref + export const minimize: Ref + export const HelpModal: Component + + // Banners + export const GettingStartedBanner: Component + export const TrialBanner: Component + export const IntermediateStepModal: Component + + // Components + export const Link: Component + export type { LinkProps } from './Link/types' +} diff --git a/tsconfig.json b/tsconfig.json index c7c5e2d4f..84ceb68a0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,7 @@ }, "include": [ "src/**/*.ts", + "frappe/index.d.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", From 3cc75e316875771269f8199cce231b15c7d57b4c Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Tue, 11 Nov 2025 16:37:58 +0530 Subject: [PATCH 07/14] fix: add base-config for TS --- package.json | 9 +++-- src/data-fetching/index.ts | 6 ++- src/index.ts | 79 ++++++++++++++++++-------------------- tsconfig.base.json | 22 +++++++++++ tsconfig.json | 21 +--------- 5 files changed, 69 insertions(+), 68 deletions(-) create mode 100644 tsconfig.base.json diff --git a/package.json b/package.json index 161b53778..718f10c7f 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "import": "./src/index.ts", "types": "./src/index.ts" }, - "./src/tailwind/preset": { + "./tailwind/preset": { "import": "./src/tailwind/preset.js", "default": "./src/tailwind/preset.js" }, @@ -33,12 +33,13 @@ "./style.css": { "import": "./src/style.css" }, - "./charts": { - "import": "./src/components/Charts/index.ts" - }, + "./tsconfig.base.json": "./tsconfig.base.json", "./frappe": { "import": "./frappe/index.js" }, + "./charts": { + "import": "./src/components/Charts/index.ts" + }, "./icons": { "import": "./src/icons.ts" } diff --git a/src/data-fetching/index.ts b/src/data-fetching/index.ts index dce40e959..dc4f19b84 100644 --- a/src/data-fetching/index.ts +++ b/src/data-fetching/index.ts @@ -1,6 +1,8 @@ +export * from './useCall/types' export { useCall } from './useCall/useCall' -export { useList } from './useList/useList' export { useDoc } from './useDoc/useDoc' export { useDoctype } from './useDoctype/useDoctype' -export { useNewDoc } from './useNewDoc/useNewDoc' export { useFrappeFetch } from './useFrappeFetch' +export * from './useList/types' +export { useList } from './useList/useList' +export { useNewDoc } from './useNewDoc/useNewDoc' diff --git a/src/index.ts b/src/index.ts index bca1ebe8f..2b4403c9e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,9 +5,13 @@ export * from './components/Avatar' export * from './components/Badge' export * from './components/Breadcrumbs' export * from './components/Button' +export * from './components/Calendar' export { default as Card } from './components/Card.vue' -export * from './components/Combobox' export * from './components/Checkbox' +export * from './components/CircularProgressBar' +export * from './components/Combobox' +export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' +export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' export * from './components/DatePicker' export * from './components/Dialog' export { default as Dialogs } from './components/Dialogs.vue' @@ -20,51 +24,49 @@ export * from './components/FormControl' export { default as FormLabel } from './components/FormLabel.vue' export { default as GreenCheckIcon } from './components/GreenCheckIcon.vue' export { default as Input } from './components/Input.vue' +export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' +export { default as ListFilter } from './components/ListFilter/ListFilter.vue' +export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' export { default as ListItem } from './components/ListItem.vue' +export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' +export { default as ListFooter } from './components/ListView/ListFooter.vue' +export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' +export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' +export { default as ListGroups } from './components/ListView/ListGroups.vue' +export { default as ListHeader } from './components/ListView/ListHeader.vue' +export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' +export { default as ListRow } from './components/ListView/ListRow.vue' +export { default as ListRowItem } from './components/ListView/ListRowItem.vue' +export { default as ListRows } from './components/ListView/ListRows.vue' +export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' +export { + default as List, + default as ListView, +} from './components/ListView/ListView.vue' export { default as LoadingIndicator } from './components/LoadingIndicator.vue' export { default as LoadingText } from './components/LoadingText.vue' -export * from './components/Progress' +export * from './components/Password' export * from './components/Popover' +export * from './components/Progress' +export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' export * from './components/Rating' export { default as Resource } from './components/Resource.vue' export * from './components/Select' -export * from './components/Password' +export { default as Sidebar } from './components/Sidebar/Sidebar.vue' export * from './components/Spinner' export * from './components/Switch' export * from './components/TabButtons' -export { default as Tabs } from './components/Tabs/Tabs.vue' export { default as TabList } from './components/Tabs/TabList.vue' export { default as TabPanel } from './components/Tabs/TabPanel.vue' -export * from './components/TextInput' +export { default as Tabs } from './components/Tabs/Tabs.vue' export * from './components/Textarea' export * from './components/TextEditor' +export * from './components/TextInput' export * from './components/TimePicker' -export { default as ListView } from './components/ListView/ListView.vue' -export { default as List } from './components/ListView/ListView.vue' -export { default as ListHeader } from './components/ListView/ListHeader.vue' -export { default as ListHeaderItem } from './components/ListView/ListHeaderItem.vue' -export { default as ListEmptyState } from './components/ListView/ListEmptyState.vue' -export { default as ListRows } from './components/ListView/ListRows.vue' -export { default as ListRow } from './components/ListView/ListRow.vue' -export { default as ListRowItem } from './components/ListView/ListRowItem.vue' -export { default as ListGroups } from './components/ListView/ListGroups.vue' -export { default as ListGroupHeader } from './components/ListView/ListGroupHeader.vue' -export { default as ListGroupRows } from './components/ListView/ListGroupRows.vue' -export { default as ListSelectBanner } from './components/ListView/ListSelectBanner.vue' -export { default as ListFooter } from './components/ListView/ListFooter.vue' -export { default as Toast } from './components/Toast/Toast.vue' export { toast } from './components/Toast/index' +export { default as Toast } from './components/Toast/Toast.vue' export * from './components/Tooltip' -export { default as CommandPalette } from './components/CommandPalette/CommandPalette.vue' -export { default as CommandPaletteItem } from './components/CommandPalette/CommandPaletteItem.vue' -export { default as ListFilter } from './components/ListFilter/ListFilter.vue' -export { default as NestedPopover } from './components/ListFilter/NestedPopover.vue' -export { default as KeyboardShortcut } from './components/KeyboardShortcut.vue' -export * from './components/Calendar' -export * from './components/CircularProgressBar' export * from './components/Tree' -export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvider.vue' -export { default as Sidebar } from './components/Sidebar/Sidebar.vue' // grid layout export { default as GridLayout } from './components/VueGridLayout/Layout.vue' @@ -74,33 +76,26 @@ export { default as onOutsideClickDirective } from './directives/onOutsideClick' export { default as visibilityDirective } from './directives/visibility' // utilities +export { getCommonSiteConfig } from '../vite/utils.js' export { default as call, createCall } from './utils/call.js' +export { dayjs, dayjsLocal } from './utils/dayjs' export { default as debounce } from './utils/debounce' export { default as fileToBase64 } from './utils/file-to-base64' export { default as FileUploadHandler } from './utils/fileUploadHandler' export { usePageMeta } from './utils/pageMeta' -export { dayjsLocal, dayjs } from './utils/dayjs' -export * from './utils/useFileUpload' export * from './utils/theme' - +export * from './utils/useFileUpload' // old data-fetching: resources export * from './resources/index.js' -export { request } from './utils/request.js' +export { getConfig, setConfig } from './utils/config' export { frappeRequest } from './utils/frappeRequest.js' +export { request } from './utils/request.js' export { default as initSocket } from './utils/socketio.js' -export { setConfig, getConfig } from './utils/config' // new data-fetching composables -export { - useCall, - useList, - useDoc, - useNewDoc, - useDoctype, - useFrappeFetch, -} from './data-fetching' +export * from './data-fetching' // plugin +export { confirmDialog } from './utils/confirmDialog.js' export { default as pageMetaPlugin } from './utils/pageMeta.js' export { default as FrappeUI } from './utils/plugin.js' -export { confirmDialog } from './utils/confirmDialog.js' \ No newline at end of file diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 000000000..75f1b75aa --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "strict": true, + "jsx": "preserve", + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "noEmit": true, + "types": ["vitest/globals", "unplugin-icons/types/vue"], + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 84ceb68a0..38cd7e3fb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,24 +1,4 @@ { - "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "strict": true, - "jsx": "preserve", - "resolveJsonModule": true, - "isolatedModules": true, - "esModuleInterop": true, - "lib": ["ESNext", "DOM"], - "skipLibCheck": true, - "noEmit": true, - "types": ["vitest/globals", "unplugin-icons/types/vue"], - "baseUrl": ".", - "paths": { - "@/*": ["src/*"] - } - }, "include": [ "src/**/*.ts", "frappe/index.d.ts", @@ -34,5 +14,6 @@ "vitest.config.ts", "vitest.setup.ts" ], + "extends": "./tsconfig.base.json", "references": [{ "path": "./tsconfig.node.json" }] } From 77afef86bf89d0019179fe543b245edd7591434b Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Wed, 12 Nov 2025 17:58:58 +0530 Subject: [PATCH 08/14] fix: move charts back to root barrel file --- package.json | 19 ++++++++----------- src/components/Charts/index.ts | 6 ------ src/components/Sidebar/index.ts | 3 +++ src/index.ts | 12 ++++++++++-- src/resources/index.ts | 1 + src/resources/realtime.js | 15 --------------- src/resources/realtime.ts | 21 +++++++++++++++++++++ 7 files changed, 43 insertions(+), 34 deletions(-) delete mode 100644 src/resources/realtime.js create mode 100644 src/resources/realtime.ts diff --git a/package.json b/package.json index 718f10c7f..4ff5fb9ac 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,13 @@ "import": "./src/index.ts", "types": "./src/index.ts" }, - "./tailwind/preset": { + "./frappe": { + "import": "./frappe/index.js" + }, + "./icons": { + "import": "./src/icons.ts" + }, + "./tailwind": { "import": "./src/tailwind/preset.js", "default": "./src/tailwind/preset.js" }, @@ -33,16 +39,7 @@ "./style.css": { "import": "./src/style.css" }, - "./tsconfig.base.json": "./tsconfig.base.json", - "./frappe": { - "import": "./frappe/index.js" - }, - "./charts": { - "import": "./src/components/Charts/index.ts" - }, - "./icons": { - "import": "./src/icons.ts" - } + "./tsconfig.base.json": "./tsconfig.base.json" }, "files": [ "frappe", diff --git a/src/components/Charts/index.ts b/src/components/Charts/index.ts index e01df8db3..e69de29bb 100644 --- a/src/components/Charts/index.ts +++ b/src/components/Charts/index.ts @@ -1,6 +0,0 @@ -// chart components -export { default as AxisChart } from './AxisChart.vue' -export { default as DonutChart } from './DonutChart.vue' -export { default as ECharts } from './ECharts.vue' -export { default as FunnelChart } from './FunnelChart.vue' -export { default as NumberChart } from './NumberChart.vue' diff --git a/src/components/Sidebar/index.ts b/src/components/Sidebar/index.ts index bde645a6f..04479fd49 100644 --- a/src/components/Sidebar/index.ts +++ b/src/components/Sidebar/index.ts @@ -1,2 +1,5 @@ export { default as Sidebar } from './Sidebar.vue' +export { default as SidebarHeader } from './SidebarHeader.vue' +export { default as SidebarItem } from './SidebarItem.vue' +export { default as SidebarSection } from './SidebarSection.vue' export type { SidebarProps } from './types' diff --git a/src/index.ts b/src/index.ts index 2b4403c9e..4e5d70884 100644 --- a/src/index.ts +++ b/src/index.ts @@ -52,7 +52,7 @@ export { default as FrappeUIProvider } from './components/Provider/FrappeUIProvi export * from './components/Rating' export { default as Resource } from './components/Resource.vue' export * from './components/Select' -export { default as Sidebar } from './components/Sidebar/Sidebar.vue' +export * from './components/Sidebar/index.ts' export * from './components/Spinner' export * from './components/Switch' export * from './components/TabButtons' @@ -85,8 +85,9 @@ export { default as FileUploadHandler } from './utils/fileUploadHandler' export { usePageMeta } from './utils/pageMeta' export * from './utils/theme' export * from './utils/useFileUpload' + // old data-fetching: resources -export * from './resources/index.js' +export * from './resources/index.ts' export { getConfig, setConfig } from './utils/config' export { frappeRequest } from './utils/frappeRequest.js' export { request } from './utils/request.js' @@ -99,3 +100,10 @@ export * from './data-fetching' export { confirmDialog } from './utils/confirmDialog.js' export { default as pageMetaPlugin } from './utils/pageMeta.js' export { default as FrappeUI } from './utils/plugin.js' + +// chart components +export { default as AxisChart } from './components/Charts/AxisChart.vue' +export { default as DonutChart } from './components/Charts/DonutChart.vue' +export { default as ECharts } from './components/Charts/ECharts.vue' +export { default as FunnelChart } from './components/Charts/FunnelChart.vue' +export { default as NumberChart } from './components/Charts/NumberChart.vue' diff --git a/src/resources/index.ts b/src/resources/index.ts index 9f57b734e..6e7b33265 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -5,4 +5,5 @@ export { export { createListResource, getCachedListResource } from './listResource' export * from './local' export { default as resourcesPlugin } from './plugin' +export * from './realtime' export { createResource, getCachedResource } from './resources' diff --git a/src/resources/realtime.js b/src/resources/realtime.js deleted file mode 100644 index 3dbdff830..000000000 --- a/src/resources/realtime.js +++ /dev/null @@ -1,15 +0,0 @@ -export function onDocUpdate(socket, doctype, callback) { - subscribe(socket, doctype) - socket.on('list_update', (data) => { - if (data.doctype == doctype) { - callback(data.name) - } - }) -} - -let subscribed = {} -function subscribe(socket, doctype) { - if (subscribed[doctype]) return - socket.emit('doctype_subscribe', doctype) - subscribed[doctype] = true -} diff --git a/src/resources/realtime.ts b/src/resources/realtime.ts new file mode 100644 index 000000000..17a1768ad --- /dev/null +++ b/src/resources/realtime.ts @@ -0,0 +1,21 @@ +import { Socket } from 'socket.io-client' + +export function onDocUpdate( + socket: Socket, + doctype: string, + callback: (name: string) => void, +): void { + subscribe(socket, doctype) + socket.on('list_update', (data) => { + if (data.doctype == doctype) { + callback(data.name) + } + }) +} + +let subscribed: Record = {} +function subscribe(socket: Socket, doctype: string): void { + if (subscribed[doctype]) return + socket.emit('doctype_subscribe', doctype) + subscribed[doctype] = true +} From 062219b2b112f16470db3e4bd06911bdd928a85a Mon Sep 17 00:00:00 2001 From: Ritvik Sardana Date: Wed, 12 Nov 2025 18:13:58 +0530 Subject: [PATCH 09/14] chore: move icons --- frappe/Billing/SignupBanner.vue | 2 +- frappe/Billing/TrialBanner.vue | 2 +- frappe/Help/HelpModal.vue | 8 ++++---- frappe/Onboarding/GettingStartedBanner.vue | 2 +- src/icons/CircleCheck.vue => icons/CircleCheckIcon.vue | 0 src/icons/DownSolid.vue => icons/DownSolidIcon.vue | 0 {frappe/Icons => icons}/HelpIcon.vue | 0 {frappe/Icons => icons}/LightningIcon.vue | 0 {frappe/Icons => icons}/MaximizeIcon.vue | 0 {frappe/Icons => icons}/MinimizeIcon.vue | 0 {frappe/Icons => icons}/StepsIcon.vue | 0 icons/index.ts | 9 +++++++++ src/components/ListView/ListGroupHeader.vue | 2 +- src/components/Toast/Toast.vue | 2 +- src/icons.ts | 9 --------- 15 files changed, 18 insertions(+), 18 deletions(-) rename src/icons/CircleCheck.vue => icons/CircleCheckIcon.vue (100%) rename src/icons/DownSolid.vue => icons/DownSolidIcon.vue (100%) rename {frappe/Icons => icons}/HelpIcon.vue (100%) rename {frappe/Icons => icons}/LightningIcon.vue (100%) rename {frappe/Icons => icons}/MaximizeIcon.vue (100%) rename {frappe/Icons => icons}/MinimizeIcon.vue (100%) rename {frappe/Icons => icons}/StepsIcon.vue (100%) create mode 100644 icons/index.ts delete mode 100644 src/icons.ts diff --git a/frappe/Billing/SignupBanner.vue b/frappe/Billing/SignupBanner.vue index 289d4146f..dff9dade1 100644 --- a/frappe/Billing/SignupBanner.vue +++ b/frappe/Billing/SignupBanner.vue @@ -25,7 +25,7 @@