From 8d2981bf6c5d8a1f1160ca7233667adbac523908 Mon Sep 17 00:00:00 2001 From: Nicolas Merget Date: Tue, 14 Jan 2025 17:25:11 +0100 Subject: [PATCH 01/10] chore: replace mitosis generated vue output (options-api) with composition-api --- output/vue/package.json | 9 ++- output/vue/scripts/fix-any-types.ts | 57 ------------------- .../mitosis/new/component/tsx.ejs.t | 6 +- packages/components/configs/vue/index.js | 3 +- packages/components/scripts/post-build/vue.ts | 31 ++-------- .../accordion-item/accordion-item.lite.tsx | 7 ++- .../accordion-item/accordion-item.scss | 2 +- .../components/accordion/accordion.lite.tsx | 19 ++++--- .../src/components/badge/badge.lite.tsx | 13 +++-- .../src/components/brand/brand.lite.tsx | 14 ++++- .../src/components/button/button.lite.tsx | 14 ++++- .../src/components/card/card.lite.tsx | 13 ++++- .../src/components/checkbox/checkbox.lite.tsx | 17 +++--- .../src/components/checkbox/docs/Vue.md | 4 +- .../src/components/divider/divider.lite.tsx | 13 ++++- .../src/components/drawer/docs/Vue.md | 4 +- .../src/components/drawer/drawer.lite.tsx | 25 ++++---- .../src/components/drawer/drawer.scss | 4 +- .../src/components/header/docs/Vue.md | 4 +- .../src/components/header/header.lite.tsx | 7 ++- .../src/components/icon/icon.lite.tsx | 14 ++++- .../src/components/infotext/infotext.lite.tsx | 14 ++++- .../src/components/input/input.lite.tsx | 17 +++--- .../src/components/input/input.scss | 2 +- .../src/components/link/link.lite.tsx | 20 ++++--- .../navigation-item/navigation-item.lite.tsx | 9 ++- .../navigation-item/navigation-item.scss | 4 +- .../navigation/docs/Accessibility.md | 2 +- .../components/navigation/navigation.lite.tsx | 14 ++++- .../src/components/navigation/navigation.scss | 2 +- .../notification/notification.lite.tsx | 15 ++++- .../src/components/page/page.lite.tsx | 6 +- .../components/src/components/page/page.scss | 2 +- .../src/components/popover/popover.lite.tsx | 22 +++---- .../src/components/radio/docs/Vue.md | 4 +- .../src/components/radio/radio.lite.tsx | 6 +- .../src/components/radio/radio.scss | 2 +- .../src/components/section/section.lite.tsx | 13 ++++- .../src/components/select/select.lite.tsx | 16 +++--- .../src/components/stack/stack.lite.tsx | 14 +++-- .../src/components/switch/switch.lite.tsx | 8 ++- .../src/components/switch/switch.scss | 4 +- .../src/components/tab-item/tab-item.lite.tsx | 12 ++-- .../src/components/tab-list/tab-list.lite.tsx | 13 ++++- .../components/tab-panel/tab-panel.lite.tsx | 6 +- .../components/src/components/tabs/index.html | 20 +++---- .../src/components/tabs/tabs.lite.tsx | 48 +++++++++------- .../src/components/tag/tag.lite.tsx | 14 +++-- .../src/components/textarea/docs/Vue.md | 6 +- .../src/components/textarea/textarea.lite.tsx | 16 +++--- .../src/components/tooltip/tooltip.lite.tsx | 16 +++--- .../components/src/utils/form-components.ts | 2 +- packages/components/src/utils/navigation.ts | 29 +++++++--- .../src/components/DefaultComponent.vue | 6 +- 54 files changed, 370 insertions(+), 294 deletions(-) delete mode 100644 output/vue/scripts/fix-any-types.ts diff --git a/output/vue/package.json b/output/vue/package.json index 670089f1e71..1c8a24109e7 100644 --- a/output/vue/package.json +++ b/output/vue/package.json @@ -13,12 +13,12 @@ "exports": { ".": { "import": { - "default": "./dist/db-ui.es.js", - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "default": "./dist/db-ui.es.js" }, "require": { - "default": "./dist/db-ui.umd.js", - "types": "./dist/index.d.ts" + "types": "./dist/index.d.ts", + "default": "./dist/db-ui.umd.js" } } }, @@ -30,7 +30,6 @@ "build": "npm-run-all build:*", "build:01_vite": "vite build", "build:02_types": "vue-tsc --declaration --emitDeclarationOnly", - "build:03_ts_workaround": "tsx scripts/fix-any-types.ts", "mv:dist": "cpr dist ../../build-outputs/vue/dist -o", "mv:package.json": "cpr package.json ../../build-outputs/vue/package.json -o", "mv:readme": "cpr README.md ../../build-outputs/vue/README.md -o", diff --git a/output/vue/scripts/fix-any-types.ts b/output/vue/scripts/fix-any-types.ts deleted file mode 100644 index 65b1ff44a7c..00000000000 --- a/output/vue/scripts/fix-any-types.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { readdirSync } from 'node:fs'; -import { replaceInFileSync } from 'replace-in-file'; - -const distDir = './dist/components'; - -const transformToUpperComponentName = (componentName: string) => - componentName - .split('-') - .map((part) => `${part[0].toUpperCase()}${part.slice(1)}`) - .join(''); - -/** - * Props are generated like this: `readonly id?: any;` - * We replace it with the correct type like DBMyComponent["id"] - */ -const replaceAnyTypes = (input: string, component: string) => { - const propModel = `DB${transformToUpperComponentName(component)}Props`; - let fileContent = input; - - const readOnlyLines = fileContent.match(/Readonly<{[\s\S]*?}>/g); - for (const roLine of readOnlyLines) { - const propLines = roLine.match(/(.*);/g); - if (propLines) { - propLines.forEach((propLine) => { - // Check if prop(contains ": any") or function - if (propLine.includes(': any;')) { - const prop = propLine - .replace('?: any;', '') - .replace(': any;', '') - .trim(); - // @ts-ignore - fileContent = fileContent.replaceAll( - propLine, - propLine.replace('any', `${propModel}["${prop}"]`) - ); - } - }); - } - } - - return `import { ${propModel} } from "./model";\n\n${fileContent}`; -}; - -const fixAnyTypes = () => { - const components: string[] = readdirSync(distDir); - - for (const component of components) { - replaceInFileSync({ - files: `${distDir}/${component}/${component}.vue.d.ts`, - processor(input: string) { - return replaceAnyTypes(input, component); - } - }); - } -}; - -fixAnyTypes(); diff --git a/packages/components/_templates/mitosis/new/component/tsx.ejs.t b/packages/components/_templates/mitosis/new/component/tsx.ejs.t index 61ed4db0691..c2faf8a2ebe 100644 --- a/packages/components/_templates/mitosis/new/component/tsx.ejs.t +++ b/packages/components/_templates/mitosis/new/component/tsx.ejs.t @@ -1,7 +1,7 @@ --- to: src/components/<%= name %>/<%= name %>.lite.tsx --- -import { Show, useMetadata, useStore, useRef } from "@builder.io/mitosis"; +import { Show, useMetadata, useStore, useRef, useDefaultProps } from "@builder.io/mitosis"; import { DB<%= h.changeCase.pascal(name) %>State, DB<%= h.changeCase.pascal(name) %>Props } from "./model"; import { cls } from "../../utils"; <% if(formValue!=="no"){ -%> @@ -11,9 +11,11 @@ import { handleFrameworkEvent } from "../../utils/form-components"; useMetadata({}); +useDefaultProps< DB<%= h.changeCase.pascal(name) %>Props>({}); + export default function DB<%= h.changeCase.pascal(name) %>(props: DB<%= h.changeCase.pascal(name) %>Props) { // This is used as forwardRef - const ref = useRef(null); + const _ref = useRef(null); // jscpd:ignore-start const state = useStoreState>({ <% if(formValue!=="no"){ -%> diff --git a/packages/components/configs/vue/index.js b/packages/components/configs/vue/index.js index fcf5f165fc6..76acfa02a2b 100644 --- a/packages/components/configs/vue/index.js +++ b/packages/components/configs/vue/index.js @@ -1,3 +1,4 @@ module.exports = { - typescript: true + typescript: true, + api: 'composition' }; diff --git a/packages/components/scripts/post-build/vue.ts b/packages/components/scripts/post-build/vue.ts index 1763c55b470..cd75f213e24 100644 --- a/packages/components/scripts/post-build/vue.ts +++ b/packages/components/scripts/post-build/vue.ts @@ -2,7 +2,7 @@ import { replaceInFileSync } from 'replace-in-file'; import components, { Overwrite } from './components.js'; -import { runReplacements, transformToUpperComponentName } from '../utils'; +import { runReplacements } from '../utils'; export default (tmp?: boolean) => { const outputFolder = `${tmp ? 'output/tmp' : 'output'}`; @@ -38,40 +38,19 @@ export default (tmp?: boolean) => { const replacements: Overwrite[] = [ { - from: /immediate: true,/g, + from: /immediate: true/g, to: 'immediate: true,\nflush: "post"' - }, - /* `this` can be undefined for ssr (nuxt) we need to add */ - { - from: /this.\$refs.ref\?.validationMessage/g, - to: '(this as any)?.$refs.ref?.validationMessage' } ]; - /* This is a workaround for valid/invalid Messages. - * If a valid/invalid message appears it will use the old this._value, - * so we need to overwrite this._value with the current event.target.value. */ - [ - 'HTMLSelectElement', - 'HTMLInputElement', - 'HTMLTextAreaElement' - ].forEach((element) => { - replacements.push({ - from: `handleInput(event: InputEvent<${element}>) {`, - to: - `handleInput(event: InputEvent<${element}>) {\n` + - 'this._value = (event.target as any).value;' - }); - }); - if (component?.config?.vue?.vModel) { replacements.push({ - from: 'props: [', - to: `emits: ${JSON.stringify( + from: 'const props =', + to: `const emit = defineEmits(${JSON.stringify( component?.config?.vue?.vModel.map( (bin) => `update:${bin.modelValue}` ) - )},\nprops: [` + )})\n\nconst props =` }); } diff --git a/packages/components/src/components/accordion-item/accordion-item.lite.tsx b/packages/components/src/components/accordion-item/accordion-item.lite.tsx index a57d527b1e0..eef1b106fe2 100644 --- a/packages/components/src/components/accordion-item/accordion-item.lite.tsx +++ b/packages/components/src/components/accordion-item/accordion-item.lite.tsx @@ -2,6 +2,7 @@ import { onMount, Show, Slot, + useDefaultProps, useMetadata, useRef, useStore @@ -13,8 +14,10 @@ import { DEFAULT_ID } from '../../shared/constants'; useMetadata({}); +useDefaultProps({}); + export default function DBAccordionItem(props: DBAccordionItemProps) { - const ref = useRef(null); + const _ref = useRef(null); // jscpd:ignore-start const state = useStore({ _id: DEFAULT_ID, @@ -42,7 +45,7 @@ export default function DBAccordionItem(props: DBAccordionItemProps) {
  • state.toggle(event)}> diff --git a/packages/components/src/components/accordion-item/accordion-item.scss b/packages/components/src/components/accordion-item/accordion-item.scss index 5e8e18f0087..0cdab82a93d 100644 --- a/packages/components/src/components/accordion-item/accordion-item.scss +++ b/packages/components/src/components/accordion-item/accordion-item.scss @@ -16,7 +16,7 @@ $db-accordion-item-border-radius: variables.$db-border-radius-sm; > details { &[open] { summary + div { - @media screen and (prefers-reduced-motion: no-preference) { + @media screen and (p_refers-reduced-motion: no-p_reference) { animation: accordion-open #{variables.$db-transition-straight-emotional} normal both; diff --git a/packages/components/src/components/accordion/accordion.lite.tsx b/packages/components/src/components/accordion/accordion.lite.tsx index 41193e14503..0cf5037e385 100644 --- a/packages/components/src/components/accordion/accordion.lite.tsx +++ b/packages/components/src/components/accordion/accordion.lite.tsx @@ -3,6 +3,7 @@ import { onMount, onUpdate, Show, + useDefaultProps, useMetadata, useRef, useStore @@ -15,8 +16,10 @@ import { DEFAULT_ID } from '../../shared/constants'; useMetadata({}); +useDefaultProps({}); + export default function DBAccordion(props: DBAccordionProps) { - const ref = useRef(null); + const _ref = useRef(null); // jscpd:ignore-start const state = useStore({ _id: DEFAULT_ID, @@ -68,8 +71,8 @@ export default function DBAccordion(props: DBAccordionProps) { }, [state.initialized, props.name, props.behaviour, state._id]); onUpdate(() => { - if (ref) { - const childDetails = ref.getElementsByTagName('details'); + if (_ref) { + const childDetails = _ref.getElementsByTagName('details'); if (childDetails) { for (const details of Array.from( childDetails @@ -82,12 +85,12 @@ export default function DBAccordion(props: DBAccordionProps) { } } } - }, [ref, state._name]); + }, [_ref, state._name]); onUpdate(() => { - if (ref && state._initOpenIndexDone) { + if (_ref && state._initOpenIndexDone) { if (props?.initOpenIndex && props.initOpenIndex?.length > 0) { - const childDetails = ref.getElementsByTagName('details'); + const childDetails = _ref.getElementsByTagName('details'); if (childDetails) { const initOpenIndex = props.behaviour === 'single' && @@ -105,11 +108,11 @@ export default function DBAccordion(props: DBAccordionProps) { } state._initOpenIndexDone = false; } - }, [ref, state._initOpenIndexDone, props.initOpenIndex]); + }, [_ref, state._initOpenIndexDone, props.initOpenIndex]); return (
      diff --git a/packages/components/src/components/badge/badge.lite.tsx b/packages/components/src/components/badge/badge.lite.tsx index c0a11fe0e57..80d1bba37bc 100644 --- a/packages/components/src/components/badge/badge.lite.tsx +++ b/packages/components/src/components/badge/badge.lite.tsx @@ -2,6 +2,7 @@ import { onMount, onUpdate, Show, + useDefaultProps, useMetadata, useRef, useStore @@ -12,8 +13,10 @@ import { DEFAULT_LABEL } from '../../shared/constants'; useMetadata({}); +useDefaultProps({}); + export default function DBBadge(props: DBBadgeProps) { - const ref = useRef(null); + const _ref = useRef(null); const state = useStore({ initialized: false }); @@ -23,9 +26,9 @@ export default function DBBadge(props: DBBadgeProps) { }); onUpdate(() => { - if (ref && state.initialized) { + if (_ref && state.initialized) { if (props.placement?.startsWith('corner')) { - let parent = ref.parentElement; + let parent = _ref.parentElement; if (parent && parent.localName.includes('badge')) { // Angular workaround @@ -37,11 +40,11 @@ export default function DBBadge(props: DBBadgeProps) { } } } - }, [ref, state.initialized]); + }, [_ref, state.initialized]); return ( ({}); + export default function DBBrand(props: DBBrandProps) { - const ref = useRef(null); + const _ref = useRef(null); // jscpd:ignore-start const state = useStore({}); // jscpd:ignore-end return (
      ({}); + export default function DBButton(props: DBButtonProps) { - const ref = useRef(null); + const _ref = useRef(null); // jscpd:ignore-start const state = useStore({ handleClick: (event: ClickEvent) => { @@ -24,7 +32,7 @@ export default function DBButton(props: DBButtonProps) { return (