From e1ff803dca6c35cacde9081c4a523f4392a8571d Mon Sep 17 00:00:00 2001 From: sakurayinfei <970412446@qq.com> Date: Fri, 1 Aug 2025 17:01:10 +0800 Subject: [PATCH 1/5] =?UTF-8?q?fix(doc):=20=E4=BC=98=E5=8C=96api=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=94=9F=E6=88=90=E5=87=BD=E6=95=B0=EF=BC=8C=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=87=BA=E6=AD=A3=E7=A1=AE=E7=9A=84expose=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/docs/scripts/generateApi.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/docs/scripts/generateApi.ts b/packages/docs/scripts/generateApi.ts index 7924c489..50dff716 100644 --- a/packages/docs/scripts/generateApi.ts +++ b/packages/docs/scripts/generateApi.ts @@ -133,6 +133,7 @@ const pathReg = /\/(O.*)\.vue/; const tagTypes = { deprecated: '(warning)', }; +const exposeDesReg = /^\s*expose:([\s\S]+)/; glob('*/O*.vue', { cwd: srcDir, posix: true }).then((files) => { files.forEach(async (file, index) => { const fullPath = join(srcDir, file); @@ -212,14 +213,14 @@ glob('*/O*.vue', { cwd: srcDir, posix: true }).then((files) => { mdContent = `${mdContent}\n\n#### slots\n\n${markdownTable(slotsData)}`; } // expose - const selfExposed = meta.exposed.filter((expose) => expose.description); + const selfExposed = meta.exposed.filter((expose) => expose.description && exposeDesReg.test(expose.description)); if (selfExposed.length) { const tableHeader = { 'zh-CN': ['名称', '类型', '说明'], 'en-US': ['Name', 'Type', 'Description'], }; - let exposeData =selfExposed.map((expose) => { - return [expose.name, expose.type, expose.description]; + let exposeData = selfExposed.map((expose) => { + return [expose.name, expose.type, (expose.description.match(exposeDesReg)?.[1] || '').trim()]; }); exposeData.unshift(tableHeader[lang]); exposeData = cleanTableData(exposeData); -- Gitee From 5325ee818fe5518004aef02127f8200fcda78f1b Mon Sep 17 00:00:00 2001 From: sakurayinfei <970412446@qq.com> Date: Fri, 1 Aug 2025 17:05:24 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat(doc):=20=E4=BC=98=E5=8C=96=E5=B0=86h?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E7=9A=84=E6=A0=87=E9=A2=98=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=BA=E8=A7=84=E8=8C=83id=E7=9A=84=E5=87=BD=E6=95=B0getHead?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/docs/src/utils/getHeads.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/docs/src/utils/getHeads.ts b/packages/docs/src/utils/getHeads.ts index 4d8fbf65..c6b0b510 100644 --- a/packages/docs/src/utils/getHeads.ts +++ b/packages/docs/src/utils/getHeads.ts @@ -1,13 +1,20 @@ /** * 将h标签的标题转换为规范的id(该id会作为h标签的id以及a便签的href) - * @param title 待转换的标题 + * @param str 待转换的标题 * @returns id */ -function escapeTitle(title: string) { - return title +function slugify(str: string) { + return str + // 将驼峰转为中横线 + .replace(/(?<=[a-z])([A-Z])|(?<=[A-Z])([A-Z][a-z])/g, '-$&') .toLowerCase() + // 将空白字符转为中横线 .replace(/\s+/g, '-') - // 转换特殊字符,但不转化 unicode 字符 + // 合并多个中横线 + .replace(/-+/g, '-') + // 移除首尾中横线 + .replace(/(^-|-$)/g, '') + // 转义特殊字符 .replace(/[;,/?:@&=+$#]/g, (char) => encodeURIComponent(char)); } /** @@ -16,11 +23,11 @@ function escapeTitle(title: string) { * @param minLevel 查找的最小级别,默认为2,即只查找h2到h6的标题 * @returns 查找结果,格式为[{title: string, level: number, id: string}] */ -export function getHeads(el: HTMLElement, minLevel = 2) { - let headerId: Record = {}; +export function getHeads(el: HTMLElement, _minLevel = 2) { + const headerId: Record = {}; const heads: Array<{ title: string; level: number; id: string }> = []; let levels = ''; - minLevel = Math.max(Math.floor(minLevel), 1); + const minLevel = Math.max(Math.floor(_minLevel), 1); if (minLevel > 6) { return heads; } @@ -38,7 +45,7 @@ export function getHeads(el: HTMLElement, minLevel = 2) { if (dom.id) { id = dom.id; } else { - id = escapeTitle(title); + id = slugify(title); } // 判断是否有重名id,如果有则加上数字编号;该id会作为锚点的href if (headerId[id]) { -- Gitee From 6c68c7b22d5e94c5f1d683ad4ce7eddd744c70d0 Mon Sep 17 00:00:00 2001 From: sakurayinfei <970412446@qq.com> Date: Fri, 1 Aug 2025 17:06:16 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix(doc):=20=E4=BC=98=E5=8C=96=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=A0=B7=E5=BC=8F=EF=BC=8C=E8=A1=A8=E6=A0=BC=E5=8F=AF?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E4=B8=94=E5=9B=BA=E5=AE=9A=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/docs/src/assets/style/markdown.scss | 29 +++++++++++++++++++- packages/docs/src/assets/style/style.scss | 10 ------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/docs/src/assets/style/markdown.scss b/packages/docs/src/assets/style/markdown.scss index 65d65dda..89e5e369 100644 --- a/packages/docs/src/assets/style/markdown.scss +++ b/packages/docs/src/assets/style/markdown.scss @@ -12,7 +12,8 @@ [data-o-theme$='dark'] pre span { color: var(--shiki-dark); } -p + .code-container, p + .o-table { +p + .code-container, +p + .o-table { margin-top: 8px; } ol, @@ -81,3 +82,29 @@ li { } } } + +.markdown-body { + padding: 0 var(--o3-gap-5); + .markdown-body { + padding: 0; + } + .o-table-wrap { + overflow-x: auto; + th:first-child, + td:first-child { + position: sticky; + left: 0; + } + td:first-child { + background-color: var(--table-bg-color); + } + @media (hover: hover) { + tr:hover td { + background-color: var(--table-row-hover); + } + } + } + @include respond-to('<=pad_v') { + padding: 0; + } +} diff --git a/packages/docs/src/assets/style/style.scss b/packages/docs/src/assets/style/style.scss index 237e243f..daeb67f1 100644 --- a/packages/docs/src/assets/style/style.scss +++ b/packages/docs/src/assets/style/style.scss @@ -154,13 +154,3 @@ section { border-color: #aaa; } } - -.markdown-body { - padding: 0 var(--o3-gap-5); - .markdown-body { - padding: 0; - } - @include respond-to('<=pad_v') { - padding: 0; - } -} -- Gitee From 51369629e86c3ecd2da0f23c754f5ee8a40992a9 Mon Sep 17 00:00:00 2001 From: sakurayinfei <970412446@qq.com> Date: Fri, 1 Aug 2025 17:06:46 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix(doc):=20=E8=B0=83=E6=95=B4TheHeader?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E7=A7=BB=E5=8A=A8=E7=AB=AF=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BAheader=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/docs/src/components/TheHeader.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/docs/src/components/TheHeader.vue b/packages/docs/src/components/TheHeader.vue index 167ce136..ad358389 100644 --- a/packages/docs/src/components/TheHeader.vue +++ b/packages/docs/src/components/TheHeader.vue @@ -128,6 +128,9 @@ watch(locale, (newLocale, oldLocale) => { left: 50%; top: 50%; transform: translate3d(-50%, -50%, 0); + @include respond-to('phone') { + display: none; + } } .left { display: flex; -- Gitee From 59b3019ff72d78b07910d8e2f4769274d4e423f9 Mon Sep 17 00:00:00 2001 From: sakurayinfei <970412446@qq.com> Date: Fri, 1 Aug 2025 17:07:07 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat(doc):=20=E6=96=B0=E5=A2=9Edialog?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/opendesign/src/dialog/ODialog.vue | 1 + .../__docs__/__case__/DialogActions.vue | 48 +++++++ .../__docs__/__case__/DialogSizeUsage.vue | 65 ++++++++++ .../dialog/__docs__/__case__/DialogSlot.vue | 119 ++++++++++++++++++ .../src/dialog/__docs__/index.en-US.md | 73 +++++++++++ .../src/dialog/__docs__/index.zh-CN.md | 74 +++++++++++ packages/opendesign/src/dialog/types.ts | 18 ++- 7 files changed, 392 insertions(+), 6 deletions(-) create mode 100644 packages/opendesign/src/dialog/__docs__/__case__/DialogActions.vue create mode 100644 packages/opendesign/src/dialog/__docs__/__case__/DialogSizeUsage.vue create mode 100644 packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue create mode 100644 packages/opendesign/src/dialog/__docs__/index.en-US.md create mode 100644 packages/opendesign/src/dialog/__docs__/index.zh-CN.md diff --git a/packages/opendesign/src/dialog/ODialog.vue b/packages/opendesign/src/dialog/ODialog.vue index ca982b13..42d4a441 100644 --- a/packages/opendesign/src/dialog/ODialog.vue +++ b/packages/opendesign/src/dialog/ODialog.vue @@ -46,6 +46,7 @@ const scrollbarProps = computed(() => { }); defineExpose({ + /** expose: Toggle the ODialog */ toggle(show?: boolean) { layerRef.value?.toggle(show); }, diff --git a/packages/opendesign/src/dialog/__docs__/__case__/DialogActions.vue b/packages/opendesign/src/dialog/__docs__/__case__/DialogActions.vue new file mode 100644 index 00000000..c3220641 --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/__case__/DialogActions.vue @@ -0,0 +1,48 @@ + + + +### 底部操作按钮 + +`ODialog` 可以通过 `actions` 属性定义对话框底部的操作按钮。`actions` 属性的类型为 [DialogActionT\[\]](#dialog-action-t)。 + + + +### Bottom Action Buttons + +Bottom action buttons in `ODialog` can be defined via the `actions` prop. The `actions` prop is of type [DialogActionT\[\]](#dialog-action-t). + + + + diff --git a/packages/opendesign/src/dialog/__docs__/__case__/DialogSizeUsage.vue b/packages/opendesign/src/dialog/__docs__/__case__/DialogSizeUsage.vue new file mode 100644 index 00000000..c36d5847 --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/__case__/DialogSizeUsage.vue @@ -0,0 +1,65 @@ + + + +### 尺寸 + +ODialog 有不同的尺寸:`'exlarge'` `'large'` `'medium'` `'small'` `'auto'`,通过 `size` 属性设置 + +- 当尺寸为 `auto` 时,对话框的大小适应内容。 +- 当尺寸为其它值时,对话框的宽是相对固定的,高度会被钳制在对应值内。 + 当客户端视口尺寸变化时,对话框尺寸会根据 `size` 自动适配,这在大部分情况下都能获得较好的效果,否则您可以将 `noResponsive` 设置为 `true` 取消自动适配,或者通过 css 变量细颗粒地自定义尺寸。 +- 将 `phoneHalfFull` 设置为 `true`,移动端(视口宽度小于 600px)对话框的宽度会占满视口。**注**: + - 此时 `size` 只影响高度,不影响宽度 + - `noResponsive` 不能为 `true` + + + +### Size + +ODialog offers various size options: `'exlarge'`, `'large'`, `'medium'`, `'small'`, and `'auto'`, configured through the `size` prop. + +- When set to `auto`, the dialog adapts its dimensions to fit the content. +- For other size values, the dialog maintains a relatively fixed width while its height is clamped within the corresponding range. + When the viewport size changes, the dialog automatically adjusts based on the `size` setting. This generally provides optimal display results. + To disable this responsive behavior, set `noResponsive` to `true`. Alternatively, use CSS variables for granular customization. +- Setting `phoneHalfFull` to `true` enables full-width display on mobile devices (viewport width < 600px). **Notes**: + - In this mode, `size` only affects height and does not impact width + - `noResponsive` must not be set to `true` + + diff --git a/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue new file mode 100644 index 00000000..9fac140b --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/__case__/DialogSlot.vue @@ -0,0 +1,119 @@ + + + +### 插槽 + +对话框有四个插槽: + +- `header`: 头部,用于放置标题 +- `default`: 主体,用于放置内容。**注**:`default` 插槽中的内容有溢出滚动的功能(可通过 `scrollbar` 参数调整滚动条,参数类型[BaseScrollerPropsT](#base-scroller-props-t)),其余插槽位置固定不能滚动; +- `actions`: 按钮,用于自定义底部按钮 +- `footer`: 底部,用于防止底部内容。**注**:`footer` 插槽会覆盖 `actions` 插槽。 + + + + + + + \ No newline at end of file diff --git a/packages/opendesign/src/dialog/__docs__/index.en-US.md b/packages/opendesign/src/dialog/__docs__/index.en-US.md new file mode 100644 index 00000000..410634e0 --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/index.en-US.md @@ -0,0 +1,73 @@ +--- +sidebar: ODialog +--- + +# ODialog + +## Demo + + + + +## 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 | + + + +### DialogActionT + +```ts +interface DialogActionT { + id: string | number; + color?: 'normal' | 'primary' | 'success' | 'warning' | 'danger'; + variant?: 'solid' | 'outline' | 'text'; + size?: 'large' | 'medium' | 'small'; + label?: string; + round?: 'pill' | (string & {}); + icon?: Component; + disabled?: boolean; + loading?: boolean; + // Button click event callback function + onClick: () => void; +} +``` + +See [OButton API Props](/en-US/components/button#props) + +### BaseScrollerPropsT + +```ts +type BaseScrollerPropsT = { + disabledX: boolean; + disabledY: boolean; + duration: number; + showType: 'auto' | 'always' | 'hover' | 'never'; + size: 'medium' | 'small'; + autoUpdateOnScrollSize: boolean; + barClass?: string | undefined; +}; +``` + +See [Scroller API Props](/en-US/components/scroller#props) diff --git a/packages/opendesign/src/dialog/__docs__/index.zh-CN.md b/packages/opendesign/src/dialog/__docs__/index.zh-CN.md new file mode 100644 index 00000000..2c6385a0 --- /dev/null +++ b/packages/opendesign/src/dialog/__docs__/index.zh-CN.md @@ -0,0 +1,74 @@ +--- +sidebar: ODialog 对话框 +--- + +# 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 | 底部操作按钮的对齐方式 | + + + +### DialogActionT + +```ts +interface DialogActionT { + id: string | number; + color?: 'normal' | 'primary' | 'success' | 'warning' | 'danger'; + variant?: 'solid' | 'outline' | 'text'; + size?: 'large' | 'medium' | 'small'; + label?: string; + round?: 'pill' | (string & {}); + icon?: Component; + disabled?: boolean; + loading?: boolean; + // 按钮点击事件回调函数 + onClick: () => void; +} +``` + +参考 [OButton API Props](/zh-CN/components/button#props) + +### BaseScrollerPropsT + +```ts +type BaseScrollerPropsT = { + disabledX: boolean; + disabledY: boolean; + duration: number; + showType: 'auto' | 'always' | 'hover' | 'never'; + size: 'medium' | 'small'; + autoUpdateOnScrollSize: boolean; + barClass?: string | undefined; +}; +``` + +参考 [Scroller API Props](/zh-CN/components/scroller#props) diff --git a/packages/opendesign/src/dialog/types.ts b/packages/opendesign/src/dialog/types.ts index 66e1383d..badf76e9 100644 --- a/packages/opendesign/src/dialog/types.ts +++ b/packages/opendesign/src/dialog/types.ts @@ -22,13 +22,15 @@ export interface DialogActionT { export const dialogProps = { ...layerProps, /** - * 是否隐藏可以关闭 + * @zh-CN 是否隐藏对话框的关闭按钮 + * @en-US Whether to hide the close button of the dialog */ hideClose: { type: Boolean, }, /** - * 弹窗尺寸 + * @zh-CN 对话框尺寸 + * @en-US Dialog size */ size: { type: String as PropType, @@ -36,25 +38,29 @@ export const dialogProps = { }, /** - * 弹窗底部按钮 + * @zh-CN 对话框底部按钮 + * @en-US Dialog bottom button */ actions: { type: Array as PropType, }, /** - * 是否响应式 + * @zh-CN 是否禁用响应式 + * @en-US Whether to disable responsive */ noResponsive: { type: Boolean, }, /** - * 移动端响应为半屏 + * @zh-CN 移动端是否渲染为半屏(宽度占满,高度占一半) + * @en-US Whether to render as half screen (width full, height half) on mobile phone */ phoneHalfFull: { type: Boolean, }, /** - * 是否使用scrollbar + * @zh-CN 是否使用scrollbar,值为 false 不使用,值为 true 或 scrollbar 的配置对象则使用 + * @en-US Whether to use scrollbar, value false not use, value true or scrollbar configuration object to use */ scrollbar: { type: [Boolean, Object] as PropType>, -- Gitee