UIKit · React 组件库

@imcore/uikit 是构建在 @imcore/sdk 之上的 React 聊天 UI 组件库:会话列表、消息流、输入框、连接状态横幅,开箱即用。所有 edition 均包含。

安装

npm i <下载的 @imcore/uikit .tgz 链接或文>
# 同时需要 SDK 与 React
npm i <下载的 @imcore/sdk .tgz>

30 行接入

import { ImcoreClient } from '@imcore/sdk';
import { ImcoreProvider, ConversationList, MessageList, Composer, ConnectionBanner } from '@imcore/uikit';
import '@imcore/uikit/theme.css';
import { useState } from 'react';

const client = new ImcoreClient({ url: 'wss://your-imcore-host/acc', auth: { token: YOUR_TOKEN } });
void client.connect();

export default function App() {
  const [peer, setPeer] = useState<string | null>(null);
  return (
    <ImcoreProvider client={client} ownUserID={MY_USER_ID}>
      <ConnectionBanner />
      <div style={{ display: 'flex', height: '100vh' }}>
        <div style={{ width: 320, borderRight: '1px solid #eee' }}>
          <ConversationList onSelect={(c) => setPeer(c.targetUserID ?? null)} />
        </div>
        {peer && (
          <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
            <MessageList target={{ scene: 'dm', targetUserID: peer }} />
            <Composer target={{ scene: 'dm', targetUserID: peer }} />
          </div>
        )}
      </div>
    </ImcoreProvider>
  );
}

换肤

每个颜色都读取 CSS 变量(--imcore-*,以及与 chat-studio 皮肤共用的 --bubble-own-bg / --bubble-own-ink / --bubble-other-bg / --bubble-other-ink)。在 :root 上重定义即可整体换肤。

Headless hooks

不想用现成组件的宿主,可直接基于无 UI 的 hooks 自建界面:useConnectionState / useConversations / useMessages

Flutter

imcore_uikit 是构建在 imcore_sdk(Dart/Flutter SDK)之上的 Flutter 聊天 UI 组件库:会话列表、消息流、输入框,与 Web 版共享同一套组件契约与主题令牌。所有 edition 均包含。

安装

解压后与 SDK 作为兄弟目录摆放(imcore_uikit 通过相对路径依赖 ../imcore_sdk):

your-project/
  packages/
    imcore_sdk/
    imcore_uikit/
dependencies:
  imcore_uikit:
    path: packages/imcore_uikit

Quickstart

import 'package:flutter/material.dart';
import 'package:imcore_sdk/imcore_sdk.dart';
import 'package:imcore_uikit/imcore_uikit.dart';

final client = ImcoreClient(
  url: 'wss://your-imcore-host/acc',
  auth: AuthConfig(token: yourToken, login: LoginPayload(userId: myUserId)),
)..connect();

class ChatPage extends StatelessWidget {
  const ChatPage({super.key});

  @override
  Widget build(BuildContext context) {
    return ImcoreScope(
      client: client,
      ownUserId: myUserId,
      child: Column(children: [
        const ConnectionBanner(),
        Expanded(
          child: ConversationListView(
            onSelect: (c) => Navigator.push(context, MaterialPageRoute(
              builder: (_) => ThreadPage(peer: c.wire.targetUserID!),
            )),
          ),
        ),
      ]),
    );
  }
}

class ThreadPage extends StatelessWidget {
  const ThreadPage({super.key, required this.peer});
  final String peer;

  @override
  Widget build(BuildContext context) {
    return ImcoreScope(
      client: client,
      ownUserId: myUserId,
      child: Scaffold(
        appBar: AppBar(title: Text(peer)),
        body: Column(children: [
          Expanded(child: MessageListView(target: DmTarget(peer))),
          ImcoreComposer(target: DmTarget(peer)),
        ]),
      ),
    );
  }
}

换肤

ThemeData.extensions 中加入 ImcoreTheme.light().copyWith(...)——bubbleOwnBg / bubbleOwnInk / bubbleOtherBg / bubbleOtherInk 令牌名与 Web UIKit 共用。想自建界面的宿主可跳过组件,直接基于无 UI 的 controller:ConnectionStateNotifier / ConversationsController / MessagesController