diff --git a/apps/builder/app/builder/features/components/components.tsx b/apps/builder/app/builder/features/components/components.tsx index b80ee794654d..b10751aa8e48 100644 --- a/apps/builder/app/builder/features/components/components.tsx +++ b/apps/builder/app/builder/features/components/components.tsx @@ -66,6 +66,12 @@ const $metas = computed( continue; } + if ( + isFeatureEnabled("animation") === false && + name.endsWith(":AnimateText") + ) { + continue; + } // only set available components from component meta availableComponents.add(name); if ( diff --git a/packages/sdk-components-animation/package.json b/packages/sdk-components-animation/package.json index b7b01681de27..0413b93d73c3 100644 --- a/packages/sdk-components-animation/package.json +++ b/packages/sdk-components-animation/package.json @@ -59,8 +59,10 @@ "@webstudio-is/react-sdk": "workspace:*", "@webstudio-is/sdk": "workspace:*", "change-case": "^5.4.4", + "nanostores": "^0.11.3", "react-error-boundary": "^5.0.0", - "scroll-timeline-polyfill": "^1.1.0" + "scroll-timeline-polyfill": "^1.1.0", + "shallow-equal": "^3.1.0" }, "devDependencies": { "@types/react": "^18.2.70", diff --git a/packages/sdk-components-animation/private-src b/packages/sdk-components-animation/private-src index c1053aa05f2d..45acad5a6caf 160000 --- a/packages/sdk-components-animation/private-src +++ b/packages/sdk-components-animation/private-src @@ -1 +1 @@ -Subproject commit c1053aa05f2d5986e3c75a3061281dc8e282ce6f +Subproject commit 45acad5a6caf111e92f62d93ac0cd07310a82e6d diff --git a/packages/sdk-components-animation/src/__generated__/animate-children.props.ts b/packages/sdk-components-animation/src/__generated__/animate-children.props.ts new file mode 100644 index 000000000000..fdadfcf1d21d --- /dev/null +++ b/packages/sdk-components-animation/src/__generated__/animate-children.props.ts @@ -0,0 +1,10 @@ +import type { PropMeta } from "@webstudio-is/sdk"; + +export const props: Record = { + debug: { + required: false, + control: "boolean", + type: "boolean", + defaultValue: false, + }, +}; diff --git a/packages/sdk-components-animation/src/__generated__/animate-text.props.ts b/packages/sdk-components-animation/src/__generated__/animate-text.props.ts new file mode 100644 index 000000000000..d6479f71feb3 --- /dev/null +++ b/packages/sdk-components-animation/src/__generated__/animate-text.props.ts @@ -0,0 +1,22 @@ +import type { PropMeta } from "@webstudio-is/sdk"; + +export const props: Record = { + charWindow: { required: true, control: "number", type: "number" }, + easing: { + required: true, + control: "select", + type: "string", + options: [ + "linear", + "easeIn", + "easeInCubic", + "easeInQuart", + "easeOut", + "easeOutCubic", + "easeOutQuart", + "ease", + "easeInOutCubic", + "easeInOutQuart", + ], + }, +}; diff --git a/packages/sdk-components-animation/src/scroll.ws.ts b/packages/sdk-components-animation/src/animate-children.ws.ts similarity index 100% rename from packages/sdk-components-animation/src/scroll.ws.ts rename to packages/sdk-components-animation/src/animate-children.ws.ts diff --git a/packages/sdk-components-animation/src/animate-text.tsx b/packages/sdk-components-animation/src/animate-text.tsx new file mode 100644 index 000000000000..6721483b5f3e --- /dev/null +++ b/packages/sdk-components-animation/src/animate-text.tsx @@ -0,0 +1,29 @@ +import { forwardRef, type ElementRef } from "react"; + +const easings = { + linear: true, + easeIn: true, + easeInCubic: true, + easeInQuart: true, + easeOut: true, + easeOutCubic: true, + easeOutQuart: true, + ease: true, + easeInOutCubic: true, + easeInOutQuart: true, +}; + +type AnimateChildrenProps = { + charWindow: number; + easing: keyof typeof easings; + children: React.ReactNode; +}; + +export const AnimateText = forwardRef, AnimateChildrenProps>( + ({ charWindow: _, easing: __, ...props }, ref) => { + return
; + } +); + +const displayName = "AnimateText"; +AnimateText.displayName = displayName; diff --git a/packages/sdk-components-animation/src/animate-text.ws.ts b/packages/sdk-components-animation/src/animate-text.ws.ts new file mode 100644 index 000000000000..833eb573bd2c --- /dev/null +++ b/packages/sdk-components-animation/src/animate-text.ws.ts @@ -0,0 +1,17 @@ +import { TextIcon } from "@webstudio-is/icons/svg"; +import type { WsComponentMeta, WsComponentPropsMeta } from "@webstudio-is/sdk"; +import { props } from "./__generated__/animate-text.props"; + +export const meta: WsComponentMeta = { + category: "general", + type: "container", + description: "Animate Text", + icon: TextIcon, + order: 6, + label: "Animate Text", +}; + +export const propsMeta: WsComponentPropsMeta = { + props, + initialProps: ["charWindow", "easing"], +}; diff --git a/packages/sdk-components-animation/src/components.ts b/packages/sdk-components-animation/src/components.ts index ab47b1c28903..ee855f0ad140 100644 --- a/packages/sdk-components-animation/src/components.ts +++ b/packages/sdk-components-animation/src/components.ts @@ -1 +1,2 @@ export { AnimateChildren } from "./animate-children"; +export { AnimateText } from "./animate-text"; diff --git a/packages/sdk-components-animation/src/metas.ts b/packages/sdk-components-animation/src/metas.ts index 3f70a4394ccb..1f24252cfce7 100644 --- a/packages/sdk-components-animation/src/metas.ts +++ b/packages/sdk-components-animation/src/metas.ts @@ -1 +1,2 @@ -export { meta as AnimateChildren } from "./scroll.ws"; +export { meta as AnimateChildren } from "./animate-children.ws"; +export { meta as AnimateText } from "./animate-text.ws"; diff --git a/packages/sdk-components-animation/src/props.ts b/packages/sdk-components-animation/src/props.ts index 677fd7a91a70..9f32425fccc2 100644 --- a/packages/sdk-components-animation/src/props.ts +++ b/packages/sdk-components-animation/src/props.ts @@ -1 +1,2 @@ -export { propsMeta as AnimateChildren } from "./scroll.ws"; +export { propsMeta as AnimateChildren } from "./animate-children.ws"; +export { propsMeta as AnimateText } from "./animate-text.ws"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 293a3b1e7337..c3574c2c754b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1865,12 +1865,18 @@ importers: change-case: specifier: ^5.4.4 version: 5.4.4 + nanostores: + specifier: ^0.11.3 + version: 0.11.3 react-error-boundary: specifier: ^5.0.0 version: 5.0.0(react@18.3.0-canary-14898b6a9-20240318) scroll-timeline-polyfill: specifier: ^1.1.0 version: 1.1.0(patch_hash=i4g3vdpump4efgy2hri5l5rsfm) + shallow-equal: + specifier: ^3.1.0 + version: 3.1.0 devDependencies: '@types/react': specifier: ^18.2.70