sgds-components
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSGDS Components Setup Skill
SGDS 组件设置指南
Prerequisites and framework integration for using web components.
<sgds-*>使用 Web组件的前提条件与框架集成方案。
<sgds-*>Installation
安装
bash
npm install @govtechsg/sgds-web-componentbash
npm install @govtechsg/sgds-web-componentor
or
pnpm add @govtechsg/sgds-web-component
Import the library once at your app entry point:
```js
import "@govtechsg/sgds-web-component";pnpm add @govtechsg/sgds-web-component
在应用入口处导入一次库文件:
```js
import "@govtechsg/sgds-web-component";Framework Integration
框架集成
React
React
React version determines which import to use.
React版本决定了导入方式。
React 19+ (client-side, e.g. Vite)
React 19+(客户端渲染,如Vite)
React 19 supports native custom elements directly — import once at the app entry point, then use the web component tag anywhere:
jsx
import "@govtechsg/sgds-web-component";
function App() {
return (
<sgds-button variant="primary" onsgds-blur={(e) => console.log(e)}>
Click Me
</sgds-button>
);
}Custom event syntax in React 19: prefix the event name with in lowercase ( → ).
onsgds-bluronsgds-blurUsing Next.js? Next.js is SSR-based and requires a different setup — see the Next.js section below.
Complex props (arrays, objects) can be passed declaratively:
jsx
import "@govtechsg/sgds-web-component";
const steps = [
{ component: <Step1 />, stepHeader: "Personal details" },
{ component: <Step2 />, stepHeader: "Contact details" },
];
function App() {
return <sgds-stepper steps={steps}></sgds-stepper>;
}React 19原生支持自定义元素——在应用入口处导入一次,即可在任意位置使用Web组件标签:
jsx
import "@govtechsg/sgds-web-component";
function App() {
return (
<sgds-button variant="primary" onsgds-blur={(e) => console.log(e)}>
Click Me
</sgds-button>
);
}React 19中的自定义事件语法:将事件名小写并添加前缀( → )。
onsgds-bluronsgds-blur使用Next.js? Next.js是基于SSR的框架,需要不同的设置——请查看下方的Next.js章节。
复杂属性(数组、对象)可通过声明式方式传递:
jsx
import "@govtechsg/sgds-web-component";
const steps = [
{ component: <Step1 />, stepHeader: "Personal details" },
{ component: <Step2 />, stepHeader: "Contact details" },
];
function App() {
return <sgds-stepper steps={steps}></sgds-stepper>;
}React 18 and below
React 18及以下版本
React ≤18 does not support custom element events or complex props natively. Use the React wrapper components:
jsx
import { SgdsButton } from "@govtechsg/sgds-web-component/react";
function App() {
return (
<SgdsButton variant="primary" onSgdsBlur={(e) => console.log(e)}>
Click Me
</SgdsButton>
);
}React wrapper event naming: → , → (prefix , camelCase applies to every hyphen-separated word).
sgds-bluronSgdsBlursgds-changeonSgdsChangeonAccessing component methods in React ≤18 (via ):
useReftsx
import { useRef } from "react";
import type { SgdsStepper as SStep } from "@govtechsg/sgds-web-component/components";
import SgdsStepper from "@govtechsg/sgds-web-component/react/stepper/index.js";
function StepperComponent() {
const stepperRef = useRef<SStep>(null);
return <SgdsStepper steps={steps} ref={stepperRef} />;
}Note: The React wrappers will be phased out in a future major version. Migrate to React 19+ native usage when possible.
React ≤18原生不支持自定义元素事件或复杂属性,请使用React包装组件:
jsx
import { SgdsButton } from "@govtechsg/sgds-web-component/react";
function App() {
return (
<SgdsButton variant="primary" onSgdsBlur={(e) => console.log(e)}>
Click Me
</SgdsButton>
);
}React包装组件的事件命名规则: → , → (添加前缀,连字符分隔的单词转为驼峰式)。
sgds-bluronSgdsBlursgds-changeonSgdsChangeon在React ≤18中访问组件方法(通过):
useReftsx
import { useRef } from "react";
import type { SgdsStepper as SStep } from "@govtechsg/sgds-web-component/components";
import SgdsStepper from "@govtechsg/sgds-web-component/react/stepper/index.js";
function StepperComponent() {
const stepperRef = useRef<SStep>(null);
return <SgdsStepper steps={steps} ref={stepperRef} />;
}注意:React包装组件将在未来的大版本中逐步淘汰。请尽可能迁移到React 19+的原生用法。
Next.js
Next.js
Next.js is an SSR framework — web components rely on browser APIs and will error if imported at the module level during server-side rendering.
Step 1 — Create (library loader)
sgds.tsxtsx
'use client';
import { useEffect } from 'react';
const SgdsLibraryLoader = () => {
useEffect(() => {
(async () => {
await import('@govtechsg/sgds-web-component');
})();
}, []);
return null;
};
export default SgdsLibraryLoader;Step 2 — Add to root layout
<head>tsx
// src/app/layout.tsx
import SgdsLibraryLoader from './sgds';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<SgdsLibraryLoader />
</head>
<body>
{children}
</body>
</html>
);
}Step 3 — Use components directly with
suppressHydrationWarningtsx
<sgds-masthead suppressHydrationWarning></sgds-masthead>Step 4 — TypeScript support — add a at the project root and reference the SGDS React type definitions. This gives full IntelliSense for props and typed detail payloads on all elements:
types.d.tsCustomEventsgds-*Use an ES import in any file included by your :
.d.tstsconfigts
import "@govtechsg/sgds-web-component/types/react";Events in Next.js — due to hydration timing, wire custom events via + rather than declarative React props:
useEffectaddEventListenertsx
'use client';
import { useEffect, useRef } from 'react';
export default function MyInput() {
const ref = useRef<any>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const handler = (e: Event) => console.log((e.target as any).value);
el.addEventListener('sgds-input', handler);
return () => el.removeEventListener('sgds-input', handler);
}, []);
return <sgds-input ref={ref} suppressHydrationWarning />;
}Organise into reusable React components — do not inline / alongside business logic. Wrap each SGDS element in a dedicated client component that exposes typed props and forwards events via callbacks:
useEffectaddEventListenertsx
// components/sgds/SgdsInput.tsx
'use client';
import { useEffect, useRef, useCallback } from 'react';
interface SgdsInputProps {
label?: string;
placeholder?: string;
value?: string;
onSgdsInput?: (value: string) => void;
onSgdsChange?: (value: string) => void;
}
export default function SgdsInput({ label, placeholder, value, onSgdsInput, onSgdsChange }: SgdsInputProps) {
const ref = useRef<any>(null);
const onSgdsInputRef = useRef(onSgdsInput);
const onSgdsChangeRef = useRef(onSgdsChange);
onSgdsInputRef.current = onSgdsInput;
onSgdsChangeRef.current = onSgdsChange;
useEffect(() => {
const el = ref.current;
if (!el) return;
const handleInput = (e: Event) => onSgdsInputRef.current?.((e.target as any).value);
const handleChange = (e: Event) => onSgdsChangeRef.current?.((e.target as any).value);
el.addEventListener('sgds-input', handleInput);
el.addEventListener('sgds-change', handleChange);
return () => {
el.removeEventListener('sgds-input', handleInput);
el.removeEventListener('sgds-change', handleChange);
};
}, []);
return (
<sgds-input
ref={ref}
label={label}
placeholder={placeholder}
value={value}
suppressHydrationWarning
/>
);
}Then consume it like any React component — no event wiring in the page:
tsx
// app/contact/page.tsx
'use client';
import SgdsInput from '@/components/sgds/SgdsInput';
export default function ContactPage() {
const [name, setName] = useState('');
return <SgdsInput label="Name" placeholder="Enter name" onSgdsInput={setName} />;
}Place all SGDS wrappers under a shared directory (e.g. ) so they are discoverable and reusable across pages.
components/sgds/See the official Next.js integration docs for more detail.
Next.js是SSR框架——Web组件依赖浏览器API,如果在服务器端渲染期间在模块级别导入会报错。
步骤1 — 创建(库加载器)
sgds.tsxtsx
'use client';
import { useEffect } from 'react';
const SgdsLibraryLoader = () => {
useEffect(() => {
(async () => {
await import('@govtechsg/sgds-web-component');
})();
}, []);
return null;
};
export default SgdsLibraryLoader;步骤2 — 添加到根布局的中
<head>tsx
// src/app/layout.tsx
import SgdsLibraryLoader from './sgds';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<SgdsLibraryLoader />
</head>
<body>
{children}
</body>
</html>
);
}步骤3 — 直接使用组件并添加
suppressHydrationWarningtsx
<sgds-masthead suppressHydrationWarning></sgds-masthead>步骤4 — TypeScript支持 — 在项目根目录添加文件,并引用SGDS React类型定义。这将为所有元素提供完整的智能提示,包括属性和带类型的详情负载:
types.d.tssgds-*CustomEvent在包含的任意文件中使用ES导入:
tsconfig.d.tsts
import "@govtechsg/sgds-web-component/types/react";Next.js中的事件处理 — 由于 hydration 时机问题,请通过 + 绑定自定义事件,而非声明式React属性:
useEffectaddEventListenertsx
'use client';
import { useEffect, useRef } from 'react';
export default function MyInput() {
const ref = useRef<any>(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const handler = (e: Event) => console.log((e.target as any).value);
el.addEventListener('sgds-input', handler);
return () => el.removeEventListener('sgds-input', handler);
}, []);
return <sgds-input ref={ref} suppressHydrationWarning />;
}组织为可复用React组件 — 不要在业务逻辑中内联 / 。将每个SGDS元素包装在专用的客户端组件中,暴露带类型的属性并通过回调转发事件:
useEffectaddEventListenertsx
// components/sgds/SgdsInput.tsx
'use client';
import { useEffect, useRef, useCallback } from 'react';
interface SgdsInputProps {
label?: string;
placeholder?: string;
value?: string;
onSgdsInput?: (value: string) => void;
onSgdsChange?: (value: string) => void;
}
export default function SgdsInput({ label, placeholder, value, onSgdsInput, onSgdsChange }: SgdsInputProps) {
const ref = useRef<any>(null);
const onSgdsInputRef = useRef(onSgdsInput);
const onSgdsChangeRef = useRef(onSgdsChange);
onSgdsInputRef.current = onSgdsInput;
onSgdsChangeRef.current = onSgdsChange;
useEffect(() => {
const el = ref.current;
if (!el) return;
const handleInput = (e: Event) => onSgdsInputRef.current?.((e.target as any).value);
const handleChange = (e: Event) => onSgdsChangeRef.current?.((e.target as any).value);
el.addEventListener('sgds-input', handleInput);
el.addEventListener('sgds-change', handleChange);
return () => {
el.removeEventListener('sgds-input', handleInput);
el.removeEventListener('sgds-change', handleChange);
};
}, []);
return (
<sgds-input
ref={ref}
label={label}
placeholder={placeholder}
value={value}
suppressHydrationWarning
/>
);
}然后像使用普通React组件一样使用它——页面中无需手动绑定事件:
tsx
// app/contact/page.tsx
'use client';
import SgdsInput from '@/components/sgds/SgdsInput';
export default function ContactPage() {
const [name, setName] = useState('');
return <SgdsInput label="Name" placeholder="Enter name" onSgdsInput={setName} />;
}将所有SGDS包装组件放在共享目录下(如),以便在各页面中方便查找和复用。
components/sgds/更多细节请查看官方Next.js集成文档。
Vue
Vue
Vue 3 supports web components natively — no SGDS-specific wrappers exist. Refer to the Vue + web components documentation for configuration. The SGDS-specific filter for suppressing unknown element warnings is .
tag.startsWith("sgds-")Vue 3原生支持Web组件——不存在SGDS专用包装组件。请参考Vue + Web组件文档进行配置。用于抑制未知元素警告的SGDS特定过滤器为。
tag.startsWith("sgds-")Angular
Angular
Angular supports web components natively via — no SGDS-specific wrappers exist. Refer to the Angular elements documentation for configuration.
CUSTOM_ELEMENTS_SCHEMAAngular通过原生支持Web组件——不存在SGDS专用包装组件。请参考Angular元素文档进行配置。
CUSTOM_ELEMENTS_SCHEMATroubleshooting Component Behaviour
组件行为故障排查
When a component behaves unexpectedly — wrong event fired, property not reflected, slot not rendering — read the compiled source directly. It contains full method bodies, event logic, internal defaults, and edge-case handling that no documentation captures.
Read from — this directory is present once the package is installed:
node_modules/@govtechsg/sgds-web-componentnode_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion.js
node_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion-item.js
node_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion.d.tsReplace with the relevant component folder and file name. The file contains the full implementation; the file lists all properties, types, events, slots, and JSDoc descriptions.
Accordion/sgds-accordion.js.d.tsIf is absent — the package has not been installed. Ask the user to run their normal install step ( / ) before inspecting source files.
node_modulesnpm installpnpm installFor AI agents: The primary decision tree is React version + rendering mode:
- React 19+ CSR (Vite etc.): native tag + direct import, event props lowercase with
<sgds-*>prefix (on)onsgds-change - Next.js (SSR): +
SgdsLibraryLoaderdynamic import — never a top-level import; wire events viauseEffectinaddEventListeneruseEffect - React ≤18: SGDS React wrapper package, camelCase event props ()
onSgdsChange - Vue / Angular: standard web component integration; SGDS-specific detail for Vue is to suppress unknown element warnings
tag.startsWith("sgds-")
When a user reports unexpected component behaviour (wrong event, property not reflecting, slot not rendering), direct them to read the compiled source before trying anything else — see the Troubleshooting Component Behaviour section above.
Global rule — never set explicit widths on SGDS components. Do not add , , or fixed-width utility classes (e.g. ) directly on any element. Width is controlled by the parent layout — use flex, grid, or wrapper divs to constrain it. The only exception is when a user explicitly requests a fixed width.
widthstyle="width: ..."sgds:w-40<sgds-*>当组件行为异常时(如事件触发错误、属性未同步、插槽未渲染),请直接查看编译后的源代码。其中包含完整的方法体、事件逻辑、内部默认值和边缘情况处理,这些内容在文档中并未完全体现。
查看目录——安装包后该目录即存在:
node_modules/@govtechsg/sgds-web-componentnode_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion.js
node_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion-item.js
node_modules/@govtechsg/sgds-web-component/components/Accordion/sgds-accordion.d.ts将替换为对应组件的文件夹和文件名。文件包含完整实现;文件列出了所有属性、类型、事件、插槽和JSDoc描述。
Accordion/sgds-accordion.js.d.ts如果不存在——说明包未安装。请告知用户先执行常规安装步骤( / ),再检查源文件。
node_modulesnpm installpnpm installAI代理参考决策树:主要依据React版本和渲染模式:
- React 19+ CSR(如Vite):原生标签 + 直接导入,事件属性为小写并添加
<sgds-*>前缀(on)onsgds-change - Next.js(SSR):+
SgdsLibraryLoader动态导入——切勿使用顶层导入;通过useEffect中的useEffect绑定事件addEventListener - React ≤18:使用SGDS React包装包,事件属性为驼峰式()
onSgdsChange - Vue / Angular:标准Web组件集成;Vue的SGDS特定细节是使用抑制未知元素警告
tag.startsWith("sgds-")
当用户反馈组件行为异常(如事件错误、属性未同步、插槽未渲染)时,先引导他们查看编译后的源代码——请参考上方组件行为故障排查章节。
全局规则——切勿为SGDS组件设置显式宽度。不要直接在任何元素上添加、或固定宽度工具类(如)。宽度由父级布局控制——使用flex、grid或包装div来约束宽度。唯一例外是用户明确要求固定宽度。
<sgds-*>widthstyle="width: ..."sgds:w-40Available Components
可用组件
| Category | Component | Reference |
|---|---|---|
| Actions | Button | → reference/button.md |
| Actions | Icon Button | → reference/icon-button.md |
| Actions | Close Button | → reference/close-button.md |
| Actions | Link | → reference/link.md |
| Actions | Dropdown | → reference/dropdown.md |
| Actions | Overflow Menu | → reference/overflow-menu.md |
| Navigation | Masthead | → reference/masthead.md |
| Navigation | Main Nav | → reference/mainnav.md |
| Navigation | Footer | → reference/footer.md |
| Navigation | Breadcrumb | → reference/breadcrumb.md |
| Navigation | Pagination | → reference/pagination.md |
| Navigation | Sidenav | → reference/sidenav.md |
| Navigation | Sidebar | → reference/sidebar.md |
| Navigation | Subnav | → reference/subnav.md |
| Navigation | Tab | → reference/tab.md |
| Navigation | Table of Contents | → reference/table-of-contents.md |
| Layout | Accordion | → reference/accordion.md |
| Layout | Divider | → reference/divider.md |
| Layout | Drawer | → reference/drawer.md |
| Layout | Modal | → reference/modal.md |
| Content | Badge | → reference/badge.md |
| Content | Card | → reference/card.md |
| Content | Icon Card | → reference/icon-card.md |
| Content | Image Card | → reference/image-card.md |
| Content | Thumbnail Card | → reference/thumbnail-card.md |
| Content | Description List | → reference/description-list.md |
| Content | Icon | → reference/icon.md |
| Content | Icon List | → reference/icon-list.md |
| Content | Table | → reference/table.md |
| Content | Tooltip | → reference/tooltip.md |
| Forms | Input | → reference/input.md |
| Forms | Textarea | → reference/textarea.md |
| Forms | Select | → reference/select.md |
| Forms | Checkbox | → reference/checkbox.md |
| Forms | Radio | → reference/radio.md |
| Forms | Combo Box | → reference/combo-box.md |
| Forms | Datepicker | → reference/datepicker.md |
| Forms | File Upload | → reference/file-upload.md |
| Forms | Quantity Toggle | → reference/quantity-toggle.md |
| Feedback | Switch | → reference/switch.md |
| Workflow | Stepper | → reference/stepper.md |
| 分类 | 组件 | 参考文档 |
|---|---|---|
| 操作组件 | Button | → reference/button.md |
| 操作组件 | Icon Button | → reference/icon-button.md |
| 操作组件 | Close Button | → reference/close-button.md |
| 操作组件 | Link | → reference/link.md |
| 操作组件 | Dropdown | → reference/dropdown.md |
| 操作组件 | Overflow Menu | → reference/overflow-menu.md |
| 导航组件 | Masthead | → reference/masthead.md |
| 导航组件 | Main Nav | → reference/mainnav.md |
| 导航组件 | Footer | → reference/footer.md |
| 导航组件 | Breadcrumb | → reference/breadcrumb.md |
| 导航组件 | Pagination | → reference/pagination.md |
| 导航组件 | Sidenav | → reference/sidenav.md |
| 导航组件 | Sidebar | → reference/sidebar.md |
| 导航组件 | Subnav | → reference/subnav.md |
| 导航组件 | Tab | → reference/tab.md |
| 导航组件 | Table of Contents | → reference/table-of-contents.md |
| 布局组件 | Accordion | → reference/accordion.md |
| 布局组件 | Divider | → reference/divider.md |
| 布局组件 | Drawer | → reference/drawer.md |
| 布局组件 | Modal | → reference/modal.md |
| 内容组件 | Badge | → reference/badge.md |
| 内容组件 | Card | → reference/card.md |
| 内容组件 | Icon Card | → reference/icon-card.md |
| 内容组件 | Image Card | → reference/image-card.md |
| 内容组件 | Thumbnail Card | → reference/thumbnail-card.md |
| 内容组件 | Description List | → reference/description-list.md |
| 内容组件 | Icon | → reference/icon.md |
| 内容组件 | Icon List | → reference/icon-list.md |
| 内容组件 | Table | → reference/table.md |
| 内容组件 | Tooltip | → reference/tooltip.md |
| 表单组件 | Input | → reference/input.md |
| 表单组件 | Textarea | → reference/textarea.md |
| 表单组件 | Select | → reference/select.md |
| 表单组件 | Checkbox | → reference/checkbox.md |
| 表单组件 | Radio | → reference/radio.md |
| 表单组件 | Combo Box | → reference/combo-box.md |
| 表单组件 | Datepicker | → reference/datepicker.md |
| 表单组件 | File Upload | → reference/file-upload.md |
| 表单组件 | Quantity Toggle | → reference/quantity-toggle.md |
| 反馈组件 | Switch | → reference/switch.md |
| 工作流组件 | Stepper | → reference/stepper.md |
Form Input Components
表单输入组件
When building forms, use these 9 form input components to capture user data:
- — text fields
<sgds-input> - — multi-line text
<sgds-textarea> - — dropdown selection
<sgds-select> - /
<sgds-checkbox>— multiple choice<sgds-checkbox-group> - /
<sgds-radio>— single choice<sgds-radio-group> - — searchable select
<sgds-combo-box> - — date input
<sgds-datepicker> - — file picker
<sgds-file-upload> - — numeric counter
<sgds-quantity-toggle>
DO NOT use in forms (these are feedback/state, not input):
- — This is a feedback component (displays toggle state), not a form input. Use
<sgds-switch>or<sgds-checkbox>to collect user choice instead.<sgds-radio-group> - Other non-input components (Alert, Badge, Button, Card, etc.) — These are layout/feedback, not form controls.
For form layout patterns (field pairing, spacing, width constraints, multi-step forms with , header hierarchy), see the sgds-blocks form layout skill.
| Feedback | Alert | → reference/alert.md |
| Feedback | Spinner | → reference/spinner.md |
| Feedback | Skeleton | → reference/skeleton.md |
| Feedback | Progress Bar | → reference/progress-bar.md |
| Feedback | Toast | → reference/toast.md |
| Feedback | System Banner | → reference/system-banner.md |
<sgds-stepper>构建表单时,使用以下9种表单输入组件收集用户数据:
- — 文本字段
<sgds-input> - — 多行文本
<sgds-textarea> - — 下拉选择
<sgds-select> - /
<sgds-checkbox>— 多选<sgds-checkbox-group> - /
<sgds-radio>— 单选<sgds-radio-group> - — 可搜索选择器
<sgds-combo-box> - — 日期输入
<sgds-datepicker> - — 文件选择器
<sgds-file-upload> - — 数字计数器
<sgds-quantity-toggle>
请勿在表单中使用以下组件(这些是反馈/状态组件,而非输入组件):
- — 这是一个反馈组件(显示切换状态),而非表单输入。请使用
<sgds-switch>或<sgds-checkbox>收集用户选择。<sgds-radio-group> - 其他非输入组件(Alert、Badge、Button、Card等)——这些是布局/反馈组件,而非表单控件。
关于表单布局模式(字段配对、间距、宽度约束、结合的多步骤表单、标题层级),请查看sgds-blocks表单布局技能文档。
| 反馈组件 | Alert | → reference/alert.md |
| 反馈组件 | Spinner | → reference/spinner.md |
| 反馈组件 | Skeleton | → reference/skeleton.md |
| 反馈组件 | Progress Bar | → reference/progress-bar.md |
| 反馈组件 | Toast | → reference/toast.md |
| 反馈组件 | System Banner | → reference/system-banner.md |
<sgds-stepper>