其他

全局配置

为组件提供统一的全局化配置。

使用场景

覆盖配置分为两种场景

  • 需要覆盖多个组件公有 Props 配置(例如 timezone、rtl),使用 ConfigProvider
  • 当 ConfigProvider 暴露参数未能满足,希望修改全局修改某个组件的 某类 Props(例如期望将所有Button的 theme 都配置为 solid 或所有 Popover的 position),使用 semiGlobal

ConfigProvider

ConfigProvider 借助 Svelte context 实现,因此它能影响组件树中的子组件。ConfigProvider 与 ConfigConsumer 不渲染自己的元素(方向切换时才会多包一层带 dir 属性的 div),未声明的属性会被丢弃,不会落到 DOM 上。

代码演示

如何引入

<script lang="ts">
    import { ConfigProvider, ConfigConsumer, useConfig } from '@fibrae/semi-ui-svelte';
</script>

基本用法

通过传入 timeZone 参数,用户可以为时间类组件配置时区:

Select Time Zone:




代码
<script lang="ts">
    import { ConfigProvider, DatePicker, Select, TimePicker } from '@fibrae/semi-ui-svelte';

    let timeZone = $state('GMT+08:00');
    const defaultTimestamp = 1581599305265;
    const gmtList: string[] = [];
    for (let hourOffset = -11; hourOffset <= 14; hourOffset++) {
        const prefix = hourOffset >= 0 ? '+' : '-';
        gmtList.push(`GMT${prefix}${String(Math.abs(hourOffset)).padStart(2, '0')}:00`);
    }
    // fractional offsets stay fixed all year; an IANA name follows its daylight saving time
    gmtList.push('GMT-03:30', 'GMT+05:45', 'GMT+13:45', 'America/New_York');
    const optionList = gmtList.map((gmt) => ({ value: gmt, label: gmt }));

    const onChange = (date: unknown, dateString: string | string[]) => console.log('changed: ', date, dateString);
</script>

<ConfigProvider {timeZone}>
    <div style="width: 300px">
        <h5 style="margin: 10px">Select Time Zone:</h5>
        <Select aria-label="时区" onSelect={(value) => (timeZone = String(value))} {optionList} placeholder="请选择时区" showClear style="width: 300px" value={timeZone} />
        <br />
        <br />
        <DatePicker {onChange} type="dateTime" value={defaultTimestamp} />
        <br />
        <br />
        <TimePicker {onChange} value={defaultTimestamp} />
    </div>
</ConfigProvider>

手动获取值

通常情况下,组件内部会自动获取 ConfigProvider 的值自动消费,无需关心。但是一些特殊场景,你可能需要手动获取值来进行其他操作。

使用 ConfigConsumer 的 children snippet 获取 ConfigProvider 的值,参数是当前生效的配置;在子组件初始化时也可以调用 useConfig(),它返回同一个配置对象,没有 ConfigProvider 时为空对象。配置对象的字段是读取时才计算的 getter,读取字段时写作 config.xxx,不要解构后长期持有,否则不会跟随变化。

{"direction":"ltr","timeZone":"GMT+08:00","responsiveObserve":false,"responsiveMap":{"xs":"(max-width: 575px)","sm":"(min-width: 576px)","md":"(min-width: 768px)","lg":"(min-width: 992px)","xl":"(min-width: 1200px)","xxl":"(min-width: 1600px)"},"screens":{"xs":false,"sm":false,"md":false,"lg":false,"xl":false,"xxl":false}}
代码
<script lang="ts">
    import { ConfigConsumer, ConfigProvider, TypographyText } from '@fibrae/semi-ui-svelte';
</script>

