From 2f28f46aefbffd7ea1c826dc0a7cd64dec7c3e9b Mon Sep 17 00:00:00 2001
From: Joo Chanhwi <56245920+te6-in@users.noreply.github.com>
Date: Fri, 24 Jan 2025 21:42:29 +0900
Subject: [PATCH 1/6] feat(figma-extractor): sort imports
---
tools/figma-extractor/CHANGELOG.md | 6 ++++++
tools/figma-extractor/package.json | 2 +-
tools/figma-extractor/src/services/component-sets.ts | 3 ++-
tools/figma-extractor/src/services/components.ts | 3 ++-
tools/figma-extractor/src/services/styles.ts | 5 ++++-
tools/figma-extractor/src/services/variables.ts | 3 ++-
6 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/tools/figma-extractor/CHANGELOG.md b/tools/figma-extractor/CHANGELOG.md
index 5ce1d08b2..578b9695f 100644
--- a/tools/figma-extractor/CHANGELOG.md
+++ b/tools/figma-extractor/CHANGELOG.md
@@ -1,5 +1,11 @@
# @seed-design/figma-extractor
+## 0.0.3
+
+### Patch Changes
+
+- Sort exports
+
## 0.0.2
### Patch Changes
diff --git a/tools/figma-extractor/package.json b/tools/figma-extractor/package.json
index b27481835..d201ac84e 100644
--- a/tools/figma-extractor/package.json
+++ b/tools/figma-extractor/package.json
@@ -1,6 +1,6 @@
{
"name": "@seed-design/figma-extractor",
- "version": "0.0.2",
+ "version": "0.0.3",
"repository": {
"type": "git",
"url": "git+https://github.com/daangn/seed-design.git",
diff --git a/tools/figma-extractor/src/services/component-sets.ts b/tools/figma-extractor/src/services/component-sets.ts
index d0eaf488d..1a8d2cecc 100644
--- a/tools/figma-extractor/src/services/component-sets.ts
+++ b/tools/figma-extractor/src/services/component-sets.ts
@@ -18,7 +18,8 @@ export async function generateComponentSetMetadata({
const componentSetsMetadata = (await getComponentSetMetadataItemsInFile({ fileKey }))
.filter(filter)
- .map(transform);
+ .map(transform)
+ .sort((a, b) => a.name.localeCompare(b.name));
if (componentSetsMetadata.length === 0) {
console.error("추출할 component set 메타데이터가 없습니다.");
diff --git a/tools/figma-extractor/src/services/components.ts b/tools/figma-extractor/src/services/components.ts
index 23d242f8f..3b1ca3ac7 100644
--- a/tools/figma-extractor/src/services/components.ts
+++ b/tools/figma-extractor/src/services/components.ts
@@ -18,7 +18,8 @@ export async function generateComponentMetadata({
const componentsMetadata = (await getComponentMetadataItemsInFile({ fileKey }))
.filter(filter)
- .map(transform);
+ .map(transform)
+ .sort((a, b) => a.name.localeCompare(b.name));
if (componentsMetadata.length === 0) {
console.error("추출할 component 메타데이터가 없습니다.");
diff --git a/tools/figma-extractor/src/services/styles.ts b/tools/figma-extractor/src/services/styles.ts
index dd7ef418b..fd427f004 100644
--- a/tools/figma-extractor/src/services/styles.ts
+++ b/tools/figma-extractor/src/services/styles.ts
@@ -20,7 +20,10 @@ export async function generateStyleMetadata({
}) {
console.log("style 메타데이터 생성 중");
- const stylesMetadata = (await getStylesMetadataInFile({ fileKey })).filter(filter).map(transform);
+ const stylesMetadata = (await getStylesMetadataInFile({ fileKey }))
+ .filter(filter)
+ .map(transform)
+ .sort((a, b) => a.name.localeCompare(b.name));
if (stylesMetadata.length === 0) {
console.error("추출할 style 메타데이터가 없습니다.");
diff --git a/tools/figma-extractor/src/services/variables.ts b/tools/figma-extractor/src/services/variables.ts
index 620651518..ef2278244 100644
--- a/tools/figma-extractor/src/services/variables.ts
+++ b/tools/figma-extractor/src/services/variables.ts
@@ -22,7 +22,8 @@ export async function generateVariableMetadata({
const variablesMetadata = (await getVariableMetadataItemsInFile({ fileKey }))
.filter(filter)
- .map(transform);
+ .map(transform)
+ .sort((a, b) => a.name.localeCompare(b.name));
if (variablesMetadata.length === 0) {
console.error("추출할 variable 메타데이터가 없습니다.");
From 480bc203c353b6439503990bfc9b0f77e1e270bb Mon Sep 17 00:00:00 2001
From: Joo Chanhwi <56245920+te6-in@users.noreply.github.com>
Date: Fri, 24 Jan 2025 22:10:41 +0900
Subject: [PATCH 2/6] feat: support codegen for ErrorState, MannerTempBadge & 2
sheets
---
.../docs/react/components/action-sheet.mdx | 11 +-
.../components/extended-action-sheet.mdx | 11 +-
tools/figma-codegen/package.json | 2 +-
.../src/codegen/component/index.ts | 217 +++++++++++++++++-
.../src/codegen/component/type.ts | 67 ++++++
.../data/component-sets/error-state.d.ts | 32 +++
.../data/component-sets/error-state.mjs | 32 +++
.../component-sets/extended-action-sheet.d.ts | 10 +-
.../component-sets/extended-action-sheet.mjs | 10 +-
.../codegen/data/component-sets/index.d.ts | 67 +++---
.../src/codegen/data/component-sets/index.mjs | 67 +++---
yarn.lock | 4 +-
12 files changed, 440 insertions(+), 90 deletions(-)
create mode 100644 tools/figma-codegen/src/codegen/data/component-sets/error-state.d.ts
create mode 100644 tools/figma-codegen/src/codegen/data/component-sets/error-state.mjs
diff --git a/docs/content/docs/react/components/action-sheet.mdx b/docs/content/docs/react/components/action-sheet.mdx
index c9b52180a..283d04544 100644
--- a/docs/content/docs/react/components/action-sheet.mdx
+++ b/docs/content/docs/react/components/action-sheet.mdx
@@ -11,14 +11,21 @@ description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core
## Props
-### ActionSheetRoot
+### `ActionSheetRoot`
-### ActionSheetItem
+### `ActionSheetContent`
+
+
+
+### `ActionSheetItem`
-### ExtendedActionSheetItem
+### `ExtendedActionSheetContent`
+
+
+
+### `ExtendedActionSheetItem`
= {
count: Number(props["Count#7185:21"].value),
}),
};
- return createElement("ChipButton", commonProps, children);
+ return createElement("ActionChip", commonProps, children);
+ },
+};
+
+const actionSheetHandler: ComponentHandler = {
+ key: metadata.actionSheet.key,
+ codegen: (node) => {
+ const { componentProperties: props } = node;
+
+ const contentProps = match(props.Header.value)
+ .with("None", () => ({
+ title: undefined,
+ description: undefined,
+ }))
+ .with("Title Only", () => ({
+ title: props["Title#15641:37"].value,
+ description: undefined,
+ }))
+ .with("Description Only", () => ({
+ title: undefined,
+ description: props["Description#15641:70"].value,
+ }))
+ .with("Title With Description", () => ({
+ title: props["Title#15641:37"].value,
+ description: props["Description#15641:70"].value,
+ }))
+ .exhaustive();
+
+ const items = node.findAll(
+ (child) =>
+ child.type === "INSTANCE" &&
+ ((child.mainComponent?.parent?.type === "COMPONENT_SET" &&
+ child.mainComponent?.parent.key === actionSheetItemHandler.key) ||
+ child.mainComponent?.key === actionSheetItemHandler.key),
+ ) as (InstanceNode & { componentProperties: ActionSheetItemProperties })[];
+
+ const contentChildren = items.map(actionSheetItemHandler.codegen);
+
+ console.log(contentProps, contentChildren);
+
+ const content = createElement(
+ "ActionSheetContent",
+ contentProps,
+ contentChildren,
+ contentProps.title
+ ? ""
+ : "title을 제공하지 않는 경우 aria-label이나 aria-labelledby 중 하나를 제공해야 합니다.",
+ );
+
+ const trigger = createElement(
+ "ActionSheetTrigger",
+ { asChild: true },
+ createElement("ActionButton", undefined, "열기", "ActionSheet을 여는 요소를 제공해주세요."),
+ );
+
+ return createElement("ActionSheet", undefined, [trigger, content]);
+ },
+};
+
+const actionSheetItemHandler: ComponentHandler = {
+ key: "c3cafd3a3fdcd45fecb6971019d88eaf39a2e381",
+ codegen: ({ componentProperties: props }) => {
+ const states = props.State.value.split("-");
+
+ const commonProps = {
+ label: props["Label#15420:4"].value,
+ tone: camelCase(props.Tone.value),
+ ...(states.includes("Disabled") && {
+ disabled: true,
+ }),
+ };
+
+ return createElement("ActionSheetItem", commonProps);
},
};
@@ -155,7 +234,10 @@ const avatarHandler: ComponentHandler = {
codegen: (node) => {
const placeholder = node.findOne(
(child) =>
- child.type === "INSTANCE" && child.mainComponent?.key === identityPlaceholderHandler.key,
+ child.type === "INSTANCE" &&
+ (child.mainComponent?.parent?.type === "COMPONENT_SET"
+ ? child.mainComponent.parent.key === identityPlaceholderHandler.key
+ : child.mainComponent?.key === identityPlaceholderHandler.key),
) as (InstanceNode & { componentProperties: IdentityPlaceholderProperties }) | null;
const { componentProperties: props } = node;
@@ -445,6 +527,117 @@ const controlChipHandler: ComponentHandler = {
},
};
+const errorStateHandler: ComponentHandler = {
+ key: metadata.errorState.key,
+ codegen: (node) => {
+ const props = node.componentProperties;
+
+ const actionButtonNode = node.findOne(
+ (child) =>
+ child.type === "INSTANCE" &&
+ ((child.mainComponent?.parent?.type === "COMPONENT_SET" &&
+ child.mainComponent?.parent.key === actionButtonHandler.key) ||
+ child.mainComponent?.key === actionButtonHandler.key),
+ ) as InstanceNode & { componentProperties: ActionButtonProperties };
+
+ const commonProps = {
+ variant: camelCase(props.Variant.value),
+ ...(props.Layout.value === "With Title" && {
+ title: props["Title#16237:0"].value,
+ }),
+ description: props["Description#16237:5"].value,
+ ...(actionButtonNode && {
+ primaryActionProps: {
+ children: actionButtonHandler.codegen(actionButtonNode).children[0],
+ },
+ secondaryActionProps: {
+ children: props["Secondary Action Label#17042:0"].value,
+ },
+ }),
+ };
+
+ return createElement("ErrorState", commonProps);
+ },
+};
+
+const extendedActionSheetHandler: ComponentHandler = {
+ key: metadata.extendedActionSheet.key,
+ codegen: (node) => {
+ const { componentProperties: props } = node;
+
+ const groups = node.findAll(
+ (child) =>
+ child.type === "INSTANCE" &&
+ ((child.mainComponent?.parent?.type === "COMPONENT_SET" &&
+ child.mainComponent?.parent.key === extendedActionSheetGroupHandler.key) ||
+ child.mainComponent?.key === extendedActionSheetGroupHandler.key),
+ ) as (InstanceNode & { componentProperties: ExtendedActionSheetGroupProperties })[];
+
+ const contentChildren = groups.map(extendedActionSheetGroupHandler.codegen);
+
+ const title = props["Show Title#17043:12"].value ? props["Title#14599:0"].value : undefined;
+
+ const content = createElement(
+ "ExtendedActionSheetContent",
+ { title },
+ contentChildren,
+ title
+ ? ""
+ : "title을 제공하지 않는 경우 aria-label이나 aria-labelledby 중 하나를 제공해야 합니다.",
+ );
+
+ const trigger = createElement(
+ "ExtendedActionSheetTrigger",
+ { asChild: true },
+ createElement(
+ "ActionButton",
+ undefined,
+ "열기",
+ "ExtendedActionSheet을 여는 요소를 제공해주세요.",
+ ),
+ );
+
+ return createElement("ExtendedActionSheet", undefined, [trigger, content]);
+ },
+};
+
+const extendedActionSheetGroupHandler: ComponentHandler = {
+ key: "2a504a1c6b7810d5e652862dcba2cb7048f9eb16",
+ codegen: (node) => {
+ const items = node.findAll(
+ (child) =>
+ child.type === "INSTANCE" &&
+ ((child.mainComponent?.parent?.type === "COMPONENT_SET" &&
+ child.mainComponent?.parent.key === extendedActionSheetItemHandler.key) ||
+ child.mainComponent?.key === extendedActionSheetItemHandler.key),
+ ) as (InstanceNode & { componentProperties: ExtendedActionSheetItemProperties })[];
+
+ const contentChildren = items.map(extendedActionSheetItemHandler.codegen);
+
+ return createElement("ExtendedActionSheetGroup", undefined, contentChildren);
+ },
+};
+
+const extendedActionSheetItemHandler: ComponentHandler = {
+ key: "057083e95466da59051119eec0b41d4ad5a07f8f",
+ codegen: ({ componentProperties: props }) => {
+ const states = props.State.value.split("-");
+
+ const commonProps = {
+ tone: camelCase(props.Tone.value),
+ label: props["Label#55905:8"].value,
+ ...(props["Show Prefix Icon#17043:5"].value && {
+ prefixIcon: createElement(createIconTagNameFromId(props["Prefix Icon#55948:0"].value)),
+ }),
+ ...(states.includes("Disabled") && {
+ disabled: true,
+ }),
+ };
+
+ return createElement("ExtendedActionSheetItem", commonProps);
+ },
+};
+
const extendedFabHandler: ComponentHandler = {
key: metadata.extendedFloatingActionButton.key,
codegen: ({ componentProperties: props }) => {
@@ -609,6 +802,19 @@ const inlineBannerHandler: ComponentHandler = {
},
};
+const mannerTempBadgeHandler: ComponentHandler = {
+ key: metadata.mannerTempBadge.key,
+ codegen: ({ children }) => {
+ const textNode = children.find((child) => child.type === "TEXT");
+
+ const commonProps = {
+ temperature: Number(textNode?.characters.replace(/[^\d.-]/g, "") ?? "-1"),
+ };
+
+ return createElement("MannerTempBadge", commonProps);
+ },
+};
+
const multilineTextFieldHandler: ComponentHandler = {
key: metadata.multilineTextField.key,
codegen: ({ componentProperties: props }) => {
@@ -1252,6 +1458,7 @@ const toggleButtonHandler: ComponentHandler = {
const componentHandlers = [
actionButtonHandler,
actionChipHandler,
+ actionSheetHandler,
avatarHandler,
avatarStackHandler,
badgeHandler,
@@ -1259,16 +1466,20 @@ const componentHandlers = [
checkboxHandler,
chipTabsHandler,
controlChipHandler,
+ errorStateHandler,
+ extendedActionSheetHandler,
extendedFabHandler,
fabHandler,
helpBubbleHandler,
identityPlaceholderHandler,
inlineBannerHandler,
+ mannerTempBadgeHandler,
multilineTextFieldHandler,
progressCircleHandler,
reactionButtonHandler,
segmentedControlHandler,
selectBoxGroupHandler,
+ selectBoxHandler,
skeletonHandler,
snackbarHandler,
switchHandler,
diff --git a/tools/figma-codegen/src/codegen/component/type.ts b/tools/figma-codegen/src/codegen/component/type.ts
index b0265656f..f86719256 100644
--- a/tools/figma-codegen/src/codegen/component/type.ts
+++ b/tools/figma-codegen/src/codegen/component/type.ts
@@ -9,6 +9,27 @@ export type ActionChipProperties = InferFromDefinition<
typeof metadata.actionChip.componentPropertyDefinitions
>;
+export type ActionSheetProperties = InferFromDefinition<
+ typeof metadata.actionSheet.componentPropertyDefinitions
+>;
+
+export type ActionSheetItemProperties = InferFromDefinition<{
+ "Label#15420:4": {
+ type: "TEXT";
+ defaultValue: "액션 버튼";
+ };
+ Tone: {
+ type: "VARIANT";
+ defaultValue: "Default";
+ variantOptions: ["Default", "Critical"];
+ };
+ State: {
+ type: "VARIANT";
+ defaultValue: "Enabled";
+ variantOptions: ["Enabled", "Enabled-Pressed", "Disabled"];
+ };
+}>;
+
export type AvatarProperties = InferFromDefinition<
typeof metadata.avatar.componentPropertyDefinitions
>;
@@ -61,6 +82,48 @@ export type ControlChipProperties = InferFromDefinition<
typeof metadata.controlChip.componentPropertyDefinitions
>;
+export type ErrorStateProperties = InferFromDefinition<
+ typeof metadata.errorState.componentPropertyDefinitions
+>;
+
+export type ExtendedActionSheetProperties = InferFromDefinition<
+ typeof metadata.extendedActionSheet.componentPropertyDefinitions
+>;
+
+export type ExtendedActionSheetGroupProperties = InferFromDefinition<{
+ "Action Count": {
+ type: "VARIANT";
+ defaultValue: "8";
+ variantOptions: ["1", "2", "3", "4", "5", "6", "7", "8"];
+ };
+}>;
+
+export type ExtendedActionSheetItemProperties = InferFromDefinition<{
+ "Show Prefix Icon#17043:5": {
+ type: "BOOLEAN";
+ defaultValue: true;
+ };
+ "Label#55905:8": {
+ type: "TEXT";
+ defaultValue: "액션 버튼";
+ };
+ "Prefix Icon#55948:0": {
+ type: "INSTANCE_SWAP";
+ defaultValue: "17024:100799";
+ preferredValues: [];
+ };
+ Tone: {
+ type: "VARIANT";
+ defaultValue: "Neutral";
+ variantOptions: ["Neutral", "Critical"];
+ };
+ State: {
+ type: "VARIANT";
+ defaultValue: "Enabled";
+ variantOptions: ["Enabled", "Enabled-Pressed", "Disabled"];
+ };
+}>;
+
export type ExtendedFabProperties = InferFromDefinition<
typeof metadata.extendedFloatingActionButton.componentPropertyDefinitions
>;
@@ -81,6 +144,10 @@ export type InlineBannerProperties = InferFromDefinition<
typeof metadata.inlineBanner.componentPropertyDefinitions
>;
+export type MannerTempBadgeProperties = InferFromDefinition<
+ typeof metadata.mannerTempBadge.componentPropertyDefinitions
+>;
+
export type MultilineTextFieldProperties = InferFromDefinition<
typeof metadata.multilineTextField.componentPropertyDefinitions
>;
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/error-state.d.ts b/tools/figma-codegen/src/codegen/data/component-sets/error-state.d.ts
new file mode 100644
index 000000000..842c60ff1
--- /dev/null
+++ b/tools/figma-codegen/src/codegen/data/component-sets/error-state.d.ts
@@ -0,0 +1,32 @@
+export declare const metadata: {
+ "name": "🟢 Error State",
+ "key": "39b4ecd0b5b4d35f4dc5791765ca04aa062a5172",
+ "componentPropertyDefinitions": {
+ "Secondary Action Label#17042:0": {
+ "type": "TEXT"
+ },
+ "Title#16237:0": {
+ "type": "TEXT"
+ },
+ "Description#16237:5": {
+ "type": "TEXT"
+ },
+ "Show Buttons#9080:5": {
+ "type": "BOOLEAN"
+ },
+ "Variant": {
+ "type": "VARIANT",
+ "variantOptions": [
+ "Default",
+ "Basement"
+ ]
+ },
+ "Layout": {
+ "type": "VARIANT",
+ "variantOptions": [
+ "With Title",
+ "Description Only"
+ ]
+ }
+ }
+};
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/error-state.mjs b/tools/figma-codegen/src/codegen/data/component-sets/error-state.mjs
new file mode 100644
index 000000000..0347951a5
--- /dev/null
+++ b/tools/figma-codegen/src/codegen/data/component-sets/error-state.mjs
@@ -0,0 +1,32 @@
+export const metadata = {
+ "name": "🟢 Error State",
+ "key": "39b4ecd0b5b4d35f4dc5791765ca04aa062a5172",
+ "componentPropertyDefinitions": {
+ "Secondary Action Label#17042:0": {
+ "type": "TEXT"
+ },
+ "Title#16237:0": {
+ "type": "TEXT"
+ },
+ "Description#16237:5": {
+ "type": "TEXT"
+ },
+ "Show Buttons#9080:5": {
+ "type": "BOOLEAN"
+ },
+ "Variant": {
+ "type": "VARIANT",
+ "variantOptions": [
+ "Default",
+ "Basement"
+ ]
+ },
+ "Layout": {
+ "type": "VARIANT",
+ "variantOptions": [
+ "With Title",
+ "Description Only"
+ ]
+ }
+ }
+};
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.d.ts b/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.d.ts
index 1564c7f5a..7acbe34fc 100644
--- a/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.d.ts
+++ b/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.d.ts
@@ -2,6 +2,9 @@ export declare const metadata: {
"name": "🟢 Extended Action Sheet",
"key": "cd4cf8a850bf3de87b79080b36b421a649bf3fcb",
"componentPropertyDefinitions": {
+ "Show Title#17043:12": {
+ "type": "BOOLEAN"
+ },
"OS Indicator (Figma Only)#81637:129": {
"type": "BOOLEAN"
},
@@ -18,13 +21,6 @@ export declare const metadata: {
"Destructive"
]
},
- "Header": {
- "type": "VARIANT",
- "variantOptions": [
- "True",
- "False"
- ]
- },
"Action Group Count": {
"type": "VARIANT",
"variantOptions": [
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.mjs b/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.mjs
index 63c3ce95f..0b49d20df 100644
--- a/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.mjs
+++ b/tools/figma-codegen/src/codegen/data/component-sets/extended-action-sheet.mjs
@@ -2,6 +2,9 @@ export const metadata = {
"name": "🟢 Extended Action Sheet",
"key": "cd4cf8a850bf3de87b79080b36b421a649bf3fcb",
"componentPropertyDefinitions": {
+ "Show Title#17043:12": {
+ "type": "BOOLEAN"
+ },
"OS Indicator (Figma Only)#81637:129": {
"type": "BOOLEAN"
},
@@ -18,13 +21,6 @@ export const metadata = {
"Destructive"
]
},
- "Header": {
- "type": "VARIANT",
- "variantOptions": [
- "True",
- "False"
- ]
- },
"Action Group Count": {
"type": "VARIANT",
"variantOptions": [
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/index.d.ts b/tools/figma-codegen/src/codegen/data/component-sets/index.d.ts
index 39312f2fe..8e7bc05c9 100644
--- a/tools/figma-codegen/src/codegen/data/component-sets/index.d.ts
+++ b/tools/figma-codegen/src/codegen/data/component-sets/index.d.ts
@@ -1,44 +1,45 @@
-export { metadata as chipTablist } from "./chip-tablist";
-export { metadata as bottomSheet } from "./bottom-sheet";
-export { metadata as rangeSlider } from "./range-slider";
-export { metadata as identityPlaceholder } from "./identity-placeholder";
-export { metadata as extendedFloatingActionButton } from "./extended-floating-action-button";
-export { metadata as toggleButton } from "./toggle-button";
-export { metadata as switch } from "./switch";
-export { metadata as divider } from "./divider";
-export { metadata as checkbox } from "./checkbox";
-export { metadata as helpBubble } from "./help-bubble";
-export { metadata as textButton } from "./text-button";
-export { metadata as multilineTextField } from "./multiline-text-field";
-export { metadata as slider } from "./slider";
-export { metadata as selectBoxGroup } from "./select-box-group";
+export { metadata as bottomFixedBar } from "./bottom-fixed-bar";
export { metadata as buttonGroup } from "./button-group";
+export { metadata as selectBoxGroup } from "./select-box-group";
+export { metadata as actionButton } from "./action-button";
export { metadata as actionChip } from "./action-chip";
+export { metadata as actionSheet } from "./action-sheet";
+export { metadata as avatar } from "./avatar";
+export { metadata as avatarStack } from "./avatar-stack";
export { metadata as badge } from "./badge";
-export { metadata as mannerTempBar } from "./manner-temp-bar";
-export { metadata as reactionButton } from "./reaction-button";
-export { metadata as topNavigationMainGlobal } from "./top-navigation-main-global";
+export { metadata as bottomNavigationGlobal } from "./bottom-navigation-global";
+export { metadata as bottomNavigationKr } from "./bottom-navigation-kr";
+export { metadata as bottomSheet } from "./bottom-sheet";
+export { metadata as callout } from "./callout";
+export { metadata as checkbox } from "./checkbox";
+export { metadata as chipTablist } from "./chip-tablist";
export { metadata as controlChip } from "./control-chip";
-export { metadata as tablist } from "./tablist";
+export { metadata as divider } from "./divider";
+export { metadata as errorState } from "./error-state";
+export { metadata as extendedActionSheet } from "./extended-action-sheet";
+export { metadata as extendedFloatingActionButton } from "./extended-floating-action-button";
+export { metadata as floatingActionButton } from "./floating-action-button";
+export { metadata as helpBubble } from "./help-bubble";
+export { metadata as identityPlaceholder } from "./identity-placeholder";
+export { metadata as inlineBanner } from "./inline-banner";
+export { metadata as mannerTemp } from "./manner-temp";
+export { metadata as mannerTempBar } from "./manner-temp-bar";
export { metadata as mannerTempBadge } from "./manner-temp-badge";
+export { metadata as multilineTextField } from "./multiline-text-field";
export { metadata as progressCircle } from "./progress-circle";
-export { metadata as actionSheet } from "./action-sheet";
-export { metadata as bottomNavigationKr } from "./bottom-navigation-kr";
-export { metadata as inlineBanner } from "./inline-banner";
export { metadata as radio } from "./radio";
-export { metadata as avatarStack } from "./avatar-stack";
-export { metadata as avatar } from "./avatar";
-export { metadata as actionButton } from "./action-button";
+export { metadata as rangeSlider } from "./range-slider";
+export { metadata as reactionButton } from "./reaction-button";
export { metadata as segmentedControl } from "./segmented-control";
-export { metadata as topNavigationMainKr } from "./top-navigation-main-kr";
-export { metadata as floatingActionButton } from "./floating-action-button";
-export { metadata as bottomNavigationGlobal } from "./bottom-navigation-global";
-export { metadata as callout } from "./callout";
-export { metadata as skeleton } from "./skeleton";
export { metadata as selectBox } from "./select-box";
-export { metadata as bottomFixedBar } from "./bottom-fixed-bar";
-export { metadata as extendedActionSheet } from "./extended-action-sheet";
+export { metadata as skeleton } from "./skeleton";
+export { metadata as slider } from "./slider";
export { metadata as snackbar } from "./snackbar";
-export { metadata as mannerTemp } from "./manner-temp";
-export { metadata as topNavigation } from "./top-navigation";
+export { metadata as switch } from "./switch";
+export { metadata as tablist } from "./tablist";
+export { metadata as textButton } from "./text-button";
export { metadata as textField } from "./text-field";
+export { metadata as toggleButton } from "./toggle-button";
+export { metadata as topNavigation } from "./top-navigation";
+export { metadata as topNavigationMainGlobal } from "./top-navigation-main-global";
+export { metadata as topNavigationMainKr } from "./top-navigation-main-kr";
diff --git a/tools/figma-codegen/src/codegen/data/component-sets/index.mjs b/tools/figma-codegen/src/codegen/data/component-sets/index.mjs
index d96f7d133..14a5c800d 100644
--- a/tools/figma-codegen/src/codegen/data/component-sets/index.mjs
+++ b/tools/figma-codegen/src/codegen/data/component-sets/index.mjs
@@ -1,44 +1,45 @@
-export { metadata as chipTablist } from "./chip-tablist.mjs";
-export { metadata as bottomSheet } from "./bottom-sheet.mjs";
-export { metadata as rangeSlider } from "./range-slider.mjs";
-export { metadata as identityPlaceholder } from "./identity-placeholder.mjs";
-export { metadata as extendedFloatingActionButton } from "./extended-floating-action-button.mjs";
-export { metadata as toggleButton } from "./toggle-button.mjs";
-export { metadata as switch } from "./switch.mjs";
-export { metadata as divider } from "./divider.mjs";
-export { metadata as checkbox } from "./checkbox.mjs";
-export { metadata as helpBubble } from "./help-bubble.mjs";
-export { metadata as textButton } from "./text-button.mjs";
-export { metadata as multilineTextField } from "./multiline-text-field.mjs";
-export { metadata as slider } from "./slider.mjs";
-export { metadata as selectBoxGroup } from "./select-box-group.mjs";
+export { metadata as bottomFixedBar } from "./bottom-fixed-bar.mjs";
export { metadata as buttonGroup } from "./button-group.mjs";
+export { metadata as selectBoxGroup } from "./select-box-group.mjs";
+export { metadata as actionButton } from "./action-button.mjs";
export { metadata as actionChip } from "./action-chip.mjs";
+export { metadata as actionSheet } from "./action-sheet.mjs";
+export { metadata as avatar } from "./avatar.mjs";
+export { metadata as avatarStack } from "./avatar-stack.mjs";
export { metadata as badge } from "./badge.mjs";
-export { metadata as mannerTempBar } from "./manner-temp-bar.mjs";
-export { metadata as reactionButton } from "./reaction-button.mjs";
-export { metadata as topNavigationMainGlobal } from "./top-navigation-main-global.mjs";
+export { metadata as bottomNavigationGlobal } from "./bottom-navigation-global.mjs";
+export { metadata as bottomNavigationKr } from "./bottom-navigation-kr.mjs";
+export { metadata as bottomSheet } from "./bottom-sheet.mjs";
+export { metadata as callout } from "./callout.mjs";
+export { metadata as checkbox } from "./checkbox.mjs";
+export { metadata as chipTablist } from "./chip-tablist.mjs";
export { metadata as controlChip } from "./control-chip.mjs";
-export { metadata as tablist } from "./tablist.mjs";
+export { metadata as divider } from "./divider.mjs";
+export { metadata as errorState } from "./error-state.mjs";
+export { metadata as extendedActionSheet } from "./extended-action-sheet.mjs";
+export { metadata as extendedFloatingActionButton } from "./extended-floating-action-button.mjs";
+export { metadata as floatingActionButton } from "./floating-action-button.mjs";
+export { metadata as helpBubble } from "./help-bubble.mjs";
+export { metadata as identityPlaceholder } from "./identity-placeholder.mjs";
+export { metadata as inlineBanner } from "./inline-banner.mjs";
+export { metadata as mannerTemp } from "./manner-temp.mjs";
+export { metadata as mannerTempBar } from "./manner-temp-bar.mjs";
export { metadata as mannerTempBadge } from "./manner-temp-badge.mjs";
+export { metadata as multilineTextField } from "./multiline-text-field.mjs";
export { metadata as progressCircle } from "./progress-circle.mjs";
-export { metadata as actionSheet } from "./action-sheet.mjs";
-export { metadata as bottomNavigationKr } from "./bottom-navigation-kr.mjs";
-export { metadata as inlineBanner } from "./inline-banner.mjs";
export { metadata as radio } from "./radio.mjs";
-export { metadata as avatarStack } from "./avatar-stack.mjs";
-export { metadata as avatar } from "./avatar.mjs";
-export { metadata as actionButton } from "./action-button.mjs";
+export { metadata as rangeSlider } from "./range-slider.mjs";
+export { metadata as reactionButton } from "./reaction-button.mjs";
export { metadata as segmentedControl } from "./segmented-control.mjs";
-export { metadata as topNavigationMainKr } from "./top-navigation-main-kr.mjs";
-export { metadata as floatingActionButton } from "./floating-action-button.mjs";
-export { metadata as bottomNavigationGlobal } from "./bottom-navigation-global.mjs";
-export { metadata as callout } from "./callout.mjs";
-export { metadata as skeleton } from "./skeleton.mjs";
export { metadata as selectBox } from "./select-box.mjs";
-export { metadata as bottomFixedBar } from "./bottom-fixed-bar.mjs";
-export { metadata as extendedActionSheet } from "./extended-action-sheet.mjs";
+export { metadata as skeleton } from "./skeleton.mjs";
+export { metadata as slider } from "./slider.mjs";
export { metadata as snackbar } from "./snackbar.mjs";
-export { metadata as mannerTemp } from "./manner-temp.mjs";
-export { metadata as topNavigation } from "./top-navigation.mjs";
+export { metadata as switch } from "./switch.mjs";
+export { metadata as tablist } from "./tablist.mjs";
+export { metadata as textButton } from "./text-button.mjs";
export { metadata as textField } from "./text-field.mjs";
+export { metadata as toggleButton } from "./toggle-button.mjs";
+export { metadata as topNavigation } from "./top-navigation.mjs";
+export { metadata as topNavigationMainGlobal } from "./top-navigation-main-global.mjs";
+export { metadata as topNavigationMainKr } from "./top-navigation-main-kr.mjs";
diff --git a/yarn.lock b/yarn.lock
index 38e9b6314..19f43f8da 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7752,7 +7752,7 @@ __metadata:
"@create-figma-plugin/tsconfig": "npm:^3.0.2"
"@create-figma-plugin/utilities": "npm:^3.0.2"
"@figma/plugin-typings": "npm:^1.107.0-beta.1"
- "@seed-design/figma-extractor": "npm:^0.0.2"
+ "@seed-design/figma-extractor": "npm:^0.0.3"
change-case: "npm:^5.2.0"
ts-pattern: "npm:^5.2.0"
typescript: "npm:^5.4.5"
@@ -7785,7 +7785,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@seed-design/figma-extractor@npm:^0.0.2, @seed-design/figma-extractor@workspace:tools/figma-extractor":
+"@seed-design/figma-extractor@npm:^0.0.3, @seed-design/figma-extractor@workspace:tools/figma-extractor":
version: 0.0.0-use.local
resolution: "@seed-design/figma-extractor@workspace:tools/figma-extractor"
dependencies:
From 8b4522ec91cbe333c5c966cdd8a8bb848c0723ed Mon Sep 17 00:00:00 2001
From: malangcat
Date: Sun, 26 Jan 2025 23:51:11 +0900
Subject: [PATCH 3/6] refactor: root layout as server component
---
docs/app/layout.tsx | 9 +++------
docs/components/theme-sync.tsx | 10 ++++++++++
2 files changed, 13 insertions(+), 6 deletions(-)
create mode 100644 docs/components/theme-sync.tsx
diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx
index a69957008..ac0cdfc4a 100644
--- a/docs/app/layout.tsx
+++ b/docs/app/layout.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import "@seed-design/stylesheet/base.css";
import "@seed-design/stylesheet/global.css";
import "@seed-design/stylesheet/token.css";
@@ -8,19 +6,17 @@ import "@stackflow/plugin-basic-ui/index.css";
import "simple-reveal/index.css";
import "./global.css";
-import { useThemeSync } from "@/hooks/useThemeSync";
+import GoogleAnalytics from "@/components/google-analytics";
+import ThemeSync from "@/components/theme-sync";
import { RootProvider } from "fumadocs-ui/provider";
import { Inter } from "next/font/google";
import type { ReactNode } from "react";
-import GoogleAnalytics from "@/components/google-analytics";
const inter = Inter({
subsets: ["latin"],
});
export default function Layout({ children }: { children: ReactNode }) {
- useThemeSync();
-
return (
+
{children}
diff --git a/docs/components/theme-sync.tsx b/docs/components/theme-sync.tsx
new file mode 100644
index 000000000..f3aa92ba9
--- /dev/null
+++ b/docs/components/theme-sync.tsx
@@ -0,0 +1,10 @@
+"use client";
+
+import { useThemeSync } from "@/hooks/useThemeSync";
+
+function ThemeSync() {
+ useThemeSync();
+
+ return null;
+}
+export default ThemeSync;
From a40e62162d58b6ff4bea27829d9b8db2b992dee5 Mon Sep 17 00:00:00 2001
From: malangcat
Date: Mon, 27 Jan 2025 00:04:08 +0900
Subject: [PATCH 4/6] feat: cleanup sanity
---
.gitignore | 1 +
docs/app/(home)/page.tsx | 13 +--
docs/app/blog/[[...slug]]/page.tsx | 102 ------------------
docs/app/blog/[slug]/page.tsx | 98 +++++++++++++++++
docs/app/blog/layout.tsx | 8 +-
docs/app/docs/[[...slug]]/page.tsx | 31 +++++-
docs/components/mdx/mdx-components.ts | 2 -
docs/components/sanity/client.tsx | 8 --
docs/components/sanity/sanity-content.tsx | 68 ------------
.../docs/design/components/action-button.mdx | 2 -
.../docs/design/components/action-chip.mdx | 2 -
.../docs/design/components/alert-dialog.mdx | 2 -
.../content/docs/design/components/avatar.mdx | 2 -
docs/content/docs/design/components/badge.mdx | 2 -
.../docs/design/components/bottom-sheet.mdx | 2 -
.../docs/design/components/callout.mdx | 2 -
.../docs/design/components/control-chip.mdx | 2 -
.../docs/design/components/extended-fab.mdx | 2 -
docs/content/docs/design/components/fab.mdx | 2 -
.../docs/design/components/inline-banner.mdx | 2 -
.../design/components/progress-circle.mdx | 2 -
.../design/components/reaction-button.mdx | 2 -
.../design/components/segmented-control.mdx | 2 -
.../docs/design/components/select-box.mdx | 2 -
.../docs/design/components/text-button.mdx | 2 -
.../docs/design/components/text-field.mdx | 2 -
.../docs/design/components/toggle-button.mdx | 2 -
.../docs/design/components/top-navigation.mdx | 2 -
.../foundation/iconography/overview.mdx | 2 -
.../design/foundation/iconography/usage.mdx | 2 -
.../content/docs/design/foundation/radius.mdx | 2 -
.../docs/design/guidelines/loading.mdx | 2 -
docs/sanity.config.ts | 1 -
docs/sanity/lib/client.tsx | 9 ++
.../sanity => sanity/lib}/do-dont.tsx | 0
.../sanity => sanity/lib}/external-image.tsx | 0
.../sanity => sanity/lib}/image-text-half.tsx | 4 +-
.../sanity => sanity/lib}/image.tsx | 11 +-
docs/sanity/lib/queries.ts | 24 +++++
docs/sanity/lib/sanity-content.tsx | 66 ++++++++++++
.../sanity => sanity/lib}/table.tsx | 2 -
.../sanity => sanity/lib}/types.ts | 0
42 files changed, 239 insertions(+), 255 deletions(-)
delete mode 100644 docs/app/blog/[[...slug]]/page.tsx
create mode 100644 docs/app/blog/[slug]/page.tsx
delete mode 100644 docs/components/sanity/client.tsx
delete mode 100644 docs/components/sanity/sanity-content.tsx
create mode 100644 docs/sanity/lib/client.tsx
rename docs/{components/sanity => sanity/lib}/do-dont.tsx (100%)
rename docs/{components/sanity => sanity/lib}/external-image.tsx (100%)
rename docs/{components/sanity => sanity/lib}/image-text-half.tsx (92%)
rename docs/{components/sanity => sanity/lib}/image.tsx (90%)
create mode 100644 docs/sanity/lib/queries.ts
create mode 100644 docs/sanity/lib/sanity-content.tsx
rename docs/{components/sanity => sanity/lib}/table.tsx (98%)
rename docs/{components/sanity => sanity/lib}/types.ts (100%)
diff --git a/.gitignore b/.gitignore
index 892eef53f..2a97b1a84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@
**/node_modules/
lib
+!docs/**/lib
\ No newline at end of file
diff --git a/docs/app/(home)/page.tsx b/docs/app/(home)/page.tsx
index b76d9fd76..4838a3b60 100644
--- a/docs/app/(home)/page.tsx
+++ b/docs/app/(home)/page.tsx
@@ -1,5 +1,6 @@
-import { client } from "@/components/sanity/client";
-import { SanityImage } from "@/components/sanity/image";
+import { client } from "@/sanity/lib/client";
+import { SanityImage } from "@/sanity/lib/image";
+import { BLOG_QUERY } from "@/sanity/lib/queries";
import type { SanityImageAsset } from "@sanity/asset-utils";
import Link from "next/link";
@@ -14,14 +15,6 @@ interface Blog {
publishedAt: string;
}
-const BLOG_QUERY = `*[_type == "blog"] {
- title,
- description,
- thumbnail,
- slug,
- publishedAt,
-}`;
-
export default async function HomePage() {
const blogs = await client.fetch(
BLOG_QUERY,
diff --git a/docs/app/blog/[[...slug]]/page.tsx b/docs/app/blog/[[...slug]]/page.tsx
deleted file mode 100644
index 805f7c30a..000000000
--- a/docs/app/blog/[[...slug]]/page.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import { client } from "@/components/sanity/client";
-import { SanityImage } from "@/components/sanity/image";
-import { PortableContent } from "@/components/sanity/sanity-content";
-import { SanityImageAsset } from "@sanity/asset-utils";
-import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page";
-import { Metadata } from "next";
-import { notFound } from "next/navigation";
-
-interface Blog {
- title: string;
- description: string;
- thumbnail: SanityImageAsset;
- slug: {
- current: string;
- _type: "slug";
- };
- publishedAt: string;
- // biome-ignore lint/suspicious/noExplicitAny:
- content: any;
-}
-
-const BLOG_QUERY = `*[_type == "blog"] {
- title,
- description,
- thumbnail,
- slug,
- publishedAt,
- content
- }`;
-
-const SINGLE_BLOG_QUERY = `*[_type == "blog" && slug.current == $slug][0] {
- title,
- description,
- thumbnail,
- slug,
- publishedAt,
- content
- }`;
-
-export default async function Page({
- params,
-}: {
- params: { slug?: string[] };
-}) {
- if (!params.slug) notFound();
-
- const blog = await client.fetch(SINGLE_BLOG_QUERY, {
- slug: params.slug[0],
- });
-
- if (!blog) {
- return (
-
-
-
- );
- }
-
- return (
-
- {blog.title}
- {blog.description}
-
-
-
-
-
- );
-}
-
-export async function generateStaticParams() {
- const blogs = await client.fetch(
- BLOG_QUERY,
- {},
- {
- perspective: "published",
- },
- );
-
- const slugs = blogs.map((blog) => {
- return { slug: [blog.slug.current] };
- });
-
- return slugs;
-}
-
-export async function generateMetadata({ params }: { params: { slug?: string[] } }) {
- const blogs = await client.fetch(
- BLOG_QUERY,
- {},
- {
- perspective: "published",
- },
- );
-
- const page = blogs.find((blog) => blog.slug.current === params.slug?.[0]);
-
- return {
- title: page?.title,
- description: page?.description,
- } satisfies Metadata;
-}
diff --git a/docs/app/blog/[slug]/page.tsx b/docs/app/blog/[slug]/page.tsx
new file mode 100644
index 000000000..541fd6c1a
--- /dev/null
+++ b/docs/app/blog/[slug]/page.tsx
@@ -0,0 +1,98 @@
+import { client } from "@/sanity/lib/client";
+import { SanityImage } from "@/sanity/lib/image";
+import { BLOG_QUERY, SINGLE_BLOG_QUERY } from "@/sanity/lib/queries";
+import { PortableContent } from "@/sanity/lib/sanity-content";
+import { SanityImageAsset } from "@sanity/asset-utils";
+import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page";
+import { Metadata } from "next";
+import { notFound } from "next/navigation";
+import { PortableTextBlock } from "sanity";
+
+interface Blog {
+ title: string;
+ description: string;
+ thumbnail: SanityImageAsset;
+ slug: {
+ current: string;
+ _type: "slug";
+ };
+ publishedAt: string;
+ content: PortableTextBlock | PortableTextBlock[];
+ toc?: {
+ _key: string;
+ level: number;
+ }[];
+}
+
+export default async function Page({
+ params,
+}: {
+ params: { slug?: string };
+}) {
+ const page = await client.fetch(SINGLE_BLOG_QUERY, {
+ slug: params.slug,
+ });
+
+ if (!page) {
+ notFound();
+ }
+
+ const toc = page.toc?.map((item) => {
+ return {
+ depth: item.level ?? 0,
+ title: (
+
+ ),
+ url: `#${item._key}`,
+ };
+ });
+
+ return (
+
+ {page.title}
+ {page.description}
+
+
+
+
+
+ );
+}
+
+export async function generateStaticParams() {
+ const blogs = await client.fetch(
+ BLOG_QUERY,
+ {},
+ {
+ perspective: "published",
+ },
+ );
+
+ const slugs = blogs.map((blog) => {
+ return { slug: blog.slug.current };
+ });
+
+ return slugs;
+}
+
+export async function generateMetadata({ params }: { params: { slug?: string } }) {
+ const blogs = await client.fetch(
+ BLOG_QUERY,
+ {},
+ {
+ perspective: "published",
+ },
+ );
+
+ const page = blogs.find((blog) => blog.slug.current === params.slug);
+
+ return {
+ title: page?.title,
+ description: page?.description,
+ } satisfies Metadata;
+}
diff --git a/docs/app/blog/layout.tsx b/docs/app/blog/layout.tsx
index 045551d6f..f50d637c4 100644
--- a/docs/app/blog/layout.tsx
+++ b/docs/app/blog/layout.tsx
@@ -1,11 +1,7 @@
import { DocsLayout } from "fumadocs-ui/layouts/docs";
-import { Suspense, type ReactNode } from "react";
+import { type ReactNode } from "react";
import { docsOptions } from "../layout.config";
export default function Layout({ children }: { children: ReactNode }) {
- return (
-
- {children}
-
- );
+ return {children};
}
diff --git a/docs/app/docs/[[...slug]]/page.tsx b/docs/app/docs/[[...slug]]/page.tsx
index d11c25d8e..53a28d55f 100644
--- a/docs/app/docs/[[...slug]]/page.tsx
+++ b/docs/app/docs/[[...slug]]/page.tsx
@@ -1,8 +1,12 @@
import { source } from "@/app/source";
import { mdxComponents } from "@/components/mdx/mdx-components";
+import { client } from "@/sanity/lib/client";
+import { GUIDELINE_QUERY } from "@/sanity/lib/queries";
+import { PortableContent } from "@/sanity/lib/sanity-content";
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
+import { PortableTextBlock } from "sanity";
export default async function Page({
params,
@@ -14,11 +18,36 @@ export default async function Page({
const MDX = page.data.body;
+ const guideline = params.slug?.includes("design")
+ ? await client.fetch(GUIDELINE_QUERY, { title: page.data.title })
+ : null;
+
+ const guidelineToc =
+ guideline?.toc?.map((item: PortableTextBlock) => {
+ return {
+ depth: item.level ?? 0,
+ title: (
+
+ ),
+ url: `#${item._key}`,
+ };
+ }) ?? [];
+
return (
-
+
{page.data.title}
{page.data.description}
+ {guideline && }
diff --git a/docs/components/mdx/mdx-components.ts b/docs/components/mdx/mdx-components.ts
index 5e5782c9b..3762ca652 100644
--- a/docs/components/mdx/mdx-components.ts
+++ b/docs/components/mdx/mdx-components.ts
@@ -1,7 +1,6 @@
import { ComponentExample } from "@/components/component-example";
import { ComponentSpecBlock } from "@/components/component-spec-block";
import { Installation } from "@/components/installation";
-import { SanityGuideline } from "@/components/sanity/sanity-content";
import { StackflowExample } from "@/components/stackflow-example";
import { File, Files, Folder } from "fumadocs-ui/components/files";
import { Step, Steps } from "fumadocs-ui/components/steps";
@@ -19,7 +18,6 @@ export const mdxComponents = {
ComponentExample,
TokenReference,
ComponentSpecBlock,
- SanityGuideline,
Tab,
Tabs,
Step,
diff --git a/docs/components/sanity/client.tsx b/docs/components/sanity/client.tsx
deleted file mode 100644
index fe658e8b7..000000000
--- a/docs/components/sanity/client.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { createClient } from "@sanity/client";
-
-export const client = createClient({
- projectId: "mokd6dka",
- dataset: "production",
- apiVersion: "2024-01-01",
- useCdn: true,
-});
diff --git a/docs/components/sanity/sanity-content.tsx b/docs/components/sanity/sanity-content.tsx
deleted file mode 100644
index 8b524c175..000000000
--- a/docs/components/sanity/sanity-content.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-"use client";
-
-import { PortableText } from "@portabletext/react";
-import type { SanityDocument } from "next-sanity";
-import { client } from "./client";
-
-import { ImageTextHalfPreview } from "@/components/sanity/image-text-half";
-import { useEffect, useState } from "react";
-import ErrorBoundary from "../error-boundary";
-import { DoDont } from "./do-dont";
-import { ExternalImage } from "./external-image";
-import { PortableImage } from "./image";
-import { Table } from "./table";
-
-interface SanityGuidelineProps {
- title: string;
-}
-
-const GUIDELINE_QUERY = `*[_type == "guideline" && title == $title][0] {
- title,
- content,
- publishedAt
-}`;
-
-export const SanityGuideline = ({ title }: SanityGuidelineProps) => {
- const [data, setData] = useState(null);
-
- useEffect(() => {
- const fetchData = async () => {
- const data = await client.fetch(GUIDELINE_QUERY, { title });
- setData(data);
- };
- fetchData();
- }, [title]);
-
- if (!data) {
- return null;
- }
-
- return (
-
-
-
- );
-};
-
-// biome-ignore lint/suspicious/noExplicitAny:
-export const PortableContent = ({ content }: { content: any }) => {
- return (
- ,
- tabelContainer: Table,
- imageWithText: ImageTextHalfPreview,
- externalImageLink: ExternalImage,
- doDont: DoDont,
- },
- block: {
- normal: (props) => ,
- h3: (props) => ,
- description: (props) => ,
- },
- }}
- value={content}
- />
- );
-};
diff --git a/docs/content/docs/design/components/action-button.mdx b/docs/content/docs/design/components/action-button.mdx
index d36125d81..7c9ad181b 100644
--- a/docs/content/docs/design/components/action-button.mdx
+++ b/docs/content/docs/design/components/action-button.mdx
@@ -3,8 +3,6 @@ title: Action Button
description: 사용자가 특정 액션을 실행할 수 있도록 도와주는 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/action-chip.mdx b/docs/content/docs/design/components/action-chip.mdx
index a003dcfe5..0beb130b0 100644
--- a/docs/content/docs/design/components/action-chip.mdx
+++ b/docs/content/docs/design/components/action-chip.mdx
@@ -3,8 +3,6 @@ title: Action Chip
description: 사용자가 특정 액션을 실행할 수 있도록 도와주는 Pill 형태의 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/alert-dialog.mdx b/docs/content/docs/design/components/alert-dialog.mdx
index c2a0b2a58..da0bd89c5 100644
--- a/docs/content/docs/design/components/alert-dialog.mdx
+++ b/docs/content/docs/design/components/alert-dialog.mdx
@@ -3,8 +3,6 @@ title: Alert Dialog
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/avatar.mdx b/docs/content/docs/design/components/avatar.mdx
index 9b11fbefb..31faefef9 100644
--- a/docs/content/docs/design/components/avatar.mdx
+++ b/docs/content/docs/design/components/avatar.mdx
@@ -3,8 +3,6 @@ title: Avatar
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블 (Avatar)
diff --git a/docs/content/docs/design/components/badge.mdx b/docs/content/docs/design/components/badge.mdx
index 84861326d..8c71fd07f 100644
--- a/docs/content/docs/design/components/badge.mdx
+++ b/docs/content/docs/design/components/badge.mdx
@@ -3,8 +3,6 @@ title: Badge
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/bottom-sheet.mdx b/docs/content/docs/design/components/bottom-sheet.mdx
index d9eeceb0f..cdc48000e 100644
--- a/docs/content/docs/design/components/bottom-sheet.mdx
+++ b/docs/content/docs/design/components/bottom-sheet.mdx
@@ -3,8 +3,6 @@ title: Bottom Sheet
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/callout.mdx b/docs/content/docs/design/components/callout.mdx
index bffbd2aac..14450dab7 100644
--- a/docs/content/docs/design/components/callout.mdx
+++ b/docs/content/docs/design/components/callout.mdx
@@ -3,8 +3,6 @@ title: Callout
description: 사용자의 주목을 끌어 중요한 정보를 강조하는 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/control-chip.mdx b/docs/content/docs/design/components/control-chip.mdx
index e0abb7cd0..4a19b7f63 100644
--- a/docs/content/docs/design/components/control-chip.mdx
+++ b/docs/content/docs/design/components/control-chip.mdx
@@ -3,8 +3,6 @@ title: Control Chip
description: Control Chip은 사용자가 선택, 필터링, 전환과 같은 제어 작업을 수행할 수 있도록 돕는 Pill 형태의 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/extended-fab.mdx b/docs/content/docs/design/components/extended-fab.mdx
index 95d287bad..1c2ba4f42 100644
--- a/docs/content/docs/design/components/extended-fab.mdx
+++ b/docs/content/docs/design/components/extended-fab.mdx
@@ -3,8 +3,6 @@ title: Extended FAB
description: 사용자가 특정 액션을 실행할 수 있도록 도와주는 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/fab.mdx b/docs/content/docs/design/components/fab.mdx
index 1bf2d62cb..500a67500 100644
--- a/docs/content/docs/design/components/fab.mdx
+++ b/docs/content/docs/design/components/fab.mdx
@@ -3,8 +3,6 @@ title: FAB
description: 사용자가 특정 액션을 실행할 수 있도록 도와주는 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/inline-banner.mdx b/docs/content/docs/design/components/inline-banner.mdx
index 93bd962cf..1b5987baf 100644
--- a/docs/content/docs/design/components/inline-banner.mdx
+++ b/docs/content/docs/design/components/inline-banner.mdx
@@ -3,8 +3,6 @@ title: Inline Banner
description: 사용자가 꼭 알아야 하는 경고 메시지나 현재 상태를 전달하는 컴포넌트입니다.
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/progress-circle.mdx b/docs/content/docs/design/components/progress-circle.mdx
index 8fc9b0c54..d5bf34bf8 100644
--- a/docs/content/docs/design/components/progress-circle.mdx
+++ b/docs/content/docs/design/components/progress-circle.mdx
@@ -3,8 +3,6 @@ title: Progress Circle
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/reaction-button.mdx b/docs/content/docs/design/components/reaction-button.mdx
index b2a4055f9..0d2ab3882 100644
--- a/docs/content/docs/design/components/reaction-button.mdx
+++ b/docs/content/docs/design/components/reaction-button.mdx
@@ -3,8 +3,6 @@ title: Reaction Button
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/segmented-control.mdx b/docs/content/docs/design/components/segmented-control.mdx
index 9e8a5a11a..e9fed80c7 100644
--- a/docs/content/docs/design/components/segmented-control.mdx
+++ b/docs/content/docs/design/components/segmented-control.mdx
@@ -3,8 +3,6 @@ title: Segmented Control
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블 (Segment)
diff --git a/docs/content/docs/design/components/select-box.mdx b/docs/content/docs/design/components/select-box.mdx
index 4b664fd69..e4f226ca6 100644
--- a/docs/content/docs/design/components/select-box.mdx
+++ b/docs/content/docs/design/components/select-box.mdx
@@ -3,8 +3,6 @@ title: Select Box
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/text-button.mdx b/docs/content/docs/design/components/text-button.mdx
index 17b248b13..fe7152a67 100644
--- a/docs/content/docs/design/components/text-button.mdx
+++ b/docs/content/docs/design/components/text-button.mdx
@@ -3,8 +3,6 @@ title: Text Button
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/text-field.mdx b/docs/content/docs/design/components/text-field.mdx
index d1cd9a6e2..358ca3bb6 100644
--- a/docs/content/docs/design/components/text-field.mdx
+++ b/docs/content/docs/design/components/text-field.mdx
@@ -3,8 +3,6 @@ title: Text Field
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/toggle-button.mdx b/docs/content/docs/design/components/toggle-button.mdx
index 7c96f10c8..e19cbbac8 100644
--- a/docs/content/docs/design/components/toggle-button.mdx
+++ b/docs/content/docs/design/components/toggle-button.mdx
@@ -3,8 +3,6 @@ title: Toggle Button
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/components/top-navigation.mdx b/docs/content/docs/design/components/top-navigation.mdx
index e0aeb416d..d4ce73a85 100644
--- a/docs/content/docs/design/components/top-navigation.mdx
+++ b/docs/content/docs/design/components/top-navigation.mdx
@@ -3,8 +3,6 @@ title: Top Navigation
description: "이 문서는 정리 중이에요. 문의 내용은 #_design_core 채널을 찾아주세요."
---
-
-
## 개요
### 옵션 테이블
diff --git a/docs/content/docs/design/foundation/iconography/overview.mdx b/docs/content/docs/design/foundation/iconography/overview.mdx
index 8e655b1c6..b5ed3076e 100644
--- a/docs/content/docs/design/foundation/iconography/overview.mdx
+++ b/docs/content/docs/design/foundation/iconography/overview.mdx
@@ -2,5 +2,3 @@
title: Overview
description: 아이콘은 사용자가 복잡한 정보나 기능을 빠르게 이해할 수 있도록 도와주는 디자인 요소입니다.
---
-
-
diff --git a/docs/content/docs/design/foundation/iconography/usage.mdx b/docs/content/docs/design/foundation/iconography/usage.mdx
index 291f8c31f..0fae620fd 100644
--- a/docs/content/docs/design/foundation/iconography/usage.mdx
+++ b/docs/content/docs/design/foundation/iconography/usage.mdx
@@ -2,5 +2,3 @@
title: Usage
description: 아이콘과 다른 디자인 요소 간의 상호작용 및 아이콘 사용 방법에 대해 설명합니다.
---
-
-
diff --git a/docs/content/docs/design/foundation/radius.mdx b/docs/content/docs/design/foundation/radius.mdx
index 10169ac41..613447153 100644
--- a/docs/content/docs/design/foundation/radius.mdx
+++ b/docs/content/docs/design/foundation/radius.mdx
@@ -3,8 +3,6 @@ title: Radius
description: Radius는 컴포넌트 혹은 콘텐츠 모서리의 둥글기를 표현합니다.
---
-
-
### Radius Tokens
diff --git a/docs/content/docs/design/guidelines/loading.mdx b/docs/content/docs/design/guidelines/loading.mdx
index 304aefd21..84b8274d9 100644
--- a/docs/content/docs/design/guidelines/loading.mdx
+++ b/docs/content/docs/design/guidelines/loading.mdx
@@ -2,5 +2,3 @@
title: Loading
description: 로딩을 관리하는 데 필요한 요소, 시간에 따른 적합한 선택지와 단계별로 사용자 경험을 최적화하는 방법에 대해 소개합니다.
---
-
-
diff --git a/docs/sanity.config.ts b/docs/sanity.config.ts
index 3b9ff3da0..3ac1d74d2 100644
--- a/docs/sanity.config.ts
+++ b/docs/sanity.config.ts
@@ -18,7 +18,6 @@ import { schema } from "./sanity/schemaTypes";
import { table } from "@sanity/table";
export default defineConfig({
- basePath: "/studio",
projectId,
dataset,
// Add and edit the content schema in the './sanity/schemaTypes' folder
diff --git a/docs/sanity/lib/client.tsx b/docs/sanity/lib/client.tsx
new file mode 100644
index 000000000..5cd7d7f7e
--- /dev/null
+++ b/docs/sanity/lib/client.tsx
@@ -0,0 +1,9 @@
+import { createClient } from "@sanity/client";
+import { apiVersion, dataset, projectId } from "../env";
+
+export const client = createClient({
+ projectId: projectId,
+ dataset: dataset,
+ apiVersion: apiVersion,
+ useCdn: false,
+});
diff --git a/docs/components/sanity/do-dont.tsx b/docs/sanity/lib/do-dont.tsx
similarity index 100%
rename from docs/components/sanity/do-dont.tsx
rename to docs/sanity/lib/do-dont.tsx
diff --git a/docs/components/sanity/external-image.tsx b/docs/sanity/lib/external-image.tsx
similarity index 100%
rename from docs/components/sanity/external-image.tsx
rename to docs/sanity/lib/external-image.tsx
diff --git a/docs/components/sanity/image-text-half.tsx b/docs/sanity/lib/image-text-half.tsx
similarity index 92%
rename from docs/components/sanity/image-text-half.tsx
rename to docs/sanity/lib/image-text-half.tsx
index 210e298a6..1b93191f9 100644
--- a/docs/components/sanity/image-text-half.tsx
+++ b/docs/sanity/lib/image-text-half.tsx
@@ -1,11 +1,11 @@
"use client";
-import { PortableContent } from "@/components/sanity/sanity-content";
-import { PortableTextBlock } from "@portabletext/react";
+import { PortableTextBlock } from "sanity";
import { SanityImageAsset } from "@sanity/asset-utils";
import imageUrlBuilder from "@sanity/image-url";
import { useCallback } from "react";
import { client } from "./client";
+import { PortableContent } from "./sanity-content";
const builder = imageUrlBuilder(client);
diff --git a/docs/components/sanity/image.tsx b/docs/sanity/lib/image.tsx
similarity index 90%
rename from docs/components/sanity/image.tsx
rename to docs/sanity/lib/image.tsx
index 97660dc2c..6d1934498 100644
--- a/docs/components/sanity/image.tsx
+++ b/docs/sanity/lib/image.tsx
@@ -1,14 +1,13 @@
"use client";
-import imageUrlBuilder from "@sanity/image-url";
-import { client } from "./client";
-
import type { PortableTextTypeComponentProps } from "@portabletext/react";
import { getImageDimensions, SanityImageAsset } from "@sanity/asset-utils";
-import { SanityImageType } from "./types";
+import imageUrlBuilder from "@sanity/image-url";
import clsx from "clsx";
+import { client } from "./client";
+import { SanityImageType } from "./types";
-const { projectId, dataset } = client.config();
+const builder = imageUrlBuilder(client);
interface ImageProps {
value: SanityImageAsset;
@@ -20,7 +19,6 @@ export const SanityImage = ({ value, className }: ImageProps) => {
return ;
}
- const builder = imageUrlBuilder({ projectId: projectId!, dataset: dataset! });
const cdnUrl = builder
.image(value)
.width(1000)
@@ -48,7 +46,6 @@ export const PortableImage = ({ value }: PortableTextTypeComponentProps
const { aspectRatio } = getImageDimensions(value as any);
- const builder = imageUrlBuilder({ projectId: projectId!, dataset: dataset! });
// Sanity CDN URL 생성
const cdnUrl = builder
diff --git a/docs/sanity/lib/queries.ts b/docs/sanity/lib/queries.ts
new file mode 100644
index 000000000..f8c903836
--- /dev/null
+++ b/docs/sanity/lib/queries.ts
@@ -0,0 +1,24 @@
+export const BLOG_QUERY = `*[_type == "blog"] {
+ title,
+ description,
+ thumbnail,
+ slug,
+ publishedAt,
+}`;
+
+export const SINGLE_BLOG_QUERY = `*[_type == "blog" && slug.current == $slug][0] {
+ title,
+ description,
+ thumbnail,
+ slug,
+ publishedAt,
+ content,
+ "toc": content[style in ["h1", "h2", "h3", "h4", "h5", "h6"]]
+}`;
+
+export const GUIDELINE_QUERY = `*[_type == "guideline" && title == $title][0] {
+ title,
+ content,
+ publishedAt,
+ "toc": content[style in ["h1", "h2", "h3", "h4", "h5", "h6"]]
+}`;
diff --git a/docs/sanity/lib/sanity-content.tsx b/docs/sanity/lib/sanity-content.tsx
new file mode 100644
index 000000000..76c71e3e5
--- /dev/null
+++ b/docs/sanity/lib/sanity-content.tsx
@@ -0,0 +1,66 @@
+"use client";
+
+import { PortableText } from "@portabletext/react";
+import { Heading } from "fumadocs-ui/components/heading";
+import { PortableTextBlock } from "sanity";
+import { DoDont } from "./do-dont";
+import { ExternalImage } from "./external-image";
+import { PortableImage } from "./image";
+import { ImageTextHalfPreview } from "./image-text-half";
+import { Table } from "./table";
+
+export const PortableContent = ({
+ content,
+}: { content: PortableTextBlock | PortableTextBlock[] }) => {
+ return (
+ (
+
+ {children}
+
+ ),
+ h1: ({ value, children }) => (
+
+ {children}
+
+ ),
+ h2: ({ value, children }) => (
+
+ {children}
+
+ ),
+ h3: ({ value, children }) => (
+
+ {children}
+
+ ),
+ h4: ({ value, children }) => (
+
+ {children}
+
+ ),
+ h5: ({ value, children }) => (
+
+ {children}
+
+ ),
+ description: ({ value, children }) => (
+
+ {children}
+
+ ),
+ },
+ }}
+ value={content}
+ />
+ );
+};
diff --git a/docs/components/sanity/table.tsx b/docs/sanity/lib/table.tsx
similarity index 98%
rename from docs/components/sanity/table.tsx
rename to docs/sanity/lib/table.tsx
index 120ea8e3f..682515a34 100644
--- a/docs/components/sanity/table.tsx
+++ b/docs/sanity/lib/table.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import type { PortableTextTypeComponentProps } from "@portabletext/react";
interface TableContainerProps {
diff --git a/docs/components/sanity/types.ts b/docs/sanity/lib/types.ts
similarity index 100%
rename from docs/components/sanity/types.ts
rename to docs/sanity/lib/types.ts
From a909bfc6f46bdaeffdf84a64b9d26e18a6158d2a Mon Sep 17 00:00:00 2001
From: malangcat
Date: Mon, 27 Jan 2025 00:04:31 +0900
Subject: [PATCH 5/6] feat: add mainDocuments to presentation tool
---
docs/sanity.config.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/docs/sanity.config.ts b/docs/sanity.config.ts
index 3ac1d74d2..fbab51fe8 100644
--- a/docs/sanity.config.ts
+++ b/docs/sanity.config.ts
@@ -8,7 +8,7 @@ import { visionTool } from "@sanity/vision";
import { defineConfig } from "sanity";
import { structure } from "./sanity/structure";
import { structureTool } from "sanity/structure";
-import { presentationTool, defineLocations } from "sanity/presentation";
+import { presentationTool, defineLocations, defineDocuments } from "sanity/presentation";
import * as changeCase from "change-case";
// Go to https://www.sanity.io/docs/api-versioning to learn how API versioning works
@@ -26,6 +26,10 @@ export default defineConfig({
structureTool({ structure }),
presentationTool({
resolve: {
+ // TODO: add design guidelines to mainDocuments
+ mainDocuments: defineDocuments([
+ { route: "/blog/:slug", filter: `_type == "blog" && slug.current == $slug` },
+ ]),
locations: {
contents: defineLocations({
select: {
From 3f065f2720ee2ce903edb100522c054200da24e4 Mon Sep 17 00:00:00 2001
From: malangcat
Date: Mon, 27 Jan 2025 00:06:18 +0900
Subject: [PATCH 6/6] feat: studio layout as server component
---
docs/app/(studio)/admin/page.tsx | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/docs/app/(studio)/admin/page.tsx b/docs/app/(studio)/admin/page.tsx
index 06351f8d9..a60ba1caa 100644
--- a/docs/app/(studio)/admin/page.tsx
+++ b/docs/app/(studio)/admin/page.tsx
@@ -1,5 +1,3 @@
-"use client";
-
/**
* This route is responsible for the built-in authoring environment using Sanity Studio.
* All routes under your studio path is handled by this file using Next.js' catch-all routes:
@@ -14,7 +12,7 @@ import config from "../../../sanity.config";
export const dynamic = "force-static";
-export { viewport } from "next-sanity/studio";
+export { viewport, metadata } from "next-sanity/studio";
export default function StudioPage() {
return ;