@alga-psa/ui-kit

中文文档
0.2.0发布于 2026/02/25TypeScriptES Module近 30 天下载 1.9万

Zero-dependency React component library for Alga extensions. All components use CSS custom properties for theming and work seamlessly inside extension iframes.

原始使用文档
文档目录13 节
  1. Install
  2. Theme Tokens
  3. Components
  4. Core
  5. Form
  6. Data Display
  7. Navigation
  8. Layout
  9. Feedback
  10. Hooks
  11. useTheme()
  12. applyThemeVars(vars)
  13. Extension Theme Bridge

@alga-psa/ui-kit

Zero-dependency React component library for Alga extensions. All components use CSS custom properties for theming and work seamlessly inside extension iframes.

See the showcase extension (ee/extensions/showcase) for interactive demos of every component.

Install

Import the theme stylesheet once at the root of your app:

import '@alga-psa/ui-kit/theme.css';

Theme Tokens

Tokens are exposed as CSS variables. When running inside an extension iframe the host automatically injects them into :root.

VariableLightDarkPurpose
--alga-bg#ffffff#0b0f14Background
--alga-fg#111111#e5e7ebForeground / text
--alga-muted#f5f5f7#0f1720Muted background
--alga-muted-fg#4b5563#9ca3afMuted text
--alga-primary#9855ee#8a4deaPrimary (purple)
--alga-primary-foreground#ffffff#ffffffText on primary
--alga-secondary#53d7fa#40cff9Secondary (blue)
--alga-secondary-foreground#111111#0b0f14Text on secondary
--alga-border#e5e7eb#1f2937Borders
--alga-radius8px8pxBorder radius
--alga-danger#dc2626#ef4444Danger / error
--alga-warning#d97706#f59e0bWarning
--alga-success#16a34a#22c55eSuccess

You can also access tokens programmatically:

import { tokens } from '@alga-psa/ui-kit';

tokens.primary   // 'var(--alga-primary)'
tokens.bg        // 'var(--alga-bg)'

Components

Core

Button

Themed button with multiple variants and sizes.

PropTypeDefaultDescription
variant'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link' | 'soft' | 'dashed''primary'Visual style
size'xs' | 'sm' | 'md' | 'lg' | 'icon''md'Controls padding and font size
<Button variant="secondary" size="sm">Save</Button>

Text

Typography component with size, tone, and weight presets.

PropTypeDefaultDescription
as'span' | 'p' | 'label' | 'strong''span'HTML element to render
size'xs' | 'sm' | 'md' | 'lg''md'Font size preset
tone'default' | 'muted' | 'danger' | 'warning' | 'success''default'Text colour
weight400 | 500 | 600 | 700400Font weight
<Text as="p" size="lg" tone="muted" weight={600}>Hello</Text>

Card

Bordered container with background, shadow, and rounded corners. Extends standard <div> attributes.

<Card style={{ padding: 24 }}>Content here</Card>

Badge

Small pill-shaped label for status indicators.

PropTypeDefaultDescription
tone'default' | 'info' | 'success' | 'warning' | 'danger''default'Colour scheme
<Badge tone="success">Active</Badge>

Alert, AlertTitle, AlertDescription

Contextual alert banner with optional icon.

PropTypeDefaultDescription
tone'info' | 'success' | 'warning' | 'danger''info'Visual tone
showIconbooleantrueShow tone-specific icon
<Alert tone="warning">
  <AlertTitle>Heads up</AlertTitle>
  <AlertDescription>This action cannot be undone.</AlertDescription>
</Alert>

Separator

Thin divider line for separating content.

PropTypeDefaultDescription
orientation'horizontal' | 'vertical''horizontal'Direction of the line
styleCSSProperties—Additional inline styles

Form

Input

Text input with error state support.

PropTypeDefaultDescription
errorboolean—Show error styling
errorMessagestring—Error message displayed below input
<Input placeholder="Email" error={!!err} errorMessage={err} />

TextArea

Multi-line text input. Extends <textarea> attributes.

PropTypeDefaultDescription
errorboolean—Show error border
errorMessagestring—Error text below the field
resize'none' | 'vertical' | 'horizontal' | 'both''vertical'Resize behaviour

CustomSelect

Dropdown with search filtering.

PropTypeDefaultDescription
optionsSelectOption[]—Available options
valuestring—Selected value
onChange(value: string) => void—Change callback
placeholderstring—Placeholder text
searchablebooleantrueEnable search filtering
disabledbooleanfalseDisable the select

SearchInput

Input with built-in search icon and optional debounce.

PropTypeDefaultDescription
onSearch(value: string) => void—Debounced search callback
debounceMsnumber300Debounce delay in ms
size'sm' | 'md''md'Input size