<ConfigProvider timeZone="GMT+08:00">
    <ConfigConsumer>
        {#snippet children(value)}
            <TypographyText ellipsis={{ showTooltip: { opts: { style: 'min-width: 1200px' } } }} style="width: 600px">
                {JSON.stringify(value)}
            </TypographyText>
        {/snippet}
    </ConfigConsumer>
</ConfigProvider>

响应式断点监听

ConfigProvider 支持配置响应式断点,并在断点变化时进行订阅回调。

开启监听与自定义断点

  • 通过 responsiveObserve 开启断点监听(建议只在确实需要订阅的场景开启)
  • 通过 responsiveMap 自定义断点(未传入时使用默认断点)
<!-- breakpoint-subscriber.svelte -->
<script lang="ts">
    import { onMount } from 'svelte';
    import { TypographyText, useConfig } from '@fibrae/semi-ui-svelte';

    const config = useConfig();
    let screens = $state(config.screens);

    onMount(() => config.onBreakpoint?.((next) => (screens = next)));
</script>

<TypographyText>{JSON.stringify(screens)}</TypographyText>
<script lang="ts">
    import { ConfigProvider } from '@fibrae/semi-ui-svelte';
    import BreakpointSubscriber from './breakpoint-subscriber.svelte';

    const responsiveMap = {
        xs: '(max-width: 575px)',
        sm: '(min-width: 576px)',
        md: '(min-width: 768px)',
        lg: '(min-width: 992px)',
        xl: '(min-width: 1200px)',
        xxl: '(min-width: 1600px)',
    };
</script>

<ConfigProvider responsiveObserve {responsiveMap}>
    <BreakpointSubscriber />
</ConfigProvider>

订阅 API

onBreakpoint 支持两种签名,均会返回取消订阅函数:

  • onBreakpoint((screens) => void):回调拿到完整的 screens 映射
  • onBreakpoint(['md', 'lg'], (screen, match) => void):只监听指定断点,回调拿到单个断点变化

RTL/LTR

全局配置 direction 可以改变组件的文本方向。

rtl 表示从右到左 (类似希伯来语或阿拉伯语), ltr 表示从左到右 (类似中文、英语等大部分语言)。显式传入的 direction 与外层不同时(含最外层),ConfigProvider 会在内容外包一层带 dir 属性的 div。组件的 RTL 样式用 :dir(rtl) 匹配,跟随最近的祖先 dir 属性;弹层根元素按 ConfigProvider 的 direction 输出 dir。页面自己在 <html> 等元素上设置 dir="rtl" 时,页面内的组件样式按 RTL 显示,但键盘方向、弹层位置等逻辑只读 ConfigProvider 的 direction,ConfigProvider 内的弹层与 Table 也按它的 direction(默认 ltr)显示,因此仍需同时设置 direction="rtl"。

特殊组件:

  • Modal,Notification,Toast 的命令式调用需要通过 prop 传 direction。
  • 如果你想对有方向性的 Icon 做 RTL 国际化,需要自己单独进行处理。我们认为对 Icon 进行 RTL 会让它变得难以理解和维护。其他组件内的 icon Semi 已经做了 RTL 适配。
  • Table 的树形数据暂不支持 RTL(Chrome、Safari 浏览器表现与 Firefox 表现不同),固定列支持 RTL。

命令式调用(Modal.success()、Toast.info()、Notification.info() 等)渲染在 ConfigProvider 之外,读不到它的方向,需要跟随方向时在选项里传 direction,或改用 Modal.useModal()、Toast.useToast()、Notification.useNotification()。Modal.useModal() 继承调用它的组件所处位置的 ConfigProvider;useToast() 与 useNotification() 返回 [api, Holder],Holder 组件渲染在哪里,就继承哪里的 ConfigProvider。

Buttons



Input





Prefix


Suffix


0/100


多选框
禁用的多选框
禁用的多选框










Navigation




Finished
This is a description.
2
In Progress
This is a description.
3
Waiting
This is a description.

Finished
This is a description.
In Progress
This is a description.
3
Waiting
This is a description.

Display

XZ 5
YB 5
LX 5
YZ
HW
XM

grey tag
blue tag
ghost tag
solid tag
red tag
green tag
orange tag
teal tag
violet tag
white tag

I am Popover
I am Tooltip

  • 审核中
    2019-07-14 10:35
  • 发布成功
    2019-06-13 16:17
  • 审核失败
    2019-05-14 18:34

Feedback





I am loading...

Here are some texts.

And more texts on the way.

代码
<script lang="ts">
    import { IconCamera, IconChevronDown, IconEdit, IconList, IconSidebar, IconVigoLogo } from '@fibrae/semi-icons-svelte';
    import {
        Avatar,
        Badge,
        Breadcrumb,
        Button,
        ButtonGroup,
        Cascader,
        Checkbox,
        Col,
        ConfigProvider,
        DatePicker,
        Input,
        Modal,
        Nav,
        Notification,
        Pagination,
        Popover,
        Radio,
        Rating,
        Row,
        Select,
        Spin,
        Steps,
        Switch,
        Tag,
        TextArea,
        TimePicker,
        Timeline,
        Toast,
        Tooltip,
        TypographyText,
        type NavItems,
        type TimelineData,
    } from '@fibrae/semi-ui-svelte';

    let direction = $state<'ltr' | 'rtl'>();
    const flexStyle = 'display: flex; margin-bottom: 32px; flex-wrap: wrap';
    const titleStyle = 'margin: 50px 0 16px 0';
    const rowStyle = 'margin: 16px 10px';
    const badgeStyle = 'width: 42px; height: 42px; border-radius: 4px; display: inline-block';
    const tagStyle = 'margin-right: 8px; margin-bottom: 8px';
    const opts = () => ({
        title: 'Hi,Bytedance',
        content: 'ies dance dance dance',
        duration: 3,
        direction,
    });
    const optionList = [
        { value: 'abc', label: '抖音' },
        { value: 'hotsoon', label: '火山' },
        { value: 'pipixia', label: '皮皮虾', disabled: true },
        { value: 'xigua', label: '西瓜视频' },
    ];
    const treeData = [
        {
            label: '浙江省',
            value: 'zhejiang',
            children: [
                {
                    label: '杭州市',
                    value: 'hangzhou',
                    children: [
                        { label: '西湖区', value: 'xihu' },
                        { label: '萧山区', value: 'xiaoshan' },
                        { label: '临安区', value: 'linan' },
                    ],
                },
                {
                    label: '宁波市',
                    value: 'ningbo',
                    children: [
                        { label: '海曙区', value: 'haishu' },
                        { label: '江北区', value: 'jiangbei' },
                    ],
                },
            ],
        },
    ];
    const navItems: NavItems = [
        { itemKey: 'user', text: 'Option1' },
        { itemKey: 'union', text: 'Option2' },
        { itemKey: 'approve-management', text: 'Group3', items: ['3-1', '3-2'] },
    ];
    const navIcons = { user: IconEdit, union: IconCamera, 'approve-management': IconList };
    const steps = [
        { title: 'Finished', description: 'This is a description.' },
        { title: 'In Progress', description: 'This is a description.' },
        { title: 'Waiting', description: 'This is a description.' },
    ];
    const timeline: TimelineData[] = [
        { type: 'ongoing', time: '2019-07-14 10:35', content: '审核中' },
        { type: 'success', time: '2019-06-13 16:17', content: '发布成功' },
        { type: 'error', time: '2019-05-14 18:34', content: '审核失败' },
    ];
    const badges = [
        { props: { count: 5, theme: 'solid' }, color: 'blue', text: 'XZ' },
        { props: { count: 5, theme: 'light' }, color: 'cyan', text: 'YB' },
        { props: { count: 5, theme: 'inverted' }, color: 'indigo', text: 'LX' },
        { props: { dot: true, theme: 'solid' }, color: 'light-blue', text: 'YZ' },
        { props: { dot: true, theme: 'light' }, color: 'teal', text: 'HW' },
    ] as const;
</script>

{#snippet vigo()}<IconVigoLogo />{/snippet}
{#snippet pinkVigo()}<IconVigoLogo style="color: pink" />{/snippet}

<div>
    <div style="margin-bottom: 20px">
        <ButtonGroup>
            <Button onclick={() => (direction = 'ltr')}>LTR</Button>
            <Button onclick={() => (direction = 'rtl')}>RTL</Button>
        </ButtonGroup>
    </div>
    <ConfigProvider {direction}>
        <Row>
            <h3 style={titleStyle}>Buttons</h3>
        </Row>
        <Row style={rowStyle}>
            <Button loading style="margin-right: 8px" theme="solid">加载</Button>
            <Button style="margin-right: 8px" theme="solid">
                {#snippet icon()}
                    <IconSidebar />
                {/snippet}
                收起
            </Button>
            <Button iconPosition="right" style="margin-right: 8px" theme="solid">
                {#snippet icon()}
                    <IconChevronDown />
                {/snippet}
                展开选项
            </Button>
            <br />
            <br />
            <ButtonGroup>
                <Button>拷贝</Button>
                <Button>查询</Button>
                <Button>剪切</Button>
            </ButtonGroup>
        </Row>
        <Row>
            <h3 style={titleStyle}>Input</h3>
        </Row>
        <Row gutter={16} style={rowStyle}>
            <Col span={12}>
                <Input aria-label="输入框" placeholder="输入框" />
                <br />
                <br />
                <Input aria-label="禁用的输入框" disabled placeholder="输入框" />
                <br />
                <br />
                <Input aria-label="带前缀的输入框" showClear>
                    {#snippet prefix()}Prefix{/snippet}
                </Input>
                <br />
                <br />
                <Input aria-label="带后缀的输入框" showClear>
                    {#snippet suffix()}
                        <TypographyText strong style="margin: 0 8px" type="secondary">Suffix</TypographyText>
                    {/snippet}
                </Input>
                <br />
                <br />
                <TextArea aria-label="文本框" maxCount={100} placeholder="文本框" />
                <br />
                <br />
                <div style={flexStyle}>
                    <Switch aria-label="已开启的开关" checked style="margin-right: 8px" />
                    <Switch aria-label="已关闭的开关" style="margin-right: 8px" />
                    <Switch aria-label="禁用的开关" checked disabled style="margin-right: 8px" />
                </div>
                <div style={flexStyle}>
                    <Checkbox checked style="margin-right: 8px">多选框</Checkbox>
                    <Checkbox checked disabled style="margin-right: 8px">禁用的多选框</Checkbox>
                    <Checkbox disabled style="margin-right: 8px">禁用的多选框</Checkbox>
                </div>
                <div style="{flexStyle}; margin-bottom: 0">
                    <Radio checked style="margin-right: 8px">单选框</Radio>
                    <Radio checked disabled style="margin-right: 8px">禁用的单选框</Radio>
                    <Radio disabled style="margin-right: 8px">禁用的单选框</Radio>
                </div>
            </Col>
            <Col span={12}>
                <DatePicker onChange={(_date, dateString) => console.log(dateString)} style="width: 100%" />
                <br />
                <br />
                <TimePicker style="width: 100%" />
                <br />
                <br />
                <Select aria-label="选择器-单选" {optionList} placeholder="选择器-单选" style="width: 100%" />
                <br />
                <br />
                <Select aria-label="选择器-禁用" disabled {optionList} placeholder="选择器-禁用" style="width: 100%" />
                <br />
                <br />
                <Select aria-label="选择器-多选" multiple {optionList} placeholder="选择器-多选" style="width: 100%" />
                <br />
                <br />
                <Cascader placeholder="级联选择器" style="width: 100%" {treeData} />
            </Col>
        </Row>
        <Row>
            <h3 style={titleStyle}>Navigation</h3>
        </Row>
        <Row style={rowStyle}>
            <Breadcrumb routes={['Semi-ui', 'Breadcrumb', 'Default']} />
            <Nav items={navItems} mode="horizontal">
                {#snippet icon({ item, size })}
                    {@const Icon = navIcons[item.itemKey as keyof typeof navIcons]}
                    {#if Icon}
                        <Icon {size} />
                    {/if}
                {/snippet}
            </Nav>
            <br />
            <br />
            <Pagination showSizeChanger total={80} />
            <br />
            <Steps current={1} dataSource={steps} type="basic" />
            <br />
            <Steps current={1} dataSource={steps} status="error" type="basic" />
        </Row>
        <Row>
            <h3 style={titleStyle}>Display</h3>
        </Row>
        <Row style={rowStyle}>
            <div style="display: flex">
                {#each badges as badge (badge.text)}
                    <div style="padding: 8px">
                        <Badge {...badge.props}>
                            <Avatar color={badge.color} shape="square" style={badgeStyle}>{badge.text}</Avatar>
                        </Badge>
                    </div>
                {/each}
                <div style="padding: 8px; border-radius: 4px; background-color: var(--semi-color-fill-0)">
                    <Badge dot theme="inverted">
                        <Avatar color="green" shape="square" style={badgeStyle}>XM</Avatar>
                    </Badge>
                </div>
            </div>
            <br />
            <div>
                <Tag color="grey" style={tagStyle}>grey tag</Tag>
                <Tag color="blue" style={tagStyle}>blue tag</Tag>
                <Tag color="blue" style={tagStyle} type="ghost">ghost tag</Tag>
                <Tag color="blue" style={tagStyle} type="solid">solid tag</Tag>
                <Tag color="red" style={tagStyle}>red tag</Tag>
                <Tag color="green" style={tagStyle}>green tag</Tag>
                <Tag color="orange" style={tagStyle}>orange tag</Tag>
                <Tag color="teal" style={tagStyle}>teal tag</Tag>
                <Tag color="violet" style={tagStyle}>violet tag</Tag>
                <Tag color="white" style={tagStyle}>white tag</Tag>
            </div>
            <br />
            <div style="display: flex; align-items: center">
                <Popover style="padding: 8px">
                    {#snippet content()}hi semi-design{/snippet}
                    <Tag style="margin-right: 8px">I am Popover</Tag>
                </Popover>
                <Tooltip>
                    {#snippet content()}hi semi-design{/snippet}
                    <Tag style="margin-right: 8px">I am Tooltip</Tag>
                </Tooltip>
                <Rating size="small" style="margin-right: 8px" value={3} />
            </div>
            <br />
            <Timeline dataSource={timeline} />
        </Row>
        <Row>
            <h3 style={titleStyle}>Feedback</h3>
        </Row>
        <Row style={rowStyle}>
            <Button style={tagStyle} type="primary" onclick={() => Notification.success(opts())}>成功信息的通知</Button>
            <Button style={tagStyle} onclick={() => Notification.info(opts())}>提示信息的通知</Button>
            <Button style={tagStyle} type="warning" onclick={() => Notification.warning(opts())}>警告信息的通知</Button>
            <Button style={tagStyle} type="danger" onclick={() => Notification.error(opts())}>失败信息的通知</Button>
            <Button aria-label="Vigo 图标通知" style={tagStyle} onclick={() => Notification.info({ ...opts(), icon: vigo })}>
                {#snippet icon()}
                    <IconVigoLogo />
                {/snippet}
            </Button>
            <Button aria-label="粉色 Vigo 图标通知" style={tagStyle} onclick={() => Notification.info({ ...opts(), icon: pinkVigo })}>
                {#snippet icon()}
                    <IconVigoLogo />
                {/snippet}
            </Button>
            <br />
            <Button style={tagStyle} type="primary" onclick={() => Modal.success(opts())}>成功信息的弹窗</Button>
            <Button style={tagStyle} onclick={() => Modal.info(opts())}>提示信息的弹窗</Button>
            <Button style={tagStyle} type="warning" onclick={() => Modal.warning(opts())}>警告信息的弹窗</Button>
            <Button style={tagStyle} type="danger" onclick={() => Modal.error(opts())}>失败信息的弹窗</Button>
            <br />
            <Button style={tagStyle} type="primary" onclick={() => Toast.success(opts())}>成功信息的提示</Button>
            <Button style={tagStyle} onclick={() => Toast.info(opts())}>提示信息的提示</Button>
            <Button style={tagStyle} type="warning" onclick={() => Toast.warning(opts())}>警告信息的提示</Button>
            <Button style={tagStyle} type="danger" onclick={() => Toast.error(opts())}>失败信息的提示</Button>
            <br />
            <br />
            <Spin>
                {#snippet tip()}I am loading...{/snippet}
                <div style="background-color: var(--semi-color-primary-light-default); border: 1px solid var(--semi-color-primary); border-radius: 4px; padding: 16px 10px">
                    <p>Here are some texts.</p>
                    <p>And more texts on the way.</p>
                </div>
            </Spin>
        </Row>
    </ConfigProvider>
</div>

嵌套使用

ConfigProvider 可以嵌套。内层只覆盖显式传入的属性,没传的属性(direction、locale、timeZone、getPopupContainer、responsiveObserve、responsiveMap)继承外层。属性值为 undefined 视为没传;locale={null} 是显式传入,会清除外层的 locale,交给其内部的 LocaleProvider 或默认语言。

direction 为 rtl 的 ConfigProvider 内可以用 direction="ltr" 把子树切回从左到右,内层组件的逻辑和样式都按 ltr 处理。

外层:locale = en-US,timeZone = Asia/Tokyo,direction = ltr
内层只传 timeZone,其余继承外层:locale = en-US,timeZone = 8,direction = ltr
代码
<script lang="ts">
    import en_US from '@fibrae/semi-foundation/locale/source/en_US';
    import { ConfigConsumer, ConfigProvider } from '@fibrae/semi-ui-svelte';
</script>

<ConfigProvider direction="ltr" locale={en_US} timeZone="Asia/Tokyo">
    <ConfigConsumer>
        {#snippet children({ locale, timeZone, direction })}
            <div style="margin: 8px">外层:locale = {locale?.code ?? '未设置'},timeZone = {String(timeZone)},direction = {direction}</div>
        {/snippet}
    </ConfigConsumer>
    <ConfigProvider timeZone={8}>
        <ConfigConsumer>
            {#snippet children({ locale, timeZone, direction })}
                <div style="margin: 8px">内层只传 timeZone,其余继承外层:locale = {locale?.code ?? '未设置'},timeZone = {String(timeZone)},direction = {direction}</div>
            {/snippet}
        </ConfigConsumer>
    </ConfigProvider>
</ConfigProvider>

API 参考

ConfigProvider

Props

属性说明类型默认值
children受该配置影响的内容。显式传入的 direction 与外层不同时(含最外层),内容外包一层带 dir 属性的 div。Snippet-
direction文本方向,可选 ltr 或 rtl。未传时继承外层 ConfigProvider,最外层默认为 ltr。'ltr' | 'rtl'-
getPopupContainer返回弹层容器的函数,只影响仍通过 Portal 渲染的 Modal、SideSheet、ImagePreview,容器需要设置 position: relative。未传时继承外层,最外层为 document.body。Type() => HTMLElement-
locale多语言配置,优先级高于 LocaleProvider。未传时继承外层 ConfigProvider;没有 ConfigProvider 设置时由 LocaleProvider 决定,两者都没有时使用 zh_CN。传 null 清除外层的 locale。Locale | null-
responsiveMap自定义响应式断点,key 为 xs、sm、md、lg、xl、xxl,value 为 media query 字符串。按内容比较,内联写对象不会重新注册监听;未传时继承外层,最外层使用 defaultResponsiveMap。ResponsiveMap-
responsiveObserve是否开启响应式断点监听。关闭时不注册任何 matchMedia 监听;开启后在首次订阅时注册,无订阅时注销。未传时继承外层,最外层为 false。boolean-
timeZone时间类组件使用的时区:数字(距 UTC 的小时偏移)、GMT±HH:MM 字符串或 IANA 标识。数字和 GMT 写法是全年固定的偏移。未传时继承外层。string | number-

defaultResponsiveMap 是默认断点配置,从 @fibrae/semi-ui-svelte 具名导出。locale 的用法同 LocaleProvider 中 locale 参数的用法。ConfigProvider 不接收 class、style 与原生属性,它们不会落到 DOM 上。

ConfigConsumer

Props

属性说明类型默认值
children参数为当前生效配置(ContextValue)的 snippet;在 ConfigProvider 内还包含 screens 与 onBreakpoint,没有 ConfigProvider 时为空对象。TypeSnippet<[config: ContextValue]>-

ConfigConsumer 同样不渲染元素,未声明的属性会被丢弃。

useConfig

useConfig(): ContextValue 返回当前生效的配置对象,没有 ConfigProvider 时为空对象;需要在组件初始化时调用。ContextValue 包含上表的 direction、timeZone、locale、getPopupContainer、responsiveObserve 和 responsiveMap,以及只读的 screens(各断点的命中情况)和 onBreakpoint(订阅函数,见上文「订阅 API」)。字段是 getter,读取时才取当前值。

时区标识

  • 数字,例如 1、-9.5,代表距离 UTC 的时间偏移,单位为小时,可以为负数或小数;
  • 字符串,例如GMT-09:30、GMT+08:00这样的以 "GMT" 开头的表征偏移字符串,也可以为 IANA 标识,如Asia/Shanghai、America/Los_Angeles等。

数字和 GMT-09:30 这类写法表示全年固定的偏移,不随夏令时变化。例如 -3.5 和 GMT-03:30 全年都是 UTC-03:30,时间格式中的时区名(z)显示为 GMT-03:30。

需要跟随某个地区的夏令时,请使用 IANA 标识。这里可以查看 IANA 标识列表,以及时区是否有夏令时。

FAQ

  • ConfigProvider中没有提供全局自定义prefix classname的功能,有类似需求如何实现(例如SDK中使用了Semi,期望打包的dom样式不带.semi-xx前缀,以免被宿主的全局 CSS 影响)?
    • 由于 prefixCls 需要同时被组件层的 js/css 消费,Semi 将此开关放在了webpack plugin的配置项中,而不是作为ConfigProvider的配置项。
    • 如果你使用webpack,请在SemiWebpackPlugin的参数中进行配置
# webpack配置示例
const SemiWebpackPlugin = require('@fibrae/semi-webpack-plugin').default;
module.exports = {
+    plugins: [new SemiWebpackPlugin({ prefixCls: 'imes' })],
}

semiGlobal

除了 ConfigProvider外,你还可以通过 semiGlobal 配置覆盖全局组件的默认 Props。

在 semiGlobal.config.overrideDefaultProps 可配置组件默认 Props。组件在创建时读取一次全局配置,之后修改它不会更新已创建的组件,因此建议在挂载应用之前设置,放在站点入口处。属性值为 undefined 时视为没传,才会采用默认值。需要为单个应用使用独立的配置时,创建一个 SemiGlobal 实例,通过 mount(App, { context: new Map([[semiGlobalKey, semi]]) }) 传入,SemiGlobal 与 semiGlobalKey 同样从 @fibrae/semi-ui-svelte 导入。

id、insetLabelId、wrapperId、addonId、extraId 这类每个实例唯一的属性不能经全局默认值设置:类型里没有这些键,运行时也忽略。

比如下方配置就是将所有的 Button 默认设置为 warning,Select 默认开启 filter 等

import { semiGlobal } from '@fibrae/semi-ui-svelte';

semiGlobal.config.overrideDefaultProps = {
    Button: {
        type: 'warning',
    },
    Select: {
        filter: true,
    },
    Tooltip: {
        trigger: 'click',
    },
};