Skip to content

Commit

Permalink
feat: Add head component
Browse files Browse the repository at this point in the history
  • Loading branch information
istarkov committed Jan 16, 2025
1 parent a98f149 commit 9014ade
Show file tree
Hide file tree
Showing 12 changed files with 1,397 additions and 1 deletion.
658 changes: 658 additions & 0 deletions packages/sdk-components-react/src/__generated__/head-link.props.ts

Large diffs are not rendered by default.

562 changes: 562 additions & 0 deletions packages/sdk-components-react/src/__generated__/head.props.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions packages/sdk-components-react/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export { XmlTime } from "./xml-time";
export { Time } from "./time";
export { Select } from "./select";
export { Option } from "./option";
export { Head } from "./head";
export { HeadLink } from "./head-link";
49 changes: 49 additions & 0 deletions packages/sdk-components-react/src/head-link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ReactSdkContext } from "@webstudio-is/react-sdk/runtime";
import {
forwardRef,
type ElementRef,
type ComponentProps,
useContext,
} from "react";
import { XmlNode } from "./xml-node";

export const defaultTag = "link";

type LinkRel =
| "alternate"
| "author"
| "canonical"
| "dns-prefetch"
| "help"
| "icon"
| "license"
| "manifest"
| "modulepreload"
| "next"
| "nofollow"
| "noopener"
| "noreferrer"
| "opener"
| "pingback"
| "preconnect"
| "prefetch"
| "preload"
| "prev"
| "search"
| "stylesheet"
| "tag";

export const HeadLink = forwardRef<
ElementRef<"div">,
{ rel: LinkRel } & ComponentProps<typeof defaultTag>
>(({ ...props }, ref) => {
const { renderer } = useContext(ReactSdkContext);

if (renderer === undefined) {
return <link {...props} />;
}

return <XmlNode tag={defaultTag} {...props} ref={ref} />;
});

HeadLink.displayName = "HeadLink";
22 changes: 22 additions & 0 deletions packages/sdk-components-react/src/head-link.ws.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Link2Icon } from "@webstudio-is/icons/svg";
import {
type WsComponentMeta,
type WsComponentPropsMeta,
} from "@webstudio-is/sdk";

import { props } from "./__generated__/head-link.props";

export const meta: WsComponentMeta = {
category: "hidden",
icon: Link2Icon,
type: "container",
constraints: {
relation: "parent",
component: { $eq: "Head" },
},
};

export const propsMeta: WsComponentPropsMeta = {
props,
initialProps: ["rel", "href", "type", "hreflang"],
};
12 changes: 12 additions & 0 deletions packages/sdk-components-react/src/head.template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type TemplateMeta, $ } from "@webstudio-is/template";

export const meta: TemplateMeta = {
category: "general",
description: "Head",
order: 4,
template: (
<$.Head>
<$.HeadLink rel="help" href="/help"></$.HeadLink>
</$.Head>
),
};
64 changes: 64 additions & 0 deletions packages/sdk-components-react/src/head.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
getClosestInstance,
ReactSdkContext,
type Hook,
} from "@webstudio-is/react-sdk/runtime";
import {
forwardRef,
type ElementRef,
type ComponentProps,
useContext,
} from "react";
import { XmlNode } from "./xml-node";

export const defaultTag = "head";

export const Head = forwardRef<
ElementRef<"div">,
{ "data-ws-expand": boolean } & ComponentProps<typeof defaultTag>
>(({ ...props }, ref) => {
const { renderer } = useContext(ReactSdkContext);

if (props["data-ws-expand"] !== true) {
return null;
}

if (renderer === undefined) {
return props.children;
}

return <XmlNode tag={defaultTag} {...props} ref={ref} />;
});

Head.displayName = "Head";

export const hooksHead: Hook = {
onNavigatorUnselect: (context, event) => {
for (const instance of event.instancePath) {
if (instance.component === `Head`) {
const popover = getClosestInstance(
event.instancePath,
instance,
`Head`
);
if (popover) {
context.setMemoryProp(popover, "data-ws-expand", undefined);
}
}
}
},
onNavigatorSelect: (context, event) => {
for (const instance of event.instancePath) {
if (instance.component === `Head`) {
const popover = getClosestInstance(
event.instancePath,
instance,
`Head`
);
if (popover) {
context.setMemoryProp(popover, "data-ws-expand", true);
}
}
}
},
};
21 changes: 21 additions & 0 deletions packages/sdk-components-react/src/head.ws.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { HeaderIcon } from "@webstudio-is/icons/svg";
import {
type WsComponentMeta,
type WsComponentPropsMeta,
} from "@webstudio-is/sdk";

import { props } from "./__generated__/head.props";

export const meta: WsComponentMeta = {
icon: HeaderIcon,
type: "container",
constraints: {
relation: "ancestor",
component: { $nin: ["Head"] },
},
};

export const propsMeta: WsComponentPropsMeta = {
props,
initialProps: [],
};
3 changes: 2 additions & 1 deletion packages/sdk-components-react/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Hook } from "@webstudio-is/react-sdk";
import { hooksSelect } from "./select";
import { hooksHead } from "./head";

export const hooks: Hook[] = [hooksSelect];
export const hooks: Hook[] = [hooksSelect, hooksHead];
2 changes: 2 additions & 0 deletions packages/sdk-components-react/src/metas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export { meta as XmlTime } from "./xml-time.ws";
export { meta as Time } from "./time.ws";
export { meta as Select } from "./select.ws";
export { meta as Option } from "./option.ws";
export { meta as Head } from "./head.ws";
export { meta as HeadLink } from "./head-link.ws";
2 changes: 2 additions & 0 deletions packages/sdk-components-react/src/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ export { propsMeta as XmlTime } from "./xml-time.ws";
export { propsMeta as Time } from "./time.ws";
export { propsMeta as Select } from "./select.ws";
export { propsMeta as Option } from "./option.ws";
export { propsMeta as Head } from "./head.ws";
export { propsMeta as HeadLink } from "./head-link.ws";
1 change: 1 addition & 0 deletions packages/sdk-components-react/src/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { meta as Checkbox } from "./checkbox.template";
export { meta as Vimeo } from "./vimeo.template";
export { meta as YouTube } from "./youtube.template";
export { meta as Select } from "./select.template";
export { meta as Head } from "./head.template";

0 comments on commit 9014ade

Please sign in to comment.