Checkbox

Themed checkbox with label.

PropTypeDefaultDescription
labelstring—Label text
size'sm' | 'md' | 'lg''md'Size preset

RadioGroup

Group of mutually exclusive radio buttons.

PropTypeDefaultDescription
optionsRadioOption[]—Available options
valuestring—Selected value
onChange(value: string) => void—Change callback
namestringautoHTML name attribute
disabledbooleanfalseDisable all options
orientation'horizontal' | 'vertical''vertical'Layout direction
size'sm' | 'md' | 'lg''md'Size preset

RadioOption: { value: string; label: string; disabled?: boolean }

<RadioGroup
  options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]}
  value={selected}
  onChange={setSelected}
/>

Switch

Toggle switch for boolean values.

PropTypeDefaultDescription
checkedboolean—Controlled state
onChange(checked: boolean) => void—Change callback
size'sm' | 'md' | 'lg''md'Size preset
disabledbooleanfalseDisable the switch
labelstring—Label text

Label

Styled <label> element.

PropTypeDefaultDescription
requiredboolean—Show required indicator
disabledboolean—Apply muted styling

Data Display

DataTable

Paginated table with sorting, search, and custom cell rendering.

PropTypeDefaultDescription
dataRow[]—Array of row objects
columnsColumn<Row>[]—Column definitions
initialSortKeystring—Initial sort column
searchablebooleanfalseShow search input
pageSizenumber10Rows per page

Column<Row>: { key: string; header: string; width?: number; sortable?: boolean; render?: (row) => ReactNode }

<DataTable
  data={items}
  columns={[
    { key: 'name', header: 'Name', sortable: true },
    { key: 'status', header: 'Status', render: (row) => <Badge>{row.status}</Badge> },
  ]}
/>

Navigation

Tabs

Horizontal tab bar.

PropTypeDefaultDescription
tabsTabItem[]—Tab definitions
activeTabstring—Currently active tab id
onChange(id: string) => void—Tab change callback

TabItem: { id: string; label: string; icon?: ComponentType; disabled?: boolean }

<Tabs
  tabs={[{ id: 'one', label: 'Tab 1' }, { id: 'two', label: 'Tab 2' }]}
  activeTab={tab}
  onChange={setTab}
/>

ViewSwitcher

Segmented button group for switching between views.

PropTypeDefaultDescription
currentViewT—Active view value
onChange(view: T) => void—View change callback
optionsViewSwitcherOption<T>[]—Available views

ViewSwitcherOption<T>: { value: T; label: string; icon?: ComponentType }

<ViewSwitcher
  currentView={view}
  onChange={setView}
  options={[{ value: 'list', label: 'List' }, { value: 'grid', label: 'Grid' }]}
/>

Breadcrumbs

Horizontal breadcrumb navigation trail.

PropTypeDefaultDescription
itemsBreadcrumbItem[]—Breadcrumb segments
separatorReactNode'/'Custom separator

BreadcrumbItem: { label: ReactNode; href?: string; onClick?: () => void }

<Breadcrumbs items={[
  { label: 'Home', href: '/' },
  { label: 'Settings', onClick: goSettings },
  { label: 'Profile' },
]} />

DropdownMenu

Popover menu triggered by a button.

PropTypeDefaultDescription
triggerReactNode—Trigger element
itemsDropdownMenuItem[]—Menu items

DropdownMenuItem: { label: string; onClick?: () => void; icon?: ComponentType; danger?: boolean; disabled?: boolean; separator?: boolean }


Layout

Stack

Flexbox layout helper for stacking children with consistent spacing.

PropTypeDefaultDescription
direction'row' | 'column''column'Flex direction
gapnumber | string8Gap between children (numbers = px)
align'stretch' | 'flex-start' | 'center' | 'flex-end' | 'baseline'—Cross-axis alignment
justify'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'—Main-axis alignment
<Stack direction="row" gap={12} align="center">
  <Text>Left</Text>
  <Button>Right</Button>
</Stack>

Drawer

Slide-in panel from the right edge with focus trapping and overlay.

PropTypeDefaultDescription
openboolean—Whether the drawer is open
onClose() => void—Close callback
widthstring'fit-content'CSS width
maxWidthstring'60vw'Max width
titleReactNode—Drawer title
overlaybooleantrueShow backdrop overlay
closeOnOverlayClickbooleantrueClose on overlay click
closeOnEscapebooleantrueClose on Escape key

Dialog / ConfirmDialog

Modal dialogs.

Dialog — base modal with title and children.

PropTypeDefaultDescription
isOpenboolean—Open state
onClose() => void—Close callback
titlestring—Dialog title

