diff --git a/packages/docs/src/components/OperatorView.ts b/packages/docs/src/components/OperatorView.ts index a694b93760983792908e1046ec9208bed4249687..8327474da512cf4bb9626e9d6e1cd5490c7ecd34 100644 --- a/packages/docs/src/components/OperatorView.ts +++ b/packages/docs/src/components/OperatorView.ts @@ -39,12 +39,13 @@ type RadioScheme = { export type SchemeT = CheckboxScheme | SelectorScheme | InputScheme | TextareaScheme | InputNumberScheme | RadioScheme; export type State = Record; +const camelcase2words = (str: string) => str.replace(/(?<=[a-z])([A-Z])|(?<=[A-Z])([A-Z][a-z])/g, ' $&').replace(/^[a-z]/, (char) => char.toUpperCase()); const createCheckboxItem = (key: string, value: CheckboxScheme) => { - return h(OCheckbox, { value: key }, { default: () => value.label || key }); + return h(OCheckbox, { value: key }, { default: () => value.label || camelcase2words(key) }); }; const createSelectorItem = (key: string, value: SelectorScheme, state: State) => { return h(Fragment, [ - h('span', { class: 'props-playground-selector-name' }, value.label || key), + h('span', { class: 'props-playground-selector-name' }, value.label || camelcase2words(key)), h( OSelect, { modelValue: state[key], 'onUpdate:modelValue': (val) => (state[key] = val) }, @@ -56,13 +57,13 @@ const createSelectorItem = (key: string, value: SelectorScheme, state: State) => }; const createInputItem = (key: string, value: InputScheme, state: State) => { return h(Fragment, [ - h('span', { class: 'props-playground-selector-name' }, value.label || key), + h('span', { class: 'props-playground-selector-name' }, value.label || camelcase2words(key)), h(OInput, { modelValue: state[key], 'onUpdate:modelValue': (val) => (state[key] = val) }), ]); }; const createTextareaItem = (key: string, value: TextareaScheme, state: State) => { return h(Fragment, [ - h('span', { class: 'props-playground-selector-name' }, value.label || key), + h('span', { class: 'props-playground-selector-name' }, value.label || camelcase2words(key)), h(OTextarea, { modelValue: state[key], style: { '--row': value.row || 3 }, @@ -73,7 +74,7 @@ const createTextareaItem = (key: string, value: TextareaScheme, state: State) => }; const createInputNumberItem = (key: string, value: InputNumberScheme, state: State) => { return h(Fragment, [ - h('span', { class: 'props-playground-selector-name' }, value.label || key), + h('span', { class: 'props-playground-selector-name' }, value.label || camelcase2words(key)), h(OInputNumber, { modelValue: state[key], min: value.min, diff --git a/packages/opendesign/src/_demo/utils.ts b/packages/opendesign/src/_demo/utils.ts index d8f86c6e8d7085ce1de38962c52dc263a66103b0..f4e02854009fbbfffa5049707b61c369d9c23500 100644 --- a/packages/opendesign/src/_demo/utils.ts +++ b/packages/opendesign/src/_demo/utils.ts @@ -11,10 +11,10 @@ export function hyphenate(str: string) { * @param exclude 不转化的props属性名 * @returns 属性字符串 */ -export function propsToAttrStr(props: Record, exclude = [] as string[]) { +export function propsToAttrStr>(props: T, exclude: (keyof T)[] = []): string { return Object.entries(props) .reduce((acc, [_key, value]) => { - if (exclude.includes(_key)) { + if (exclude.includes(_key as any)) { return acc; } const key = hyphenate(_key); @@ -50,3 +50,19 @@ export function propsToAttrStr(props: Record, exclude = [] as strin }, '') .slice(1); } + +const REPLACEMENTS: Record = { + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '&': '&', +}; +function replaceCellChar(ch: string) { + return REPLACEMENTS[ch]; +} +// 避免xss注入 +export function escapeHTML(value?: string) { + const ESCAPE_REPLACE_RE = /[<>"'&]/g; + return value ? value.replace(ESCAPE_REPLACE_RE, replaceCellChar) : ''; +} diff --git a/packages/opendesign/src/badge/__docs__/__case__/BadgeUsage.vue b/packages/opendesign/src/badge/__docs__/__case__/BadgeUsage.vue index 67ee2061e976e0f22d4e4f43a1045930180c7942..a0af9a3782386f7523a0dd244372c76f551716cf 100644 --- a/packages/opendesign/src/badge/__docs__/__case__/BadgeUsage.vue +++ b/packages/opendesign/src/badge/__docs__/__case__/BadgeUsage.vue @@ -45,11 +45,11 @@ const _schema = { type: 'boolean', default: false, }, - 'offset-x': { + offsetX: { type: 'number', default: 0, }, - 'offset-y': { + offsetY: { type: 'number', default: 0, }, @@ -57,12 +57,12 @@ const _schema = { const NUMBER_REGEXP = /^\d+$/; const _template: DocDemoTemplate = (props) => { - const { 'offset-x': offsetX, 'offset-y': offsetY, value } = props; + const { offsetX, offsetY, value } = props; const isNumber = NUMBER_REGEXP.test(value); return ` diff --git a/packages/opendesign/src/card/__docs__/__case__/CardUsage.vue b/packages/opendesign/src/card/__docs__/__case__/CardUsage.vue index eefee6d8b7197565940ca9abfe50f2a762d5e7fb..157edde54e65ba97eb7a429d05792db407b9b1d3 100644 --- a/packages/opendesign/src/card/__docs__/__case__/CardUsage.vue +++ b/packages/opendesign/src/card/__docs__/__case__/CardUsage.vue @@ -76,7 +76,7 @@ const _schema = { }, coverOrIcon: { type: 'radio', - list: ['cover', 'icon'], + list: ['Cover', 'Icon'] as const, default: 'cover', }, coverRatio: { @@ -122,14 +122,13 @@ const _schema = { noResponsive: { type: 'boolean', default: false, - label: 'close responsive', }, } satisfies Record; const _template: DocDemoTemplate = (props) => { const { coverOrIcon, titleRow, detailRow } = props; let attrs = ''; - if (coverOrIcon === 'cover') { + if (coverOrIcon === 'Cover') { attrs += ' cover="/card-cover.jpg"'; } else { attrs += ' icon="/avatar.svg"'; diff --git a/packages/opendesign/src/carousel/__docs__/__case__/CarouselUsage.vue b/packages/opendesign/src/carousel/__docs__/__case__/CarouselUsage.vue index 6ed2bdc26be9182730a84d9e6a9a0ad290ebf74e..87b795c3e5b43c1a57e9b8631d6bb7074f078891 100644 --- a/packages/opendesign/src/carousel/__docs__/__case__/CarouselUsage.vue +++ b/packages/opendesign/src/carousel/__docs__/__case__/CarouselUsage.vue @@ -81,14 +81,13 @@ const _schema = { autoPlay: { type: 'boolean', default: true, - label: 'auto play', }, interval: { type: 'number', default: 5000, step: 1000, min: 1000, - label: 'interval (ms)', + label: 'Interval (ms)', }, arrow: { type: 'list', @@ -98,20 +97,16 @@ const _schema = { hideIndicator: { type: 'boolean', default: false, - label: 'hide indicator', }, indicatorClick: { type: 'boolean', - label: 'indicator click', }, pauseOnHover: { type: 'boolean', default: true, - label: 'pause on hover', }, clickToSwitch: { type: 'boolean', - label: 'click to switch', }, } satisfies Record; diff --git a/packages/opendesign/src/cascader/__docs__/__case__/CascaderUsage.vue b/packages/opendesign/src/cascader/__docs__/__case__/CascaderUsage.vue index ac13117321db4ee5f2bb844a79be86baa816d417..7566fcc878fc0d73d614e7a4d00c359babdbdcb0 100644 --- a/packages/opendesign/src/cascader/__docs__/__case__/CascaderUsage.vue +++ b/packages/opendesign/src/cascader/__docs__/__case__/CascaderUsage.vue @@ -89,10 +89,9 @@ import { DocDemoTemplate, DocDemoSchema } from '../../../_demo/types'; import { propsToAttrStr } from '../../../_demo/utils'; const _schema = { - 'path-mode': { + pathMode: { type: 'boolean', default: false, - label: 'path mode', }, round: { type: 'list', @@ -106,11 +105,10 @@ const _schema = { type: 'string', default: 'Please select', }, - 'option-position': { + optionPosition: { type: 'list', list: ['top', 'tl', 'tr', 'bottom', 'bl', 'br', 'left', 'lt', 'lb', 'right', 'rt', 'rb'], default: 'bl', - label: 'option position', }, } satisfies Record; diff --git a/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue index 9fac140b5d90b3988a8087ca20a47e2880cb0c53..731030ef55c4c050f5af6bb7f2cd06ecfaa664a0 100644 --- a/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue +++ b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue @@ -9,29 +9,35 @@ - `default`: 主体,用于放置内容。**注**:`default` 插槽中的内容有溢出滚动的功能(可通过 `scrollbar` 参数调整滚动条,参数类型[BaseScrollerPropsT](#base-scroller-props-t)),其余插槽位置固定不能滚动; - `actions`: 按钮,用于自定义底部按钮 - `footer`: 底部,用于防止底部内容。**注**:`footer` 插槽会覆盖 `actions` 插槽。 + + + +### Slots + +The dialog has four slots: + +- `header`: Header, used to place the title. +- `default`: Body, used to place content. **Note**: Content in the `default` slot supports overflow scrolling + (the scrollbar can be adjusted via the `scrollbar` parameter; for the parameter type, see [BaseScrollerPropsT](#base-scroller-props-t)), + while other slots have fixed positions and cannot scroll. +- `actions`: Buttons, used to customize the bottom buttons. - - - - - - - - - - \ No newline at end of file diff --git a/packages/opendesign/src/dialog/__docs__/__case__/DialogSlotForm.vue b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlotForm.vue new file mode 100644 index 0000000000000000000000000000000000000000..9855664aa90b9bdcf324307851dec8d10b05e732 --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlotForm.vue @@ -0,0 +1,57 @@ + + + + diff --git a/packages/opendesign/src/dialog/__docs__/index.en-US.md b/packages/opendesign/src/dialog/__docs__/index.en-US.md index 410634e03a634c5895e323826ba8a6b124d6cd83..ab1755805ab16a9e83980cb9adfcfdd924ad9fcd 100644 --- a/packages/opendesign/src/dialog/__docs__/index.en-US.md +++ b/packages/opendesign/src/dialog/__docs__/index.en-US.md @@ -8,31 +8,33 @@ sidebar: ODialog + + ## API ### CSS Variables -| CSS Variable | Description | -| --- | --- | -| --dlg-close-size | Size of the close button | -| --dlg-close-color | Color of the close button | -| --dlg-close-color-hover | Color of the close button when hovered | -| --dlg-close-color-active | Color of the close button when active | -| --dlg-color | Text color | -| --dlg-header-color | Header color, overrides `--dlg-color` | -| --dlg-bg-color | Background color | -| --dlg-radius | Border radius | -| --dlg-shadow | Box shadow | -| --dlg-max-height | Maximum height | -| --dlg-min-height | Minimum height | -| --dlg-min-width | Minimum width | -| --dlg-width | Width | -| --dlg-margin | Margin | -| --dlg-edge-gap | Padding | -| --dlg-inner-gap | Spacing between the default header and footer | -| --dlg-header-gap | Spacing between the header and default content, overrides `--dlg-inner-gap` | -| --actions-justify | Alignment of the action buttons at the bottom | +| CSS Variable | Description | +| -------------------------- | --------------------------------------------------------------------------- | +| \-\-dlg-close-size | Size of the close button | +| \-\-dlg-close-color | Color of the close button | +| \-\-dlg-close-color-hover | Color of the close button when hovered | +| \-\-dlg-close-color-active | Color of the close button when active | +| \-\-dlg-color | Text color | +| \-\-dlg-header-color | Header color, overrides `--dlg-color` | +| \-\-dlg-bg-color | Background color | +| \-\-dlg-radius | Border radius | +| \-\-dlg-shadow | Box shadow | +| \-\-dlg-max-height | Maximum height | +| \-\-dlg-min-height | Minimum height | +| \-\-dlg-min-width | Minimum width | +| \-\-dlg-width | Width | +| \-\-dlg-margin | Margin | +| \-\-dlg-edge-gap | Padding | +| \-\-dlg-inner-gap | Spacing between the default header and footer | +| \-\-dlg-header-gap | Spacing between the header and default content, overrides `--dlg-inner-gap` | +| \-\-actions-justify | Alignment of the action buttons at the bottom | diff --git a/packages/opendesign/src/dialog/__docs__/index.zh-CN.md b/packages/opendesign/src/dialog/__docs__/index.zh-CN.md index 2c6385a0e3d14c6af911a8d596c995ec5d210bd8..9bcc4c68b7d6dc71968c6a88017cea83faa5e49e 100644 --- a/packages/opendesign/src/dialog/__docs__/index.zh-CN.md +++ b/packages/opendesign/src/dialog/__docs__/index.zh-CN.md @@ -9,31 +9,32 @@ sidebar: ODialog 对话框 + ## API ### CSS 变量 -| CSS变量 | 描述 | -| --- | --- | -| --dlg-close-size | 关闭按钮大小 | -| --dlg-close-color | 关闭按钮颜色 | -| --dlg-close-color-hover | 鼠标悬停关闭按钮颜色 | -| --dlg-close-color-active | 鼠标按下关闭按钮颜色 | -| --dlg-color | 文字颜色 | -| --dlg-header-color | 标题颜色,覆盖 `--dlg-color` | -| --dlg-bg-color | 背景颜色 | -| --dlg-radius | 圆角 | -| --dlg-shadow | 阴影 | -| --dlg-max-height | 最大高度 | -| --dlg-min-height | 最小高度 | -| --dlg-min-width | 最小宽度 | -| --dlg-width | 宽度 | -| --dlg-margin | 外边距 | -| --dlg-edge-gap | 内边距 | -| --dlg-inner-gap | header default 和 footer 之间的间距 | -| --dlg-header-gap | header 和 default 之间的间距,覆盖 `--dlg-inner-gap` | -| --actions-justify | 底部操作按钮的对齐方式 | +| CSS 变量 | 描述 | +| -------------------------- | ---------------------------------------------------- | +| \-\-dlg-close-size | 关闭按钮大小 | +| \-\-dlg-close-color | 关闭按钮颜色 | +| \-\-dlg-close-color-hover | 鼠标悬停关闭按钮颜色 | +| \-\-dlg-close-color-active | 鼠标按下关闭按钮颜色 | +| \-\-dlg-color | 文字颜色 | +| \-\-dlg-header-color | 标题颜色,覆盖 `--dlg-color` | +| \-\-dlg-bg-color | 背景颜色 | +| \-\-dlg-radius | 圆角 | +| \-\-dlg-shadow | 阴影 | +| \-\-dlg-max-height | 最大高度 | +| \-\-dlg-min-height | 最小高度 | +| \-\-dlg-min-width | 最小宽度 | +| \-\-dlg-width | 宽度 | +| \-\-dlg-margin | 外边距 | +| \-\-dlg-edge-gap | 内边距 | +| \-\-dlg-inner-gap | header default 和 footer 之间的间距 | +| \-\-dlg-header-gap | header 和 default 之间的间距,覆盖 `--dlg-inner-gap` | +| \-\-actions-justify | 底部操作按钮的对齐方式 | diff --git a/packages/opendesign/src/divider/__docs__/__case__/DividerUsage.vue b/packages/opendesign/src/divider/__docs__/__case__/DividerUsage.vue new file mode 100644 index 0000000000000000000000000000000000000000..4c9425ce765a8d3c8bb91c17505b3b30e6d19ddd --- /dev/null +++ b/packages/opendesign/src/divider/__docs__/__case__/DividerUsage.vue @@ -0,0 +1,86 @@ + + + +### 使用说明 + +#### 参数配置 + +- **variant**:控制分割线形状 + 可选值:`solid`(实线)、`dashed`(虚线)、`dotted`(点线) + +- **direction**:控制分割线方向 + 可选值:`h`(水平)、`v`(垂直) + + - 水平分割线(`direction="h"`)默认宽度占满容器; + - 垂直分割线(`direction="v"`)默认高度为 `1em`。 + +- **darker**:控制分割线颜色深浅 + 可选值:`true`(深色)、`false`(浅色) + +#### 标签 + +- **限制**:仅水平分割线(`direction="h"`)支持标签功能。 +- **标签位置**:通过 `labelPosition` 属性控制,可选值:`left`(左侧)、`center`(中间)、`right`(右侧)。 +- **标签内容**:标签文本需放置在组件的 `default` 插槽中。 + + + +### Usage Instructions + +#### Props Configuration + +- **variant**: Controls the shape of the divider + Optional values: `solid` (solid line), `dashed` (dashed line), `dotted` (dotted line) + +- **direction**: Controls the direction of the divider + Optional values: `h` (horizontal), `v` (vertical) + + - Horizontal dividers (`direction="h"`) by default fill the full width of the container; + - Vertical dividers (`direction="v"`) have a default height of `1em`. + +- **darker**: Controls the darkness of the divider color + Optional values: `true` (darker), `false` (lighter) + +#### Label + +- **Restrictions**: Only horizontal dividers (`direction="h"`) support the label feature. +- **Label Position**: Controlled by the `labelPosition` prop, with optional values: `left` (left side), `center` (middle), `right` (right side). +- **Label Content**: The label text should be placed in the component's default slot. + + + diff --git a/packages/opendesign/src/divider/__docs__/index.en-US.md b/packages/opendesign/src/divider/__docs__/index.en-US.md new file mode 100644 index 0000000000000000000000000000000000000000..43a3318b992c006218541c33ed72feba1cdb864f --- /dev/null +++ b/packages/opendesign/src/divider/__docs__/index.en-US.md @@ -0,0 +1,24 @@ +--- +sidebar: ODivider +--- + +# ODivider + +## Demo + + + +## API + +### CSS Variables + +| CSS Variable | Description | +| ------------------------- | ------------------------------------------------ | +| \-\-o-divider-color | Label text color | +| \-\-o-divider-text-size | Label text font size | +| \-\-o-divider-text-height | Label text line height | +| \-\-o-divider-label-gap | Spacing between label and divider | +| \-\-o-divider-bd-color | Divider border color | +| \-\-o-divider-gap | Spacing between divider and surrounding elements | + + diff --git a/packages/opendesign/src/divider/__docs__/index.zh-CN.md b/packages/opendesign/src/divider/__docs__/index.zh-CN.md new file mode 100644 index 0000000000000000000000000000000000000000..a07c15fd0a43f28db4944174e37b0baab27848b6 --- /dev/null +++ b/packages/opendesign/src/divider/__docs__/index.zh-CN.md @@ -0,0 +1,24 @@ +--- +sidebar: ODivider +--- + +# ODivider 分割线 + +## 示例 + + + +## API + +### CSS 变量 + +| CSS 变量 | 描述 | +| ----------------------- | -------------------------- | +| \-\-o-divider-color | label 文本颜色 | +| \-\-o-divider-text-size | label 文本字号 | +| \-\-o-divider-text-height | label 文本行高 | +| \-\-o-divider-label-gap | label 与分割线之间的间距 | +| \-\-o-divider-bd-color | 分割线颜色 | +| \-\-o-divider-gap | 分割线与周围元素之间的间距 | + + diff --git a/packages/opendesign/src/divider/types.ts b/packages/opendesign/src/divider/types.ts index 4e42e386f94e0563ca802ff5f02c1167254a5a0c..6ae4f80e65dabab1d6044940e7ba35b05a544904 100644 --- a/packages/opendesign/src/divider/types.ts +++ b/packages/opendesign/src/divider/types.ts @@ -6,28 +6,36 @@ export type DividerVariantT = (typeof DividerVariantTypes)[number]; export const dividerProps = { /** - * 分割线类型 DividerVariantT + * @zh-CN 分割线形状 + * @en-US Divider shape + * @default 'solid' */ variant: { type: String as PropType, default: 'solid', }, /** - * 分割线方向 DirectionT + * @zh-CN 分割线方向 + * @en-US Divider direction + * @default 'h' */ direction: { type: String as PropType, default: 'h', }, /** - * 自定义内容位置 + * @zh-CN 分割线标签位置 + * @en-US Divider label position + * @default 'center' */ labelPosition: { type: String as PropType<'left' | 'center' | 'right'>, default: 'center', }, /** - * 是否颜色加深 + * @zh-CN 是否使用深色 + * @en-US Whether to use dark + * @default false */ darker: { type: Boolean,