diff --git a/.vscode/settings.json b/.vscode/settings.json index 444d5bf4a118..c2360b2907c1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,11 @@ { "eslint.workingDirectories": [ + "./packages/base", "./packages/localization", "./packages/main", "./packages/fiori", + "./packages/ai", ], "html.customData": [ "./packages/base/dist/vscode.html-custom-data.json", diff --git a/packages/ai/src/Button.ts b/packages/ai/src/Button.ts index 1f8bdd590f3a..dd86d089b373 100644 --- a/packages/ai/src/Button.ts +++ b/packages/ai/src/Button.ts @@ -1,28 +1,19 @@ -import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js"; -import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import property from "@ui5/webcomponents-base/dist/decorators/property.js"; -import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; -import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; -import query from "@ui5/webcomponents-base/dist/decorators/query.js"; -import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import type SplitButton from "@ui5/webcomponents/dist/SplitButton.js"; -import type ButtonDesign from "@ui5/webcomponents/dist/types/ButtonDesign.js"; +import UI5Element, { renderFinished, customElement, property, eventStrict as event, slot, query, i18n, jsxRenderer, AccessibilityTextsHelper } from "@ui5/webcomponents-base"; +import type { SplitButton, ButtonDesign } from "@ui5/webcomponents"; import type ButtonState from "./ButtonState.js"; import { BUTTON_TOOLTIP_TEXT } from "./generated/i18n/i18n-defaults.js"; import "./ButtonState.js"; import ButtonTemplate from "./ButtonTemplate.js"; -import { - getEffectiveAriaLabelText, - getAssociatedLabelForTexts, - getAllAccessibleNameRefTexts, -} from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; // Styles import ButtonCss from "./generated/themes/Button.css.js"; -import { i18n } from "@ui5/webcomponents-base/dist/decorators.js"; -import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import type { AccessibilityAttributes } from "@ui5/webcomponents-base/dist/types.js"; +import type { I18nBundle, AccessibilityAttributes } from "@ui5/webcomponents-base"; + +const { + getEffectiveAriaLabelText, + getAssociatedLabelForTexts, + getAllAccessibleNameRefTexts, +} = AccessibilityTextsHelper; type AIButtonRootAccessibilityAttributes = Pick; type AIButtonArrowButtonAccessibilityAttributes = Pick; @@ -373,6 +364,4 @@ class Button extends UI5Element { Button.define(); export default Button; -export type { - AIButtonAccessibilityAttributes, -}; +export type { AIButtonAccessibilityAttributes }; diff --git a/packages/ai/src/ButtonState.ts b/packages/ai/src/ButtonState.ts index 223e771f53d7..70a3d74ee3d9 100644 --- a/packages/ai/src/ButtonState.ts +++ b/packages/ai/src/ButtonState.ts @@ -1,6 +1,4 @@ -import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import property from "@ui5/webcomponents-base/dist/decorators/property.js"; +import UI5Element, { customElement, property } from "@ui5/webcomponents-base"; /** * @class diff --git a/packages/ai/src/ButtonTemplate.tsx b/packages/ai/src/ButtonTemplate.tsx index 095f49965ad0..e799d4bf9a6a 100644 --- a/packages/ai/src/ButtonTemplate.tsx +++ b/packages/ai/src/ButtonTemplate.tsx @@ -1,3 +1,4 @@ +// import { SplitButton } from "@ui5/webcomponents"; import SplitButton from "@ui5/webcomponents/dist/SplitButton.js"; import type Button from "./Button.js"; diff --git a/packages/ai/src/index.ts b/packages/ai/src/index.ts new file mode 100644 index 000000000000..e553cf4a31a8 --- /dev/null +++ b/packages/ai/src/index.ts @@ -0,0 +1 @@ +export { default as Button } from "./Button.js"; diff --git a/packages/ai/tsconfig.json b/packages/ai/tsconfig.json index a1850462744a..52e963716c66 100644 --- a/packages/ai/tsconfig.json +++ b/packages/ai/tsconfig.json @@ -38,6 +38,9 @@ { "path": "../base" }, + { + "path": "../main" + }, { "path": "../localization" }, diff --git a/packages/ai/vite.preload.js b/packages/ai/vite.preload.js new file mode 100644 index 000000000000..8c7c99433c9a --- /dev/null +++ b/packages/ai/vite.preload.js @@ -0,0 +1,19 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + emptyOutDir: false, + lib: { + entry: ["dist/index.js"], + formats: ["es"], + fileName: (format, entryName) => `bundle-ai.js`, + }, + rollupOptions: { + external: [ + "@ui5/webcomponents-base", + "@ui5/webcomponents", + ], + }, + }, +}); diff --git a/packages/base/src/asset-registries/Icons.ts b/packages/base/src/asset-registries/Icons.ts index d21be0274d43..ca50ddeddf46 100644 --- a/packages/base/src/asset-registries/Icons.ts +++ b/packages/base/src/asset-registries/Icons.ts @@ -160,7 +160,7 @@ const processName = (name: string) => { return { name, collection }; }; -const getIconDataSync = (iconName: string) => { +export const getIconDataSync = (iconName: string) => { const { name, collection } = processName(iconName); return getRegisteredIconData(collection, name); }; @@ -243,7 +243,6 @@ const _getRegisteredNames = async () => { export { registerIconLoader, getIconData, - getIconDataSync, getIconAccessibleName, registerIcon, unsafeRegisterIcon, diff --git a/packages/base/src/index.ts b/packages/base/src/index.ts index 0765f6461e3d..404bdd0b5738 100644 --- a/packages/base/src/index.ts +++ b/packages/base/src/index.ts @@ -28,13 +28,17 @@ import { getTheme, setTheme, getDefaultTheme, + isLegacyThemeFamilyAsync, } from "./config/Theme.js"; // decorators/ import customElement from "./decorators/customElement.js"; import event from "./decorators/event.js"; +import eventStrict from "./decorators/event-strict.js"; import property from "./decorators/property.js"; import slot from "./decorators/slot.js"; +import i18n from "./decorators/i18n.js"; +import query from "./decorators/query.js"; // delegate/ import ItemNavigation from "./delegate/ItemNavigation.js"; @@ -54,7 +58,7 @@ import { URLListValidator, sanitizeHTML } from "./util/HTMLSanitizer.js"; import { registerI18nLoader } from "./asset-registries/i18n.js"; import { registerLocaleDataLoader } from "./asset-registries/LocaleData.js"; import { registerThemePropertiesLoader } from "./asset-registries/Themes.js"; -import { registerIconLoader } from "./asset-registries/Icons.js"; +import { registerIconLoader, getIconAccessibleName, registerIcon } from "./asset-registries/Icons.js"; // Boot.ts import { attachBoot } from "./Boot.js"; @@ -105,6 +109,18 @@ import { addCustomCSS, attachThemeLoaded, detachThemeLoaded } from "./Theming.js // UI5Element.ts import UI5Element from "./UI5Element.js"; +export { default as jsxRenderer } from "./renderer/JsxRenderer.js"; +export * as AccessibilityTextsHelper from "./util/AccessibilityTextsHelper.js"; +export * as Keys from "./Keys.js"; +export { default as willShowContent } from "./util/willShowContent.js"; +export * as Device from "./Device.js"; +export * as Tooltips from "./config/Tooltips.js"; +export { default as toLowercaseEnumValue } from "./util/toLowercaseEnumValue.js"; +export * as InputElementsFormSupport from "./features/InputElementsFormSupport.js"; +export * as Icons from "./asset-registries/Icons.js"; +export { default as executeTemplate } from "./renderer/executeTemplate.js"; +export * as CustomElementsScopeUtils from "./CustomElementsScopeUtils.js"; + export default UI5Element; export { // drag and drop @@ -135,12 +151,16 @@ export { getTheme, setTheme, getDefaultTheme, + isLegacyThemeFamilyAsync, // decorators/ customElement, event, + eventStrict, property, slot, + i18n, + query, // delegate/ ItemNavigation, @@ -164,6 +184,8 @@ export { registerLocaleDataLoader, registerThemePropertiesLoader, registerIconLoader, + getIconAccessibleName, + registerIcon, // Boot.ts attachBoot, @@ -221,3 +243,6 @@ export type JsxTemplate = () => JsxTemplateResult; export type * from "./types.d.ts"; export type * from "./jsx-runtime.d.ts"; +export type { ITabbable } from "./delegate/ItemNavigation.js"; +export type { I18nText } from "./i18nBundle.js"; +export type { IconData, UnsafeIconData } from "./asset-registries/Icons.js"; diff --git a/packages/base/src/index2.ts b/packages/base/src/index2.ts new file mode 100644 index 000000000000..3abd956b3955 --- /dev/null +++ b/packages/base/src/index2.ts @@ -0,0 +1,133 @@ +import type { JSX } from "./jsx-runtime.d.ts"; +import type UI5Element from "./UI5Element.js"; + +// animations/ +export { default as scroll } from "./animations/scroll.js"; +export { default as slideDown } from "./animations/slideDown.js"; +export { default as slideUp } from "./animations/slideUp.js"; + +// config/ +export { getAnimationMode, setAnimationMode } from "./config/AnimationMode.js"; +export { getCalendarType } from "./config/CalendarType.js"; +export { getFirstDayOfWeek, getLegacyDateCalendarCustomizing } from "./config/FormatSettings.js"; +export { + setDefaultIconCollection, + getDefaultIconCollection, +} from "./config/Icons.js"; +export { RegisteredIconCollection } from "./asset-registries/util/IconCollectionsByTheme.js"; +export { default as getEffectiveIconCollection } from "./asset-registries/util/getIconCollectionByTheme.js"; +export { startMultipleDrag } from "./DragAndDrop.js"; +export { + getLanguage, + setLanguage, + getDefaultLanguage, + setFetchDefaultLanguage, + getFetchDefaultLanguage, +} from "./config/Language.js"; +export { getNoConflict, setNoConflict } from "./config/NoConflict.js"; +export { + getTheme, + setTheme, + getDefaultTheme, +} from "./config/Theme.js"; + +// decorators/ +export { default as customElement } from "./decorators/customElement.js"; +export { default as event } from "./decorators/event.js"; +export { default as eventStrict } from "./decorators/event-strict.js"; +export { default as property } from "./decorators/property.js"; +export { default as slot } from "./decorators/slot.js"; +export { default as i18n } from "./decorators/i18n.js"; + +// delegate/ +export { default as ItemNavigation } from "./delegate/ItemNavigation.js"; +export { default as ResizeHandler } from "./delegate/ResizeHandler.js"; +export { default as ScrollEnablement } from "./delegate/ScrollEnablement.js"; + +// locale/ +export { default as applyDirection } from "./locale/applyDirection.js"; +export { attachDirectionChange, detachDirectionChange } from "./locale/directionChange.js"; +export { default as getEffectiveDir } from "./locale/getEffectiveDir.js"; +export { attachLanguageChange, detachLanguageChange } from "./locale/languageChange.js"; + +// util/ +export { URLListValidator, sanitizeHTML } from "./util/HTMLSanitizer.js"; + +// Assets.ts +export { registerI18nLoader } from "./asset-registries/i18n.js"; +export { registerLocaleDataLoader } from "./asset-registries/LocaleData.js"; +export { registerThemePropertiesLoader } from "./asset-registries/Themes.js"; +export { registerIconLoader, getIconAccessibleName } from "./asset-registries/Icons.js"; + +// Boot.ts +export { attachBoot } from "./Boot.js"; + +// CustomElementsScope.ts +export { + setCustomElementsScopingSuffix, + getCustomElementsScopingSuffix, + setCustomElementsScopingRules, + getCustomElementsScopingRules, + getEffectiveScopingSuffixForTag, +} from "./CustomElementsScope.js"; + +// Device.ts +export { + supportsTouch, + isSafari, + isChrome, + isFirefox, + isPhone, + isTablet, + isDesktop, + isCombi, + isIOS, + isAndroid, +} from "./Device.js"; + +// EventProvider.ts +export { default as EventProvider } from "./EventProvider.js"; + +// i18nBundle.ts +export { default as I18nBundle, getI18nBundle, registerCustomI18nBundleGetter } from "./i18nBundle.js"; + +// MediaRange.ts +export { default as MediaRange } from "./MediaRange.js"; + +// Render.ts +export { + renderDeferred, + renderImmediately, + cancelRender, + renderFinished, +} from "./Render.js"; +export * as CustomElementsScopeUtils from "./CustomElementsScopeUtils.js"; + +// Theming.ts +export { addCustomCSS, attachThemeLoaded, detachThemeLoaded } from "./Theming.js"; + +// UI5Element.ts +export { default as UI5Element } from "./UI5Element.js"; + +export { default as jsxRenderer } from "./renderer/JsxRenderer.js"; +export * as AccessibilityTextsHelper from "./util/AccessibilityTextsHelper.js"; +export * as Keys from "./Keys.js"; +export { default as willShowContent } from "./util/willShowContent.js"; +export * as Device from "./Device.js"; +export * as Tooltips from "./config/Tooltips.js"; +export { default as toLowercaseEnumValue } from "./util/toLowercaseEnumValue.js"; +export * as InputElementsFormSupport from "./features/InputElementsFormSupport.js"; +export * as Icons from "./asset-registries/Icons.js"; +export { default as executeTemplate } from "./renderer/executeTemplate.js"; + +type TargetedCustomEvent = Omit, "currentTarget"> & { currentTarget: T }; +// export type UI5NativeEvent = Parameters[0]; +export type UI5CustomEvent = TargetedCustomEvent; +export type JsxTemplateResult = JSX.Element | void; +export type JsxTemplate = () => JsxTemplateResult; + +export type * from "./types.d.ts"; +export type * from "./jsx-runtime.d.ts"; +export type { ITabbable } from "./delegate/ItemNavigation.js"; +export type { I18nText } from "./i18nBundle.js"; +export type { IconData, UnsafeIconData } from "./asset-registries/Icons.js"; diff --git a/packages/base/src/thirdparty/preact/hooks.module.d.ts b/packages/base/src/thirdparty/preact/hooks.module.d.ts new file mode 100644 index 000000000000..3334d2a24da5 --- /dev/null +++ b/packages/base/src/thirdparty/preact/hooks.module.d.ts @@ -0,0 +1,145 @@ +// Intentionally not using a relative path to take advantage of +// the TS version resolution mechanism +import { ErrorInfo, PreactContext, Ref, RefObject } from './preact.module.d.ts'; + +type Inputs = ReadonlyArray; + +export type Dispatch = (value: A) => void; +export type StateUpdater = S | ((prevState: S) => S); + +/** + * Returns a stateful value, and a function to update it. + * @param initialState The initial value (or a function that returns the initial value) + */ +export function useState( + initialState: S | (() => S) +): [S, Dispatch>]; + +export function useState(): [ + S | undefined, + Dispatch> +]; + +export type Reducer = (prevState: S, action: A) => S; + +/** + * An alternative to `useState`. + * + * `useReducer` is usually preferable to `useState` when you have complex state logic that involves + * multiple sub-values. It also lets you optimize performance for components that trigger deep + * updates because you can pass `dispatch` down instead of callbacks. + * @param reducer Given the current state and an action, returns the new state + * @param initialState The initial value to store as state + */ +export function useReducer( + reducer: Reducer, + initialState: S +): [S, Dispatch]; + +/** + * An alternative to `useState`. + * + * `useReducer` is usually preferable to `useState` when you have complex state logic that involves + * multiple sub-values. It also lets you optimize performance for components that trigger deep + * updates because you can pass `dispatch` down instead of callbacks. + * @param reducer Given the current state and an action, returns the new state + * @param initialArg The initial argument to pass to the `init` function + * @param init A function that, given the `initialArg`, returns the initial value to store as state + */ +export function useReducer( + reducer: Reducer, + initialArg: I, + init: (arg: I) => S +): [S, Dispatch]; + +/** @deprecated Use the `Ref` type instead. */ +type PropRef = MutableRef; + +interface MutableRef { + current: T; +} + +/** + * `useRef` returns a mutable ref object whose `.current` property is initialized to the passed argument + * (`initialValue`). The returned object will persist for the full lifetime of the component. + * + * Note that `useRef()` is useful for more than the `ref` attribute. It’s handy for keeping any mutable + * value around similar to how you’d use instance fields in classes. + * + * @param initialValue the initial value to store in the ref object + */ +export function useRef(initialValue: T): MutableRef; +export function useRef(initialValue: T | null): RefObject; +export function useRef(): MutableRef; + +type EffectCallback = () => void | (() => void); +/** + * Accepts a function that contains imperative, possibly effectful code. + * The effects run after browser paint, without blocking it. + * + * @param effect Imperative function that can return a cleanup function + * @param inputs If present, effect will only activate if the values in the list change (using ===). + */ +export function useEffect(effect: EffectCallback, inputs?: Inputs): void; + +type CreateHandle = () => object; + +/** + * @param ref The ref that will be mutated + * @param create The function that will be executed to get the value that will be attached to + * ref.current + * @param inputs If present, effect will only activate if the values in the list change (using ===). + */ +export function useImperativeHandle( + ref: Ref, + create: () => R, + inputs?: Inputs +): void; + +/** + * Accepts a function that contains imperative, possibly effectful code. + * Use this to read layout from the DOM and synchronously re-render. + * Updates scheduled inside `useLayoutEffect` will be flushed synchronously, after all DOM mutations but before the browser has a chance to paint. + * Prefer the standard `useEffect` hook when possible to avoid blocking visual updates. + * + * @param effect Imperative function that can return a cleanup function + * @param inputs If present, effect will only activate if the values in the list change (using ===). + */ +export function useLayoutEffect(effect: EffectCallback, inputs?: Inputs): void; + +/** + * Returns a memoized version of the callback that only changes if one of the `inputs` + * has changed (using ===). + */ +export function useCallback(callback: T, inputs: Inputs): T; + +/** + * Pass a factory function and an array of inputs. + * useMemo will only recompute the memoized value when one of the inputs has changed. + * This optimization helps to avoid expensive calculations on every render. + * If no array is provided, a new value will be computed whenever a new function instance is passed as the first argument. + */ +// for `inputs`, allow undefined, but don't make it optional as that is very likely a mistake +export function useMemo(factory: () => T, inputs: Inputs | undefined): T; + +/** + * Returns the current context value, as given by the nearest context provider for the given context. + * When the provider updates, this Hook will trigger a rerender with the latest context value. + * + * @param context The context you want to use + */ +export function useContext(context: PreactContext): T; + +/** + * Customize the displayed value in the devtools panel. + * + * @param value Custom hook name or object that is passed to formatter + * @param formatter Formatter to modify value before sending it to the devtools + */ +export function useDebugValue(value: T, formatter?: (value: T) => any): void; + +export function useErrorBoundary( + callback?: (error: any, errorInfo: ErrorInfo) => Promise | void +): [any, () => void]; + +export function useId(): string; diff --git a/packages/base/src/thirdparty/preact/hooks.module.js b/packages/base/src/thirdparty/preact/hooks.module.js new file mode 100644 index 000000000000..e04c056dc08c --- /dev/null +++ b/packages/base/src/thirdparty/preact/hooks.module.js @@ -0,0 +1,2 @@ +import{options as n}from"./preact.module.js";var t,r,u,i,o=0,f=[],c=n,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function d(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function h(n){return o=1,p(D,n)}function p(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return!!n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c&&c.call(this,n,t,r)||i};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function y(n,u){var i=d(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__H.__h.push(i))}function _(n,u){var i=d(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__h.push(i))}function A(n){return o=5,T(function(){return{current:n}},[])}function F(n,t,r){o=6,_(function(){return"function"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function T(n,r){var u=d(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function q(n,t){return o=8,T(function(){return n},t)}function x(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function P(n,t){c.useDebugValue&&c.useDebugValue(t?t(n):n)}function b(n){var u=d(t++,10),i=h();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=d(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__="P"+i[0]+"-"+i[1]++}return n.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[]}catch(t){n.__H.__h=[],c.__e(t,n.__v)}}c.__b=function(n){r=null,e&&e(n)},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t)},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.i=n.__N=void 0})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.i=void 0})),u=r=null},c.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],c.__e(r,n.__v)}}),l&&l(n,t)},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&c.__e(t,r.__v))};var k="function"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;"function"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return"function"==typeof t?t(n):t}export{q as useCallback,x as useContext,P as useDebugValue,y as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,p as useReducer,A as useRef,h as useState}; +//# sourceMappingURL=hooks.module.js.map diff --git a/packages/base/vite.preload.js b/packages/base/vite.preload.js new file mode 100644 index 000000000000..0afaf1992561 --- /dev/null +++ b/packages/base/vite.preload.js @@ -0,0 +1,13 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + emptyOutDir: false, + lib: { + entry: ["dist/index.js"], + formats: ["es"], + fileName: (format, entryName) => `bundle-base.js`, + }, + }, +}); diff --git a/packages/main/package.json b/packages/main/package.json index 823bcd49cf42..aff6d829276c 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -38,6 +38,7 @@ "prepublishOnly": "tsc -b" }, "exports": { + ".": "./dist/index.js", "./src/*": "./src/*", "./dist/*": "./dist/*", "./package.json": "./package.json", diff --git a/packages/main/src/BusyIndicator.ts b/packages/main/src/BusyIndicator.ts index 736e3e925d77..a1891ff81f9e 100644 --- a/packages/main/src/BusyIndicator.ts +++ b/packages/main/src/BusyIndicator.ts @@ -1,15 +1,5 @@ -import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import property from "@ui5/webcomponents-base/dist/decorators/property.js"; -import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import { isTabNext } from "@ui5/webcomponents-base/dist/Keys.js"; -import type { Timeout } from "@ui5/webcomponents-base/dist/types.js"; -import { - isDesktop, -} from "@ui5/webcomponents-base/dist/Device.js"; -import willShowContent from "@ui5/webcomponents-base/dist/util/willShowContent.js"; +import UI5Element, { customElement, property, i18n, jsxRenderer, Device, willShowContent, Keys } from "@ui5/webcomponents-base"; +import type { I18nBundle, Timeout } from "@ui5/webcomponents-base"; import type BusyIndicatorSize from "./types/BusyIndicatorSize.js"; import BusyIndicatorTextPlacement from "./types/BusyIndicatorTextPlacement.js"; @@ -21,6 +11,9 @@ import { BUSY_INDICATOR_TITLE } from "./generated/i18n/i18n-defaults.js"; // Styles import busyIndicatorCss from "./generated/themes/BusyIndicator.css.js"; +const { isDesktop } = Device; +const { isTabNext } = Keys; + /** * @class * diff --git a/packages/main/src/Button.ts b/packages/main/src/Button.ts index 32a3e0b32cc2..2b0b30ef789c 100644 --- a/packages/main/src/Button.ts +++ b/packages/main/src/Button.ts @@ -1,49 +1,24 @@ -import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import property from "@ui5/webcomponents-base/dist/decorators/property.js"; -import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; -import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; -import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import { - isSpace, - isEnter, - isEscape, - isShift, -} from "@ui5/webcomponents-base/dist/Keys.js"; -import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; -import type { AccessibilityAttributes, AriaRole } from "@ui5/webcomponents-base"; -import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; -import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import type { I18nText } from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import { getIconAccessibleName } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js"; - -import { - isDesktop, - isSafari, -} from "@ui5/webcomponents-base/dist/Device.js"; -import willShowContent from "@ui5/webcomponents-base/dist/util/willShowContent.js"; -import { submitForm, resetForm } from "@ui5/webcomponents-base/dist/features/InputElementsFormSupport.js"; -import { getEnableDefaultTooltips } from "@ui5/webcomponents-base/dist/config/Tooltips.js"; -import toLowercaseEnumValue from "@ui5/webcomponents-base/dist/util/toLowercaseEnumValue.js"; -import ButtonDesign from "./types/ButtonDesign.js"; -import ButtonType from "./types/ButtonType.js"; -import ButtonBadgeDesign from "./types/ButtonBadgeDesign.js"; +import UI5Element, { customElement, property, eventStrict as event, slot, jsxRenderer, i18n, AccessibilityTextsHelper, Keys, getIconAccessibleName, willShowContent, Device, Tooltips, toLowercaseEnumValue, InputElementsFormSupport } from "@ui5/webcomponents-base"; + +import type { AccessibilityAttributes, AriaRole, ITabbable, I18nBundle, I18nText } from "@ui5/webcomponents-base"; + +import type ButtonType from "./types/ButtonType.js"; +import type ButtonDesign from "./types/ButtonDesign.js"; import type ButtonAccessibleRole from "./types/ButtonAccessibleRole.js"; import type ButtonBadge from "./ButtonBadge.js"; import ButtonTemplate from "./ButtonTemplate.js"; -import { - BUTTON_ARIA_TYPE_ACCEPT, - BUTTON_ARIA_TYPE_REJECT, - BUTTON_ARIA_TYPE_EMPHASIZED, - BUTTON_ARIA_TYPE_ATTENTION, - BUTTON_BADGE_ONE_ITEM, - BUTTON_BADGE_MANY_ITEMS, -} from "./generated/i18n/i18n-defaults.js"; + +import { BUTTON_ARIA_TYPE_ACCEPT, BUTTON_ARIA_TYPE_REJECT, BUTTON_ARIA_TYPE_EMPHASIZED, BUTTON_ARIA_TYPE_ATTENTION, BUTTON_BADGE_ONE_ITEM, BUTTON_BADGE_MANY_ITEMS } from "./generated/i18n/i18n-defaults.js"; // Styles import buttonCss from "./generated/themes/Button.css.js"; +const { getEffectiveAriaLabelText } = AccessibilityTextsHelper; +const { isSpace, isEnter, isEscape, isShift } = Keys; +const { isDesktop, isSafari } = Device; +const { getEnableDefaultTooltips } = Tooltips; +const { submitForm, resetForm } = InputElementsFormSupport; + /** * Interface for components that may be used as a button inside numerous higher-order components * @public @@ -458,7 +433,7 @@ class Button extends UI5Element implements IButton { } _setBadgeOverlayStyle() { - const needsOverflowVisible = this.badge.length && (this.badge[0].design === ButtonBadgeDesign.AttentionDot || this.badge[0].design === ButtonBadgeDesign.OverlayText); + const needsOverflowVisible = this.badge.length && (this.badge[0].design === "AttentionDot" || this.badge[0].design === "OverlayText"); if (needsOverflowVisible) { this._internals.states.add("has-overlay-badge"); @@ -579,7 +554,7 @@ class Button extends UI5Element implements IButton { } get hasButtonType() { - return this.design !== ButtonDesign.Default && this.design !== ButtonDesign.Transparent; + return this.design !== "Default" && this.design !== "Transparent"; } get isIconOnly() { @@ -670,15 +645,15 @@ class Button extends UI5Element implements IButton { } get _isSubmit() { - return this.type === ButtonType.Submit || this.submits; + return this.type === "Submit" || this.submits; } get _isReset() { - return this.type === ButtonType.Reset; + return this.type === "Reset"; } get shouldRenderBadge() { - return !!this.badge.length && (!!this.badge[0].text.length || this.badge[0].design === ButtonBadgeDesign.AttentionDot); + return !!this.badge.length && (!!this.badge[0].text.length || this.badge[0].design === "AttentionDot"); } } diff --git a/packages/main/src/ButtonTemplate.tsx b/packages/main/src/ButtonTemplate.tsx index dc6d1afa8c29..31daa2133dfb 100644 --- a/packages/main/src/ButtonTemplate.tsx +++ b/packages/main/src/ButtonTemplate.tsx @@ -1,7 +1,24 @@ import type Button from "./Button.js"; -import Icon from "./Icon.js"; -import BusyIndicator from "./BusyIndicator.js"; -import BusyIndicatorSize from "./types/BusyIndicatorSize.js"; +import { useState } from "@ui5/webcomponents-base/dist/thirdparty/preact/hooks.module.js"; +import { jsx } from "@ui5/webcomponents-base/dist/jsx-runtime.js"; +import type UI5Element from "@ui5/webcomponents-base"; + +function lazy(tag: string, fn: () => Promise<{ default: T }>): T { + return function Component(props: { [key: string]: unknown }) { + const [Comp, setComp] = useState(null); + Promise.resolve().then(() => { + console.log("immediate promise"); + }); + const p = fn(); + p.then(module => { + setComp(() => module.default); + }); + return Comp ? : jsx(tag, props, ""); + } as unknown as T; +} + +const LazyIcon = lazy("ui5-icon", () => import("./Icon.js")); +const LazyBusyIndicator = lazy("ui5-busy-indicator", () => import("./BusyIndicator.js")); export default function ButtonTemplate(this: Button, injectedProps?: { ariaPressed?: boolean, @@ -46,7 +63,7 @@ export default function ButtonTemplate(this: Button, injectedProps?: { role={this.effectiveAccRole} > { this.icon && - {this.endIcon && - {this.loading && - ; type SplitButtonArrowButtonAccAtributes = Pick; type SplitButtonAccessibilityAttributes = {root?: SplitButtonRootAccAttributes, arrowButton?: SplitButtonArrowButtonAccAtributes} diff --git a/packages/main/src/Text.ts b/packages/main/src/Text.ts index 1ddb3fc13cb3..20ef31bd8184 100644 --- a/packages/main/src/Text.ts +++ b/packages/main/src/Text.ts @@ -1,24 +1,16 @@ -import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; -import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; -import property from "@ui5/webcomponents-base/dist/decorators/property.js"; -import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; -import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import { getScopedVarName } from "@ui5/webcomponents-base/dist/CustomElementsScope.js"; -import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; -import willShowContent from "@ui5/webcomponents-base/dist/util/willShowContent.js"; +import UI5Element, { customElement, property, slot, jsxRenderer, i18n, willShowContent, CustomElementsScopeUtils } from "@ui5/webcomponents-base"; +import type { I18nBundle } from "@ui5/webcomponents-base"; import TextEmptyIndicatorMode from "./types/TextEmptyIndicatorMode.js"; // Template import TextTemplate2 from "./TextTemplate.js"; -import { - EMPTY_INDICATOR_SYMBOL, - EMPTY_INDICATOR_ACCESSIBLE_TEXT, -} from "./generated/i18n/i18n-defaults.js"; +import { EMPTY_INDICATOR_SYMBOL, EMPTY_INDICATOR_ACCESSIBLE_TEXT } from "./generated/i18n/i18n-defaults.js"; // Styles import styles from "./generated/themes/Text.css.js"; +const { getScopedVarName } = CustomElementsScopeUtils; + /** * @class * diff --git a/packages/main/src/bundle.common.bootstrap.ts b/packages/main/src/bundle.common.bootstrap.ts index bfe51ae57a00..9a1d45454c62 100644 --- a/packages/main/src/bundle.common.bootstrap.ts +++ b/packages/main/src/bundle.common.bootstrap.ts @@ -5,7 +5,7 @@ import { setRuntimeAlias } from "@ui5/webcomponents-base/dist/Runtimes.js"; import "@ui5/webcomponents-base/dist/features/OpenUI5Support.js"; // Assets -import "./Assets.js"; +// import "./Assets.js"; // Icons import "@ui5/webcomponents-icons/dist/Assets.js"; diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts new file mode 100644 index 000000000000..0fe16420067a --- /dev/null +++ b/packages/main/src/index.ts @@ -0,0 +1,10 @@ +export { default as Button } from "./Button.js"; +export { default as Icon } from "./Icon.js"; +export { default as Label } from "./Label.js"; +export { default as BusyIndicator } from "./BusyIndicator.js"; + +export { default as Text } from "./Text.js"; + +export { default as SplitButton } from "./SplitButton.js"; + +export type { default as ButtonDesign } from "./types/ButtonDesign.js"; diff --git a/packages/main/vite.preload.js b/packages/main/vite.preload.js new file mode 100644 index 000000000000..37944e30f4cb --- /dev/null +++ b/packages/main/vite.preload.js @@ -0,0 +1,19 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + emptyOutDir: false, + lib: { + entry: ["dist/index.js"], + formats: ["es"], + fileName: (format, entryName) => `bundle-main.js`, + }, + rollupOptions: { + external: [ + "@ui5/webcomponents-base", + "@ui5/webcomponents-base/dist/thirdparty/preact/hooks.module.js", + ], + }, + }, +}); diff --git a/packages/main/vite.preload2.js b/packages/main/vite.preload2.js new file mode 100644 index 000000000000..e09f9ae58a53 --- /dev/null +++ b/packages/main/vite.preload2.js @@ -0,0 +1,20 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + emptyOutDir: false, + lib: { + entry: ["dist/index.js"], + formats: ["es"], + fileName: (format, entryName) => `bundle-main.js`, + }, + rollupOptions: { + external: [ + "@ui5/webcomponents-base", + /@ui5\/webcomponents-theming\//, + "@ui5/webcomponents-localization", + ], + }, + }, +}); diff --git a/packages/main/vite.sfc.js b/packages/main/vite.sfc.js new file mode 100644 index 000000000000..395ea56f1ff3 --- /dev/null +++ b/packages/main/vite.sfc.js @@ -0,0 +1,18 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + emptyOutDir: false, + lib: { + entry: ["dist/Button.js"], + formats: ["es"], + fileName: (format, entryName) => `Button.sfc.js`, + }, + rollupOptions: { + external: (id, parentId, isResolved) => { + return !(id.includes("ButtonTemplate.js") || id.includes("Button.css.js")) && !id.endsWith("Button.js"); + }, + }, + }, +}); diff --git a/packages/tools/components-package/eslint.js b/packages/tools/components-package/eslint.js index ce352328167f..5515a82d106d 100644 --- a/packages/tools/components-package/eslint.js +++ b/packages/tools/components-package/eslint.js @@ -103,6 +103,15 @@ module.exports = { // "requireReturn": false // }], "valid-typeof": 2, + "no-restricted-imports": ["error", { + "patterns": [ + "@ui5/webcomponents-base/dist/*", + "@ui5/webcomponents-theming/dist/*", + "@ui5/webcomponents-localization/dist/*", + "@ui5/webcomponents/dist/*", + ], + }], + "object-curly-newline": ["error", { "ImportDeclaration": "never", "ExportDeclaration": "never" }], "accessor-pairs": 2, "block-scoped-var": 1, diff --git a/packages/tools/lib/create-icons/index.js b/packages/tools/lib/create-icons/index.js index e57e043611ac..5853c28422ec 100644 --- a/packages/tools/lib/create-icons/index.js +++ b/packages/tools/lib/create-icons/index.js @@ -1,7 +1,7 @@ const fs = require("fs").promises; const path = require("path"); -const iconTemplate = (name, pathData, ltr, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js"; +const iconTemplate = (name, pathData, ltr, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base"; const name = "${name}"; const pathData = "${pathData}"; @@ -16,7 +16,7 @@ export default "${collection}/${name}"; export { pathData, ltr, accData };`; -const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName, versioned) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js"; +const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName, versioned) => `import { registerIcon } from "@ui5/webcomponents-base"; import { ${accData.key} } from "${versioned ? "../" : "./"}generated/i18n/i18n-defaults.js"; const name = "${name}"; @@ -33,7 +33,7 @@ export { pathData, ltr, accData };`; -const collectionTemplate = (name, versions, fullName) => `import { isLegacyThemeFamilyAsync } from "@ui5/webcomponents-base/dist/config/Theme.js"; +const collectionTemplate = (name, versions, fullName) => `import { isLegacyThemeFamilyAsync } from "@ui5/webcomponents-base"; import { pathData as pathData${versions[0]}, ltr, accData } from "./${versions[0]}/${name}.js"; import { pathData as pathData${versions[1]} } from "./${versions[1]}/${name}.js"; diff --git a/packages/tools/lib/css-processors/shared.mjs b/packages/tools/lib/css-processors/shared.mjs index 0cda3c30d4c1..54b75d6f26e4 100644 --- a/packages/tools/lib/css-processors/shared.mjs +++ b/packages/tools/lib/css-processors/shared.mjs @@ -27,7 +27,7 @@ const writeFileIfChanged = async (fileName, content) => { const DEFAULT_THEME = assets.themes.default; const getDefaultThemeCode = packageName => { - return `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js"; + return `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base"; import defaultThemeBase from "@ui5/webcomponents-theming/dist/generated/themes/${DEFAULT_THEME}/parameters-bundle.css.js"; import defaultTheme from "./${DEFAULT_THEME}/parameters-bundle.css.js"; diff --git a/packages/tools/lib/generate-json-imports/themes.js b/packages/tools/lib/generate-json-imports/themes.js index b61d28a7226a..c5f9537c2043 100644 --- a/packages/tools/lib/generate-json-imports/themes.js +++ b/packages/tools/lib/generate-json-imports/themes.js @@ -31,7 +31,7 @@ const generate = async (argv) => { // dynamic imports file content const contentDynamic = function (lines) { return `// @ts-nocheck -import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js"; +import { registerThemePropertiesLoader } from "@ui5/webcomponents-base"; const loadThemeProperties = async (themeName) => { switch (themeName) { diff --git a/test-bundles.html b/test-bundles.html new file mode 100644 index 000000000000..09d713aa54c4 --- /dev/null +++ b/test-bundles.html @@ -0,0 +1,185 @@ + + + + + + Document + + + + + + + + + + + + Button +
+ Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + + Button + Button + Button + Button + Button + Button + Button + Button + Button + Button + +
+ + + + + + + + \ No newline at end of file diff --git a/test-bundles2.html b/test-bundles2.html new file mode 100644 index 000000000000..ed7101cd7409 --- /dev/null +++ b/test-bundles2.html @@ -0,0 +1,66 @@ + + + + + + Document + + + + + + + + + + + Button + + + + + + + \ No newline at end of file