ConfirmDialog — confirm / cancel modal.

PropTypeDefaultDescription
isOpenboolean—Open state
titlestring—Title
messagestring—Body text
variant'default' | 'danger''default'Visual tone
onConfirm() => void—Confirm callback
onCancel() => void—Cancel callback
<ConfirmDialog
  isOpen={open}
  title="Delete Item"
  message="Are you sure?"
  variant="danger"
  onConfirm={handleDelete}
  onCancel={() => setOpen(false)}
/>

Popover

Positioned content popover anchored to a trigger element.

PropTypeDefaultDescription
triggerReactNode—Trigger element
openboolean—Controlled open state
onOpenChange(open: boolean) => void—Open state callback
placement'top' | 'bottom' | 'left' | 'right''bottom'Popover placement

Feedback

Spinner / LoadingIndicator

Spinner — animated circular loading indicator.

PropTypeDefaultDescription
size'button' | 'xs' | 'sm' | 'md' | 'lg''md'Diameter preset
variant'default' | 'inverted''default'Use 'inverted' on coloured backgrounds

LoadingIndicator — spinner with optional text.

PropTypeDefaultDescription
sizesame as Spinner'md'Spinner size
textstring—Label next to spinner
layout'inline' | 'stacked''inline'Text position
<Spinner size="sm" />
<LoadingIndicator text="Loading..." layout="stacked" />

Tooltip

Hover tooltip anchored to its children.

PropTypeDefaultDescription
contentReactNode—Tooltip content
placement'top' | 'bottom' | 'left' | 'right''top'Position
delaynumber200Show delay in ms
<Tooltip content="More info">
  <Button variant="ghost">?</Button>
</Tooltip>

Progress

Horizontal progress bar.

PropTypeDefaultDescription
valuenumber—Current value (0–100)
maxnumber100Maximum value
size'sm' | 'md' | 'lg''md'Bar height
tone'primary' | 'success' | 'warning' | 'danger''primary'Bar colour
<Progress value={75} tone="success" />

Skeleton / SkeletonText / SkeletonCircle / SkeletonRectangle

Placeholder loading shapes.

PropTypeDefaultDescription
widthstring | number'100%'Width
heightstring | number'1em'Height
variant'text' | 'circular' | 'rectangular''text'Shape
animation'pulse' | 'wave' | 'none''pulse'Animation type
linesnumber3Number of lines (text variant)
<SkeletonText lines={3} />
<SkeletonCircle width={40} height={40} />

Hooks

useTheme()

Returns { setMode, getMode } for reading and setting the current theme mode ('light' | 'dark').

import { useTheme } from '@alga-psa/ui-kit';

const { setMode, getMode } = useTheme();
setMode('dark');

applyThemeVars(vars)

Applies a Record<string, string> of CSS custom property values to the document root.

import { applyThemeVars } from '@alga-psa/ui-kit';

applyThemeVars({ 'alga-primary': '#ff6600' });

Extension Theme Bridge

For extensions running in iframes, use the built-in theme bridge to receive host theme variables:

import { applyThemeVars } from '@alga-psa/ui-kit';

window.addEventListener('message', (ev) => {
  const data = ev.data;
  if (data?.alga === true && data?.version === '1' && data?.type === 'theme') {
    applyThemeVars(data.payload || {});
  }
});

// Signal readiness to the host
window.parent.postMessage({ alga: true, version: '1', type: 'ready' }, '*');

版本与发布记录

@alga-psa/ui-kit 共发布 2 个版本,首次发布于 2025/09/02;过去 12 个月发布了 1 个版本。

版本发布日期距今
0.2.0latest2026/02/258 个月前
0.1.02025/09/021.2 年前

关于 @alga-psa/ui-kit 的常见问题

@alga-psa/ui-kit 是什么?

Zero-dependency React component library for Alga extensions. All components use CSS custom properties for theming and work seamlessly inside extension iframes.

如何安装 @alga-psa/ui-kit?

在项目目录运行 npm install @alga-psa/ui-kit,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18 || ^19)、react-dom(^18 || ^19)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@alga-psa/ui-kit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alga-psa/ui-kit 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@alga-psa/ui-kit 可以商用吗?

@alga-psa/ui-kit 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@alga-psa/ui-kit 的下载量有多少?

根据 npm 官方下载统计,@alga-psa/ui-kit 在 2026/10/06 – 2026/11/04 这 30 天内被下载 18,673 次,日均约 622 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@alga-psa/ui-kit 还在维护吗?

最新版本 0.2.0 发布于 2026/02/25(8 个月前);至今共发布 2 个版本,其中过去 12 个月发布了 1 个;首次发布于 2025/09/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。