@xihan-ui/vue 3.1.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +160 -0
- package/dist/components/carousel/carousel.d.ts +7 -1
- package/dist/components/carousel/carousel.d.ts.map +1 -1
- package/dist/components/carousel/carousel.js +1 -0
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/cartesian-chart/cartesian-chart.d.ts.map +1 -1
- package/dist/components/cartesian-chart/cartesian-chart.js +2 -2
- package/dist/components/cartesian-chart/cartesian-chart.js.map +1 -1
- package/dist/components/cascader/cascader.js +2 -1
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/citation/citation.d.ts.map +1 -1
- package/dist/components/citation/citation.js +8 -6
- package/dist/components/citation/citation.js.map +1 -1
- package/dist/components/color-picker/color-picker.js +2 -1
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/combobox/combobox.js +3 -3
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.d.ts +3 -3
- package/dist/components/context-menu/context-menu.js +2 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/date-picker/date-picker.d.ts +4 -1
- package/dist/components/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/date-picker.js +9 -1
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts +4 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +9 -1
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/dialog/dialog.d.ts +12 -1
- package/dist/components/dialog/dialog.d.ts.map +1 -1
- package/dist/components/dialog/dialog.js +14 -4
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/drawer/drawer.d.ts +12 -1
- package/dist/components/drawer/drawer.d.ts.map +1 -1
- package/dist/components/drawer/drawer.js +14 -4
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/fieldset/context.d.ts +1 -0
- package/dist/components/fieldset/context.d.ts.map +1 -1
- package/dist/components/fieldset/context.js +9 -1
- package/dist/components/fieldset/context.js.map +1 -1
- package/dist/components/fieldset/fieldset.d.ts.map +1 -1
- package/dist/components/fieldset/fieldset.js +8 -3
- package/dist/components/fieldset/fieldset.js.map +1 -1
- package/dist/components/floating-panel/floating-panel.js +4 -1
- package/dist/components/floating-panel/floating-panel.js.map +1 -1
- package/dist/components/form/form.d.ts +8 -0
- package/dist/components/form/form.d.ts.map +1 -1
- package/dist/components/form/form.js +4 -1
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/funnel-chart/funnel-chart.d.ts.map +1 -1
- package/dist/components/funnel-chart/funnel-chart.js +2 -2
- package/dist/components/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/graph-chart/graph-chart.d.ts.map +1 -1
- package/dist/components/graph-chart/graph-chart.js +2 -2
- package/dist/components/graph-chart/graph-chart.js.map +1 -1
- package/dist/components/hierarchy-chart/hierarchy-chart.d.ts.map +1 -1
- package/dist/components/hierarchy-chart/hierarchy-chart.js +2 -2
- package/dist/components/hierarchy-chart/hierarchy-chart.js.map +1 -1
- package/dist/components/hover-card/hover-card.js +2 -1
- package/dist/components/hover-card/hover-card.js.map +1 -1
- package/dist/components/image-viewer/image-viewer.d.ts +7 -1
- package/dist/components/image-viewer/image-viewer.d.ts.map +1 -1
- package/dist/components/image-viewer/image-viewer.js +1 -0
- package/dist/components/image-viewer/image-viewer.js.map +1 -1
- package/dist/components/mention/mention.d.ts +1 -1
- package/dist/components/mention/mention.js +5 -4
- package/dist/components/mention/mention.js.map +1 -1
- package/dist/components/menu/menu.js +2 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menubar/context.d.ts.map +1 -1
- package/dist/components/menubar/context.js.map +1 -1
- package/dist/components/menubar/menubar.d.ts.map +1 -1
- package/dist/components/menubar/menubar.js +16 -2
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/pagination/pagination.js +4 -2
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/components/pie-chart/pie-chart.js +2 -2
- package/dist/components/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.js +2 -1
- package/dist/components/popconfirm/popconfirm.js.map +1 -1
- package/dist/components/popover/popover.d.ts +1 -1
- package/dist/components/popover/popover.js +2 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/radar-chart/radar-chart.d.ts.map +1 -1
- package/dist/components/radar-chart/radar-chart.js +2 -2
- package/dist/components/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/sankey-chart/sankey-chart.d.ts.map +1 -1
- package/dist/components/sankey-chart/sankey-chart.js +2 -2
- package/dist/components/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/select/select.d.ts +11 -0
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +12 -3
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/side-nav/side-nav.d.ts.map +1 -1
- package/dist/components/side-nav/side-nav.js +8 -2
- package/dist/components/side-nav/side-nav.js.map +1 -1
- package/dist/components/spinner/spinner.d.ts +9 -1
- package/dist/components/spinner/spinner.d.ts.map +1 -1
- package/dist/components/spinner/spinner.js +2 -0
- package/dist/components/spinner/spinner.js.map +1 -1
- package/dist/components/time-picker/time-picker.d.ts +4 -1
- package/dist/components/time-picker/time-picker.d.ts.map +1 -1
- package/dist/components/time-picker/time-picker.js +10 -2
- package/dist/components/time-picker/time-picker.js.map +1 -1
- package/dist/components/time-range-picker/time-range-picker.js +2 -1
- package/dist/components/time-range-picker/time-range-picker.js.map +1 -1
- package/dist/components/tooltip/tooltip.js +2 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tour/tour.js +12 -3
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/tree-select/tree-select.js +3 -3
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/config/config.js +1 -0
- package/dist/config/config.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/locale.d.ts +2 -0
- package/dist/locale.js +2 -0
- package/dist/package.js +1 -1
- package/dist/runtime/as-child.js +7 -2
- package/dist/runtime/as-child.js.map +1 -1
- package/dist/runtime/portal.js +11 -1
- package/dist/runtime/portal.js.map +1 -1
- package/dist/runtime/use-overlay-exit.js +6 -1
- package/dist/runtime/use-overlay-exit.js.map +1 -1
- package/dist/services/dialog-service.d.ts +3 -3
- package/dist/services/dialog-service.d.ts.map +1 -1
- package/dist/services/dialog-service.js +8 -6
- package/dist/services/dialog-service.js.map +1 -1
- package/dist/services/service-config.js +2 -1
- package/dist/services/service-config.js.map +1 -1
- package/package.json +19 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnel-chart.js","names":[],"sources":["../../../src/components/funnel-chart/funnel-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 funnel chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n ChartPalette,\n ChartRow,\n FunnelAlign,\n FunnelChartApi,\n FunnelChartSchema,\n FunnelChartTranslations,\n FunnelConversion,\n FunnelDirection,\n FunnelLabels,\n FunnelShape,\n FunnelTooltipModel,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideFunnelChart, useFunnelChartContext } from './context'\nimport { useFunnelChart } from './use-funnel-chart'\n\ntype FunnelChartProps = FunnelChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type FunnelChartRootSlotProps = Pick<FunnelChartApi, 'active' | 'tooltip' | 'empty' | 'hiddenSeries' | 'activeKey' | 'toggleSeries' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的阶段与缺省的内容模型。 */\nexport interface FunnelChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: FunnelTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: FunnelChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是阶段名,下面是数值与两种转化率。 */\nfunction renderTooltipContent(api: FunnelChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipSwatchProps(row) as Record<string, unknown>),\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: FunnelChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhFunnelChartCaption = defineComponent({\n name: 'XhFunnelChartCaption',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhFunnelChartViewport = defineComponent({\n name: 'XhFunnelChartViewport',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:阶段在下,阶段标签与转化率在上,焦点环最上。 */\nexport const XhFunnelChartPlot = defineComponent({\n name: 'XhFunnelChartPlot',\n setup() {\n const ctx = useFunnelChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的阶段生成,作用域插槽可替换。 */\nexport const XhFunnelChartTooltip = defineComponent({\n name: 'XhFunnelChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: FunnelChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhFunnelChartEmpty = defineComponent({\n name: 'XhFunnelChartEmpty',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhFunnelChartRoot = defineComponent({\n name: 'XhFunnelChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n data: { type: Array as PropType<readonly ChartRow[]> },\n nameField: { type: String },\n valueField: { type: String },\n shape: { type: String as PropType<FunnelShape> },\n align: { type: String as PropType<FunnelAlign> },\n direction: { type: String as PropType<FunnelDirection> },\n conversion: { type: String as PropType<FunnelConversion> },\n labels: { type: String as PropType<FunnelLabels> },\n palette: { type: String as PropType<ChartPalette> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n hiddenSeries: { type: Array as PropType<string[]> },\n defaultHiddenSeries: { type: Array as PropType<string[]> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<FunnelChartTranslations>> },\n },\n // hidden-series-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'hidden-series-change': (_details: PayloadOf<FunnelChartProps, 'onHiddenSeriesChange'>) => true,\n 'update:hiddenSeries': (_hidden: PayloadOf<FunnelChartProps, 'onHiddenSeriesChange'>['hiddenSeries']) => true,\n 'active-key-change': (_details: PayloadOf<FunnelChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<FunnelChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<FunnelChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<FunnelChartProps, 'onDatumPress'>) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:视口(绘图区与空态)、提示框。 */\n default?: (props: FunnelChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: FunnelChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useFunnelChart(withXhConfig('funnel-chart', props) as FunnelChartProps, {\n onHiddenSeriesChange: (details) => {\n emit('hidden-series-change', details)\n emit('update:hiddenSeries', details.hiddenSeries)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n })\n provideFunnelChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n hiddenSeries: api.hiddenSeries,\n activeKey: api.activeKey,\n toggleSeries: api.toggleSeries,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhFunnelChartCaption, null, () => slots.caption?.())] : []),\n // 空态放进视口:叠在绘图区上,标题与图例不被盖住\n h(XhFunnelChartViewport, null, () => [\n h(XhFunnelChartPlot),\n h(XhFunnelChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhFunnelChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":";;;;;;AA2CA,SAAS,WAAW,KAAqB,MAAwB;CAC/D,MAAM,QAAQ;EAAE,GAAG,IAAI,aAAa,IAAI;EAA8B,KAAK,KAAK;CAAI;CACpF,IAAI,KAAK,SAAS,SAChB,OAAO,EAAE,KAAK,OAAO,KAAK,SAAS,KAAI,UAAS,WAAW,KAAK,KAAK,CAAC,CAAC;CACzE,IAAI,KAAK,SAAS,QAChB,OAAO,EAAE,QAAQ,OAAO,KAAK,IAAI;CACnC,OAAO,EAAE,QAAQ,KAAK;AACxB;;AAGA,SAAS,qBAAqB,KAA8B;CAC1D,MAAM,UAAU,IAAI;CACpB,IAAI,CAAC,SACH,OAAO,CAAC;CACV,OAAO,CACL,EAAE,OAAO,IAAI,sBAAsB,GAA8B,QAAQ,MAAM,GAC/E,GAAG,QAAQ,KAAK,KAAI,QAAO,EAAE,OAAO;EAAE,GAAG,IAAI,mBAAmB,GAAG;EAA8B,KAAK,IAAI;CAAI,GAAG;EAC/G,EAAE,QAAQ,IAAI,sBAAsB,GAAG,CAA4B;EACnE,EAAE,QAAQ,IAAI,qBAAqB,GAAG,GAA8B,IAAI,KAAK;EAC7E,EAAE,QAAQ,IAAI,oBAAoB,GAAG,GAA8B,IAAI,IAAI;CAC7E,CAAC,CAAC,CACJ;AACF;;AAGA,SAAS,WAAW,KAA8B;CAChD,MAAM,EAAE,SAAS,SAAS,IAAI;CAC9B,OAAO,CACL,EAAE,KAAK,IAAI,gBAAgB,GAA8B,IAAI,OAAO,GACpE,EAAE,SAAS,IAAI,cAAc,GAA8B;EACzD,EAAE,WAAW,IAAI,YAAY;EAC7B,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAI,WAAU,EAAE,MAAM;GAAE,KAAK,OAAO;GAAI,OAAO;EAAM,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;EACpG,EAAE,SAAS,KAAK,KAAK,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,MAAM,KAAK,MAAM,MACvE,MAAM,IAAI,EAAE,MAAM;GAAE,KAAK;GAAG,OAAO;EAAM,GAAG,KAAK,IAAI,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;CAC9F,CAAC,CACH;AACF;;AAGA,MAAa,uBAAuB,gBAAgB;CAClD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa,EAAE,cAAc,IAAI,IAAI,MAAM,gBAAgB,GAA8B,MAAM,UAAU,CAAC;CAC5G;AACF,CAAC;;AAGD,MAAa,wBAAwB,gBAAgB;CACnD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa,EAAE,OAAO;GACpB,GAAG,IAAI,IAAI,MAAM,iBAAiB;GAClC,MAAM,OAAgB;IAAE,IAAI,YAAY,QAAQ;GAAkB;EACpE,GAAG,MAAM,UAAU,CAAC;CACtB;AACF,CAAC;;AAGD,MAAa,oBAAoB,gBAAgB;CAC/C,MAAM;CACN,QAAQ;EACN,MAAM,MAAM,sBAAsB;EAClC,aAAa;GACX,MAAM,MAAM,IAAI,IAAI;GACpB,MAAM,QAAQ;IAAC,GAAG,IAAI,MAAM,OAAO;IAAM,GAAG,IAAI,MAAM,OAAO;IAAO,GAAG,IAAI,QAAQ;GAAI;GACvF,OAAO,EAAE,OAAO,IAAI,aAAa,GAA8B,MAAM,KAAI,SAAQ,WAAW,KAAK,IAAI,CAAC,CAAC;EACzG;CACF;AACF,CAAC;;AAGD,MAAa,uBAAuB,gBAAgB;CAClD,MAAM;CACN,OAAO;CAGP,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa;GACX,MAAM,MAAM,IAAI,IAAI;GACpB,OAAO,EAAE,OAAO,IAAI,gBAAgB,GAA8B,MAAM,UACpE,MAAM,QAAQ;IAAE,QAAQ,IAAI;IAAQ,SAAS,IAAI;GAAQ,CAAC,IAC1D,qBAAqB,GAAG,CAAC;EAC/B;CACF;AACF,CAAC;;AAGD,MAAa,qBAAqB,gBAAgB;CAChD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa,EAAE,OAAO,IAAI,IAAI,MAAM,cAAc,GAA8B,MAAM,UAAU,KAAK,IAAI,IAAI,MAAM,SAAS;CAC9H;AACF,CAAC;;AAGD,MAAa,oBAAoB,gBAAgB;CAC/C,MAAM;CAEN,OAAO;EACL,MAAM,EAAE,MAAM,MAAuC;EACrD,WAAW,EAAE,MAAM,OAAO;EAC1B,YAAY,EAAE,MAAM,OAAO;EAC3B,OAAO,EAAE,MAAM,OAAgC;EAC/C,OAAO,EAAE,MAAM,OAAgC;EAC/C,WAAW,EAAE,MAAM,OAAoC;EACvD,YAAY,EAAE,MAAM,OAAqC;EACzD,QAAQ,EAAE,MAAM,OAAiC;EACjD,SAAS,EAAE,MAAM,OAAiC;EAClD,QAAQ,EAAE,MAAM,CAAC,QAAQ,QAAQ,EAA8D;EAC/F,cAAc,EAAE,MAAM,MAA4B;EAClD,qBAAqB,EAAE,MAAM,MAA4B;EACzD,WAAW,EAAE,MAAM;GAAC;GAAQ;GAAQ;GAAM;EAAI,EAA+B;EAC7E,SAAS;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC7C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC9C,QAAQ,EAAE,MAAM,OAAO;EACvB,cAAc,EAAE,MAAM,OAAqD;CAC7E;CAEA,OAAO;EACL,yBAAyB,aAAkE;EAC3F,wBAAwB,YAAiF;EACzG,sBAAsB,aAA+D;EACrF,qBAAqB,SAAwE;EAC7F,iBAAiB,aAA2D;EAC5E,gBAAgB,aAA0D;CAC5E;CACA,OAAO;CAUP,MAAM,OAAO,EAAE,OAAO,QAAQ;EAC5B,MAAM,MAAM,eAAe,aAAa,gBAAgB,KAAK,GAAuB;GAClF,uBAAuB,YAAY;IACjC,KAAK,wBAAwB,OAAO;IACpC,KAAK,uBAAuB,QAAQ,YAAY;GAClD;GACA,oBAAoB,YAAY;IAC9B,KAAK,qBAAqB,OAAO;IACjC,KAAK,oBAAoB,QAAQ,SAAS;GAC5C;GACA,gBAAe,YAAW,KAAK,gBAAgB,OAAO;GACtD,eAAc,YAAW,KAAK,eAAe,OAAO;EACtD,CAAC;EACD,mBAAmB,GAAG;EACtB,aAAa;GACX,MAAM,MAAM,IAAI,IAAI;GACpB,MAAM,UAAU,MAAM,UAClB,MAAM,QAAQ;IACZ,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,OAAO,IAAI;IACX,OAAO,IAAI;IACX,cAAc,IAAI;IAClB,WAAW,IAAI;IACf,cAAc,IAAI;IAClB,iBAAiB,IAAI;GACvB,CAAC,IACD;IACE,GAAI,MAAM,UAAU,CAAC,EAAE,sBAAsB,YAAY,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC;IAEhF,EAAE,uBAAuB,YAAY,CACnC,EAAE,iBAAiB,GACnB,EAAE,oBAAoB,MAAM,MAAM,cAAc,MAAM,QAAQ,IAAI,KAAA,CAAS,CAC7E,CAAC;IACD,EAAE,sBAAsB,MAAM,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,KAAA,CAAS;GACtF;GACJ,OAAO,EAAE,UAAU;IACjB,GAAG,IAAI,aAAa;IACpB,MAAM,OAAgB;KAAE,IAAI,QAAQ,QAAQ;IAAkB;GAChE,GAAG,CAAC,GAAG,SAAS,GAAG,WAAW,GAAG,CAAC,CAAC;EACrC;CACF;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"funnel-chart.js","names":[],"sources":["../../../src/components/funnel-chart/funnel-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 funnel chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n ChartPalette,\n ChartRow,\n FunnelAlign,\n FunnelChartApi,\n FunnelChartSchema,\n FunnelChartTranslations,\n FunnelConversion,\n FunnelDirection,\n FunnelLabels,\n FunnelShape,\n FunnelTooltipModel,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideFunnelChart, useFunnelChartContext } from './context'\nimport { useFunnelChart } from './use-funnel-chart'\n\ntype FunnelChartProps = FunnelChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type FunnelChartRootSlotProps = Pick<FunnelChartApi, 'active' | 'tooltip' | 'empty' | 'hiddenSeries' | 'activeKey' | 'toggleSeries' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的阶段与缺省的内容模型。 */\nexport interface FunnelChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: FunnelTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: FunnelChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是阶段名,下面是数值与两种转化率。 */\nfunction renderTooltipContent(api: FunnelChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipSwatchProps(row) as Record<string, unknown>),\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: FunnelChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n // 视觉隐藏落在包着表格的区域上,表格在里面照常排版:隐藏写在表格上收不住它的高度\n h('div', api.getTableRegionProps() as Record<string, unknown>, [\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhFunnelChartCaption = defineComponent({\n name: 'XhFunnelChartCaption',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhFunnelChartViewport = defineComponent({\n name: 'XhFunnelChartViewport',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:阶段在下,阶段标签与转化率在上,焦点环最上。 */\nexport const XhFunnelChartPlot = defineComponent({\n name: 'XhFunnelChartPlot',\n setup() {\n const ctx = useFunnelChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的阶段生成,作用域插槽可替换。 */\nexport const XhFunnelChartTooltip = defineComponent({\n name: 'XhFunnelChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: FunnelChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhFunnelChartEmpty = defineComponent({\n name: 'XhFunnelChartEmpty',\n setup(_, { slots }) {\n const ctx = useFunnelChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhFunnelChartRoot = defineComponent({\n name: 'XhFunnelChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n data: { type: Array as PropType<readonly ChartRow[]> },\n nameField: { type: String },\n valueField: { type: String },\n shape: { type: String as PropType<FunnelShape> },\n align: { type: String as PropType<FunnelAlign> },\n direction: { type: String as PropType<FunnelDirection> },\n conversion: { type: String as PropType<FunnelConversion> },\n labels: { type: String as PropType<FunnelLabels> },\n palette: { type: String as PropType<ChartPalette> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n hiddenSeries: { type: Array as PropType<string[]> },\n defaultHiddenSeries: { type: Array as PropType<string[]> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<FunnelChartTranslations>> },\n },\n // hidden-series-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'hidden-series-change': (_details: PayloadOf<FunnelChartProps, 'onHiddenSeriesChange'>) => true,\n 'update:hiddenSeries': (_hidden: PayloadOf<FunnelChartProps, 'onHiddenSeriesChange'>['hiddenSeries']) => true,\n 'active-key-change': (_details: PayloadOf<FunnelChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<FunnelChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<FunnelChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<FunnelChartProps, 'onDatumPress'>) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:视口(绘图区与空态)、提示框。 */\n default?: (props: FunnelChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: FunnelChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useFunnelChart(withXhConfig('funnel-chart', props) as FunnelChartProps, {\n onHiddenSeriesChange: (details) => {\n emit('hidden-series-change', details)\n emit('update:hiddenSeries', details.hiddenSeries)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n })\n provideFunnelChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n hiddenSeries: api.hiddenSeries,\n activeKey: api.activeKey,\n toggleSeries: api.toggleSeries,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhFunnelChartCaption, null, () => slots.caption?.())] : []),\n // 空态放进视口:叠在绘图区上,标题与图例不被盖住\n h(XhFunnelChartViewport, null, () => [\n h(XhFunnelChartPlot),\n h(XhFunnelChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhFunnelChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-chart.d.ts","names":[],"sources":["../../../src/components/graph-chart/graph-chart.ts"],"mappings":";;;;KA4BK,kBAAkB;;KAGX,0BAA0B,KAAK;;UAG1B;EACf,QAAQ;EACR,SAAS;;;
|
|
1
|
+
{"version":3,"file":"graph-chart.d.ts","names":[],"sources":["../../../src/components/graph-chart/graph-chart.ts"],"mappings":";;;;KA4BK,kBAAkB;;KAGX,0BAA0B,KAAK;;UAG1B;EACf,QAAQ;EACR,SAAS;;;cA6CE,mCAAmB,0BAAA,oBAAA,4BAAA;;8BAM9B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAa7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAS/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAU3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,mCAAmB,0BAAA,oBAAA,4BAAA;;;EAGlB,WAAC,OAAO,+BAA+B;kCAWnD;;cAGW,iCAAiB,0BAAA,oBAAA,4BAAA;;8BAM5B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,gCAAgB,8BAAA;;IAID,MAAA,kBAAkB;;;IAClB,MAAA,kBAAkB;;;IAChB,MAAA,SAAS;;;;;;;;;;;;;;;;;;;IAMX,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACF,MAAA,SAAS,qBAAqB;;;IACrC,MAAA;;;IACO,MAAA;;;IACa,MAAA,SAAS;;;;;;;;;;;;;;IAI5B,MAAA,SAAS,QAAQ;;;;;EAId,yBAAA,UAAA,UAAU;EACZ,wBAAA,SAAA,UAAU;EACX,sBAAA,UAAA,UAAU;EACf,qBAAA,MAAA,UAAU;EACV,iBAAA,UAAA,UAAU;EACX,gBAAA,UAAA,UAAU;EACV,gBAAA,UAAA,UAAU;EACb,gBAAA,OAAA,UAAU;;;IA5BT,MAAA,kBAAkB;;;IAClB,MAAA,kBAAkB;;;IAChB,MAAA,SAAS;;;;;;;;;;;;;;;;;;;IAMX,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACF,MAAA,SAAS,qBAAqB;;;IACrC,MAAA;;;IACO,MAAA;;;IACa,MAAA,SAAS;;;;;;;;;;;;;;IAI5B,MAAA,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;EAevC,WAAC,OAAO,4BAA4B;;EAEpC,gBAAM;;EAEN,WAAC,OAAO,+BAA+B;;EAEzC,cAAM;kCAqDhB"}
|
|
@@ -25,7 +25,7 @@ function renderTooltipContent(api) {
|
|
|
25
25
|
/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */
|
|
26
26
|
function renderA11y(api) {
|
|
27
27
|
const { columns, rows } = api.table;
|
|
28
|
-
return [h("p", api.getSummaryProps(), api.summary), h("table", api.getTableProps(), [
|
|
28
|
+
return [h("p", api.getSummaryProps(), api.summary), h("div", api.getTableRegionProps(), [h("table", api.getTableProps(), [
|
|
29
29
|
h("caption", api.tableCaption),
|
|
30
30
|
h("thead", [h("tr", columns.map((column) => h("th", {
|
|
31
31
|
key: column.id,
|
|
@@ -35,7 +35,7 @@ function renderA11y(api) {
|
|
|
35
35
|
key: c,
|
|
36
36
|
scope: "row"
|
|
37
37
|
}, cell.text) : h("td", { key: c }, cell.text)))))
|
|
38
|
-
])];
|
|
38
|
+
])])];
|
|
39
39
|
}
|
|
40
40
|
/** 标题:图表的可及名来源。 */
|
|
41
41
|
const XhGraphChartCaption = defineComponent({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-chart.js","names":[],"sources":["../../../src/components/graph-chart/graph-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 graph chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n GraphChartApi,\n GraphChartSchema,\n GraphChartTranslations,\n GraphLayout,\n GraphLinkDatum,\n GraphNodeDatum,\n GraphTooltipModel,\n GraphView,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideGraphChart, useGraphChartContext } from './context'\nimport { useGraphChart } from './use-graph-chart'\n\ntype GraphChartProps = GraphChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type GraphChartRootSlotProps = Pick<GraphChartApi, 'legendItems' | 'active' | 'tooltip' | 'empty' | 'hiddenSeries' | 'activeKey' | 'view' | 'toggleSeries' | 'zoomBy' | 'resetView' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的节点与缺省的内容模型。 */\nexport interface GraphChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: GraphTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: GraphChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是节点名,下面是数值与连线数。 */\nfunction renderTooltipContent(api: GraphChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: GraphChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhGraphChartCaption = defineComponent({\n name: 'XhGraphChartCaption',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 图例:项由组件按分组生成;不到两组时整条收起。 */\nexport const XhGraphChartLegend = defineComponent({\n name: 'XhGraphChartLegend',\n setup() {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getLegendProps() as Record<string, unknown>, api.legendItems.map(item =>\n h('button', { ...api.getLegendItemProps(item) as Record<string, unknown>, key: item.id }, [\n h('span', api.getLegendSwatchProps(item) as Record<string, unknown>),\n h('span', api.getLegendLabelProps(item) as Record<string, unknown>, item.name),\n ])))\n }\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhGraphChartViewport = defineComponent({\n name: 'XhGraphChartViewport',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:连线在下,箭头其上,节点再上,节点名与焦点环最上。 */\nexport const XhGraphChartPlot = defineComponent({\n name: 'XhGraphChartPlot',\n setup() {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的节点生成,作用域插槽可替换。 */\nexport const XhGraphChartTooltip = defineComponent({\n name: 'XhGraphChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: GraphChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhGraphChartEmpty = defineComponent({\n name: 'XhGraphChartEmpty',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhGraphChartRoot = defineComponent({\n name: 'XhGraphChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n nodes: { type: Array as PropType<readonly GraphNodeDatum[]> },\n links: { type: Array as PropType<readonly GraphLinkDatum[]> },\n layout: { type: String as PropType<GraphLayout> },\n root: { type: String },\n directed: { type: Boolean, default: undefined },\n draggableNodes: { type: Boolean, default: undefined },\n zoom: { type: Boolean, default: undefined },\n /** 画布视图:给了即受控,配合 v-model:view。 */\n view: { type: Object as PropType<GraphView> },\n defaultView: { type: Object as PropType<GraphView> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n hiddenSeries: { type: Array as PropType<string[]> },\n defaultHiddenSeries: { type: Array as PropType<string[]> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<GraphChartTranslations>> },\n },\n // hidden-series-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'hidden-series-change': (_details: PayloadOf<GraphChartProps, 'onHiddenSeriesChange'>) => true,\n 'update:hiddenSeries': (_hidden: PayloadOf<GraphChartProps, 'onHiddenSeriesChange'>['hiddenSeries']) => true,\n 'active-key-change': (_details: PayloadOf<GraphChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<GraphChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<GraphChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<GraphChartProps, 'onDatumPress'>) => true,\n 'view-change': (_details: PayloadOf<GraphChartProps, 'onViewChange'>) => true,\n 'update:view': (_view: PayloadOf<GraphChartProps, 'onViewChange'>['view']) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:图例、视口(绘图区与空态)、提示框。 */\n default?: (props: GraphChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: GraphChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useGraphChart(withXhConfig('graph-chart', props) as GraphChartProps, {\n onHiddenSeriesChange: (details) => {\n emit('hidden-series-change', details)\n emit('update:hiddenSeries', details.hiddenSeries)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n onViewChange: (details) => {\n emit('view-change', details)\n emit('update:view', details.view)\n },\n })\n provideGraphChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n legendItems: api.legendItems,\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n hiddenSeries: api.hiddenSeries,\n activeKey: api.activeKey,\n view: api.view,\n toggleSeries: api.toggleSeries,\n zoomBy: api.zoomBy,\n resetView: api.resetView,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhGraphChartCaption, null, () => slots.caption?.())] : []),\n h(XhGraphChartLegend),\n // 空态放进视口:叠在绘图区上,标题与图例不被盖住\n h(XhGraphChartViewport, null, () => [\n h(XhGraphChartPlot),\n h(XhGraphChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhGraphChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"graph-chart.js","names":[],"sources":["../../../src/components/graph-chart/graph-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 graph chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n GraphChartApi,\n GraphChartSchema,\n GraphChartTranslations,\n GraphLayout,\n GraphLinkDatum,\n GraphNodeDatum,\n GraphTooltipModel,\n GraphView,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideGraphChart, useGraphChartContext } from './context'\nimport { useGraphChart } from './use-graph-chart'\n\ntype GraphChartProps = GraphChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type GraphChartRootSlotProps = Pick<GraphChartApi, 'legendItems' | 'active' | 'tooltip' | 'empty' | 'hiddenSeries' | 'activeKey' | 'view' | 'toggleSeries' | 'zoomBy' | 'resetView' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的节点与缺省的内容模型。 */\nexport interface GraphChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: GraphTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: GraphChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是节点名,下面是数值与连线数。 */\nfunction renderTooltipContent(api: GraphChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: GraphChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n // 视觉隐藏落在包着表格的区域上,表格在里面照常排版:隐藏写在表格上收不住它的高度\n h('div', api.getTableRegionProps() as Record<string, unknown>, [\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhGraphChartCaption = defineComponent({\n name: 'XhGraphChartCaption',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 图例:项由组件按分组生成;不到两组时整条收起。 */\nexport const XhGraphChartLegend = defineComponent({\n name: 'XhGraphChartLegend',\n setup() {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getLegendProps() as Record<string, unknown>, api.legendItems.map(item =>\n h('button', { ...api.getLegendItemProps(item) as Record<string, unknown>, key: item.id }, [\n h('span', api.getLegendSwatchProps(item) as Record<string, unknown>),\n h('span', api.getLegendLabelProps(item) as Record<string, unknown>, item.name),\n ])))\n }\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhGraphChartViewport = defineComponent({\n name: 'XhGraphChartViewport',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:连线在下,箭头其上,节点再上,节点名与焦点环最上。 */\nexport const XhGraphChartPlot = defineComponent({\n name: 'XhGraphChartPlot',\n setup() {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的节点生成,作用域插槽可替换。 */\nexport const XhGraphChartTooltip = defineComponent({\n name: 'XhGraphChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: GraphChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhGraphChartEmpty = defineComponent({\n name: 'XhGraphChartEmpty',\n setup(_, { slots }) {\n const ctx = useGraphChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhGraphChartRoot = defineComponent({\n name: 'XhGraphChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n nodes: { type: Array as PropType<readonly GraphNodeDatum[]> },\n links: { type: Array as PropType<readonly GraphLinkDatum[]> },\n layout: { type: String as PropType<GraphLayout> },\n root: { type: String },\n directed: { type: Boolean, default: undefined },\n draggableNodes: { type: Boolean, default: undefined },\n zoom: { type: Boolean, default: undefined },\n /** 画布视图:给了即受控,配合 v-model:view。 */\n view: { type: Object as PropType<GraphView> },\n defaultView: { type: Object as PropType<GraphView> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n hiddenSeries: { type: Array as PropType<string[]> },\n defaultHiddenSeries: { type: Array as PropType<string[]> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<GraphChartTranslations>> },\n },\n // hidden-series-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'hidden-series-change': (_details: PayloadOf<GraphChartProps, 'onHiddenSeriesChange'>) => true,\n 'update:hiddenSeries': (_hidden: PayloadOf<GraphChartProps, 'onHiddenSeriesChange'>['hiddenSeries']) => true,\n 'active-key-change': (_details: PayloadOf<GraphChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<GraphChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<GraphChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<GraphChartProps, 'onDatumPress'>) => true,\n 'view-change': (_details: PayloadOf<GraphChartProps, 'onViewChange'>) => true,\n 'update:view': (_view: PayloadOf<GraphChartProps, 'onViewChange'>['view']) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:图例、视口(绘图区与空态)、提示框。 */\n default?: (props: GraphChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: GraphChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useGraphChart(withXhConfig('graph-chart', props) as GraphChartProps, {\n onHiddenSeriesChange: (details) => {\n emit('hidden-series-change', details)\n emit('update:hiddenSeries', details.hiddenSeries)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n onViewChange: (details) => {\n emit('view-change', details)\n emit('update:view', details.view)\n },\n })\n provideGraphChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n legendItems: api.legendItems,\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n hiddenSeries: api.hiddenSeries,\n activeKey: api.activeKey,\n view: api.view,\n toggleSeries: api.toggleSeries,\n zoomBy: api.zoomBy,\n resetView: api.resetView,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhGraphChartCaption, null, () => slots.caption?.())] : []),\n h(XhGraphChartLegend),\n // 空态放进视口:叠在绘图区上,标题与图例不被盖住\n h(XhGraphChartViewport, null, () => [\n h(XhGraphChartPlot),\n h(XhGraphChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhGraphChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchy-chart.d.ts","names":[],"sources":["../../../src/components/hierarchy-chart/hierarchy-chart.ts"],"mappings":";;;;KA6BK,sBAAsB;;KAGf,8BAA8B,KAAK;;UAG9B;EACf,QAAQ;EACR,SAAS;;;
|
|
1
|
+
{"version":3,"file":"hierarchy-chart.d.ts","names":[],"sources":["../../../src/components/hierarchy-chart/hierarchy-chart.ts"],"mappings":";;;;KA6BK,sBAAsB;;KAGf,8BAA8B,KAAK;;UAG9B;EACf,QAAQ;EACR,SAAS;;;cA8CE,uCAAuB,0BAAA,oBAAA,4BAAA;;8BAMlC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAU/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,sCAAsB,0BAAA,oBAAA,4BAAA;;8BAejC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,wCAAwB,0BAAA,oBAAA,4BAAA;;8BASnC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAU/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,uCAAuB,0BAAA,oBAAA,4BAAA;;;EAGtB,WAAC,OAAO,mCAAmC;kCAWvD;;cAGW,qCAAqB,0BAAA,oBAAA,4BAAA;;8BAMhC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,oCAAoB,8BAAA;;IAII,MAAA,SAAS,oBAAoB;;;;;;;;;;;;;;;;;;IAMpC,MAAA,SAAS;;;IACX,MAAA,SAAS;;;;;;IAEN,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACL,MAAA;;;IACI,MAAA;;;IACO,MAAA;;;IACJ,MAAA,SAAS,qBAAqB;;;IACjB,MAAA,SAAS;;;;;;;;;;;;;;IAI5B,MAAA,SAAS,QAAQ;;;;;EAInB,oBAAA,UAAA,UAAU;EACf,mBAAA,MAAA,UAAU;EACH,sBAAA,UAAA,UAAU;EACf,qBAAA,MAAA,UAAU;EACV,iBAAA,UAAA,UAAU;EACX,gBAAA,UAAA,UAAU;;;IA5BH,MAAA,SAAS,oBAAoB;;;;;;;;;;;;;;;;;;IAMpC,MAAA,SAAS;;;IACX,MAAA,SAAS;;;;;;IAEN,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACL,MAAA;;;IACI,MAAA;;;IACO,MAAA;;;IACJ,MAAA,SAAS,qBAAqB;;;IACjB,MAAA,SAAS;;;;;;;;;;;;;;IAI5B,MAAA,SAAS,QAAQ;;;;;;;;;;;;;;EAavC,WAAC,OAAO,gCAAgC;;EAExC,gBAAM;;EAEN,WAAC,OAAO,mCAAmC;;EAE7C,cAAM;kCAgDhB"}
|
|
@@ -29,7 +29,7 @@ function renderTooltipContent(api) {
|
|
|
29
29
|
/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */
|
|
30
30
|
function renderA11y(api) {
|
|
31
31
|
const { columns, rows } = api.table;
|
|
32
|
-
return [h("p", api.getSummaryProps(), api.summary), h("table", api.getTableProps(), [
|
|
32
|
+
return [h("p", api.getSummaryProps(), api.summary), h("div", api.getTableRegionProps(), [h("table", api.getTableProps(), [
|
|
33
33
|
h("caption", api.tableCaption),
|
|
34
34
|
h("thead", [h("tr", columns.map((column) => h("th", {
|
|
35
35
|
key: column.id,
|
|
@@ -39,7 +39,7 @@ function renderA11y(api) {
|
|
|
39
39
|
key: c,
|
|
40
40
|
scope: "row"
|
|
41
41
|
}, cell.text) : h("td", { key: c }, cell.text)))))
|
|
42
|
-
])];
|
|
42
|
+
])])];
|
|
43
43
|
}
|
|
44
44
|
/** 标题:图表的可及名来源。 */
|
|
45
45
|
const XhHierarchyChartCaption = defineComponent({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchy-chart.js","names":[],"sources":["../../../src/components/hierarchy-chart/hierarchy-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 hierarchy chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n ChartPalette,\n ChartRow,\n HierarchyChartApi,\n HierarchyChartSchema,\n HierarchyChartTranslations,\n HierarchyColorBy,\n HierarchyLayout,\n HierarchyTile,\n HierarchyTooltipModel,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideHierarchyChart, useHierarchyChartContext } from './context'\nimport { useHierarchyChart } from './use-hierarchy-chart'\n\ntype HierarchyChartProps = HierarchyChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type HierarchyChartRootSlotProps = Pick<HierarchyChartApi, 'active' | 'tooltip' | 'empty' | 'path' | 'rootKey' | 'activeKey' | 'drillTo' | 'drillUp' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的节点与缺省的内容模型。 */\nexport interface HierarchyChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: HierarchyTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: HierarchyChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是从当前的根到节点的路径,下面是数值与两种占比。 */\nfunction renderTooltipContent(api: HierarchyChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipSwatchProps(row) as Record<string, unknown>),\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: HierarchyChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhHierarchyChartCaption = defineComponent({\n name: 'XhHierarchyChartCaption',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 下钻路径:从最顶层到当前的根,每一项是一个按钮;还在最顶层时收起。 */\nexport const XhHierarchyChartPath = defineComponent({\n name: 'XhHierarchyChartPath',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('nav', api.getPathProps() as Record<string, unknown>, api.path.map(item =>\n h('button', { ...api.getPathItemProps(item) as Record<string, unknown>, key: item.key ?? '' }, item.name)))\n }\n },\n})\n\n/** 图例:按值着色时每个看得见的层一条色阶(名字、低端的值、渐变条、高端的值);其余着色方式收起。 */\nexport const XhHierarchyChartLegend = defineComponent({\n name: 'XhHierarchyChartLegend',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getLegendProps() as Record<string, unknown>, api.legendScales.map(scale =>\n h('div', { ...api.getLegendScaleProps(scale) as Record<string, unknown>, key: scale.level }, [\n h('span', api.getLegendScaleNameProps() as Record<string, unknown>, scale.name),\n h('span', api.getLegendScaleValueProps('min') as Record<string, unknown>, scale.min),\n h('span', api.getLegendScaleBarProps() as Record<string, unknown>),\n h('span', api.getLegendScaleValueProps('max') as Record<string, unknown>, scale.max),\n ])))\n }\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhHierarchyChartViewport = defineComponent({\n name: 'XhHierarchyChartViewport',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:节点由浅到深,名字与分组标题在上,焦点环最上。 */\nexport const XhHierarchyChartPlot = defineComponent({\n name: 'XhHierarchyChartPlot',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的节点生成,作用域插槽可替换。 */\nexport const XhHierarchyChartTooltip = defineComponent({\n name: 'XhHierarchyChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: HierarchyChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhHierarchyChartEmpty = defineComponent({\n name: 'XhHierarchyChartEmpty',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhHierarchyChartRoot = defineComponent({\n name: 'XhHierarchyChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n data: { type: [Object, Array] as PropType<ChartRow | readonly ChartRow[]> },\n childrenField: { type: String },\n idField: { type: String },\n parentField: { type: String },\n nameField: { type: String },\n valueField: { type: String },\n layout: { type: String as PropType<HierarchyLayout> },\n tile: { type: String as PropType<HierarchyTile> },\n depth: { type: Number },\n colorBy: { type: String as PropType<HierarchyColorBy> },\n palette: { type: String as PropType<ChartPalette> },\n orientation: { type: String as PropType<'vertical' | 'horizontal'> },\n rootKey: { type: [String, null] as PropType<string | null> },\n defaultRootKey: { type: [String, null] as PropType<string | null> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<HierarchyChartTranslations>> },\n },\n // root-key-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'root-key-change': (_details: PayloadOf<HierarchyChartProps, 'onRootKeyChange'>) => true,\n 'update:rootKey': (_key: PayloadOf<HierarchyChartProps, 'onRootKeyChange'>['rootKey']) => true,\n 'active-key-change': (_details: PayloadOf<HierarchyChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<HierarchyChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<HierarchyChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<HierarchyChartProps, 'onDatumPress'>) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:下钻路径、视口(绘图区与空态)、提示框。 */\n default?: (props: HierarchyChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: HierarchyChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useHierarchyChart(withXhConfig('hierarchy-chart', props) as HierarchyChartProps, {\n onRootKeyChange: (details) => {\n emit('root-key-change', details)\n emit('update:rootKey', details.rootKey)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n })\n provideHierarchyChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n path: api.path,\n rootKey: api.rootKey,\n activeKey: api.activeKey,\n drillTo: api.drillTo,\n drillUp: api.drillUp,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhHierarchyChartCaption, null, () => slots.caption?.())] : []),\n h(XhHierarchyChartPath),\n h(XhHierarchyChartLegend),\n // 空态放进视口:叠在绘图区上,标题与路径不被盖住\n h(XhHierarchyChartViewport, null, () => [\n h(XhHierarchyChartPlot),\n h(XhHierarchyChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhHierarchyChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hierarchy-chart.js","names":[],"sources":["../../../src/components/hierarchy-chart/hierarchy-chart.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 hierarchy chart 相关实现。\n\nimport type {\n ChartDatumDetails,\n ChartKey,\n ChartMark,\n ChartPalette,\n ChartRow,\n HierarchyChartApi,\n HierarchyChartSchema,\n HierarchyChartTranslations,\n HierarchyColorBy,\n HierarchyLayout,\n HierarchyTile,\n HierarchyTooltipModel,\n NumberFormatSpec,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideHierarchyChart, useHierarchyChartContext } from './context'\nimport { useHierarchyChart } from './use-hierarchy-chart'\n\ntype HierarchyChartProps = HierarchyChartSchema['props']\n\n/** 默认插槽的载荷:自行摆放部件时用得上的状态与动作。 */\nexport type HierarchyChartRootSlotProps = Pick<HierarchyChartApi, 'active' | 'tooltip' | 'empty' | 'path' | 'rootKey' | 'activeKey' | 'drillTo' | 'drillUp' | 'setFocusedDatum' | 'table'>\n\n/** 提示框插槽的载荷:激活的节点与缺省的内容模型。 */\nexport interface HierarchyChartTooltipSlotProps {\n active: ChartDatumDetails | null\n tooltip: HierarchyTooltipModel | null\n}\n\n/** 一个场景标记画成 SVG 元素;文字标记带文字。 */\nfunction renderMark(api: HierarchyChartApi, mark: ChartMark): VNode {\n const props = { ...api.getMarkProps(mark) as Record<string, unknown>, key: mark.key }\n if (mark.kind === 'group')\n return h('g', props, mark.children.map(child => renderMark(api, child)))\n if (mark.kind === 'text')\n return h('text', props, mark.text)\n return h('path', props)\n}\n\n/** 缺省的提示框内容:头部是从当前的根到节点的路径,下面是数值与两种占比。 */\nfunction renderTooltipContent(api: HierarchyChartApi): VNode[] {\n const tooltip = api.tooltip\n if (!tooltip)\n return []\n return [\n h('div', api.getTooltipHeaderProps() as Record<string, unknown>, tooltip.header),\n ...tooltip.rows.map(row => h('div', { ...api.getTooltipRowProps(row) as Record<string, unknown>, key: row.key }, [\n h('span', api.getTooltipSwatchProps(row) as Record<string, unknown>),\n h('span', api.getTooltipValueProps(row) as Record<string, unknown>, row.value),\n h('span', api.getTooltipNameProps(row) as Record<string, unknown>, row.name),\n ])),\n ]\n}\n\n/** 摘要与数据表:由根自动生成、视觉隐藏,保证无障碍等价物始终存在。 */\nfunction renderA11y(api: HierarchyChartApi): VNode[] {\n const { columns, rows } = api.table\n return [\n h('p', api.getSummaryProps() as Record<string, unknown>, api.summary),\n // 视觉隐藏落在包着表格的区域上,表格在里面照常排版:隐藏写在表格上收不住它的高度\n h('div', api.getTableRegionProps() as Record<string, unknown>, [\n h('table', api.getTableProps() as Record<string, unknown>, [\n h('caption', api.tableCaption),\n h('thead', [h('tr', columns.map(column => h('th', { key: column.id, scope: 'col' }, column.label)))]),\n h('tbody', rows.map((row, i) => h('tr', { key: i }, row.cells.map((cell, c) =>\n c === 0 ? h('th', { key: c, scope: 'row' }, cell.text) : h('td', { key: c }, cell.text))))),\n ]),\n ]),\n ]\n}\n\n/** 标题:图表的可及名来源。 */\nexport const XhHierarchyChartCaption = defineComponent({\n name: 'XhHierarchyChartCaption',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('figcaption', ctx.api.value.getCaptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 下钻路径:从最顶层到当前的根,每一项是一个按钮;还在最顶层时收起。 */\nexport const XhHierarchyChartPath = defineComponent({\n name: 'XhHierarchyChartPath',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('nav', api.getPathProps() as Record<string, unknown>, api.path.map(item =>\n h('button', { ...api.getPathItemProps(item) as Record<string, unknown>, key: item.key ?? '' }, item.name)))\n }\n },\n})\n\n/** 图例:按值着色时每个看得见的层一条色阶(名字、低端的值、渐变条、高端的值);其余着色方式收起。 */\nexport const XhHierarchyChartLegend = defineComponent({\n name: 'XhHierarchyChartLegend',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getLegendProps() as Record<string, unknown>, api.legendScales.map(scale =>\n h('div', { ...api.getLegendScaleProps(scale) as Record<string, unknown>, key: scale.level }, [\n h('span', api.getLegendScaleNameProps() as Record<string, unknown>, scale.name),\n h('span', api.getLegendScaleValueProps('min') as Record<string, unknown>, scale.min),\n h('span', api.getLegendScaleBarProps() as Record<string, unknown>),\n h('span', api.getLegendScaleValueProps('max') as Record<string, unknown>, scale.max),\n ])))\n }\n },\n})\n\n/** 视口:尺寸观测的宿主,块尺寸由组件槽决定。 */\nexport const XhHierarchyChartViewport = defineComponent({\n name: 'XhHierarchyChartViewport',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('div', {\n ...ctx.api.value.getViewportProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.viewportRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\n/** 绘图区:节点由浅到深,名字与分组标题在上,焦点环最上。 */\nexport const XhHierarchyChartPlot = defineComponent({\n name: 'XhHierarchyChartPlot',\n setup() {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n const marks = [...api.scene.layers.data, ...api.scene.layers.front, ...api.overlay.over]\n return h('svg', api.getPlotProps() as Record<string, unknown>, marks.map(mark => renderMark(api, mark)))\n }\n },\n})\n\n/** 提示框:缺省内容按激活的节点生成,作用域插槽可替换。 */\nexport const XhHierarchyChartTooltip = defineComponent({\n name: 'XhHierarchyChartTooltip',\n slots: Object as SlotsType<{\n default?: (props: HierarchyChartTooltipSlotProps) => VNode[]\n }>,\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => {\n const api = ctx.api.value\n return h('div', api.getTooltipProps() as Record<string, unknown>, slots.default\n ? slots.default({ active: api.active, tooltip: api.tooltip })\n : renderTooltipContent(api))\n }\n },\n})\n\n/** 空态:没有可画的数据时显示,缺省文字取文案。 */\nexport const XhHierarchyChartEmpty = defineComponent({\n name: 'XhHierarchyChartEmpty',\n setup(_, { slots }) {\n const ctx = useHierarchyChartContext()\n return () => h('div', ctx.api.value.getEmptyProps() as Record<string, unknown>, slots.default?.() ?? ctx.api.value.emptyText)\n },\n})\n\n/** 根:铺开缺省结构或交给默认插槽,并在末尾追加摘要与数据表。 */\nexport const XhHierarchyChartRoot = defineComponent({\n name: 'XhHierarchyChartRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n data: { type: [Object, Array] as PropType<ChartRow | readonly ChartRow[]> },\n childrenField: { type: String },\n idField: { type: String },\n parentField: { type: String },\n nameField: { type: String },\n valueField: { type: String },\n layout: { type: String as PropType<HierarchyLayout> },\n tile: { type: String as PropType<HierarchyTile> },\n depth: { type: Number },\n colorBy: { type: String as PropType<HierarchyColorBy> },\n palette: { type: String as PropType<ChartPalette> },\n orientation: { type: String as PropType<'vertical' | 'horizontal'> },\n rootKey: { type: [String, null] as PropType<string | null> },\n defaultRootKey: { type: [String, null] as PropType<string | null> },\n format: { type: [Object, Function] as PropType<NumberFormatSpec | ((value: number) => string)> },\n activeKey: { type: [String, Number, Date, null] as PropType<ChartKey | null> },\n pending: { type: Boolean, default: undefined },\n animated: { type: Boolean, default: undefined },\n locale: { type: String },\n translations: { type: Object as PropType<Partial<HierarchyChartTranslations>> },\n },\n // root-key-change / active-key-change 携带 details;update:* 携带裸值,支持 v-model\n emits: {\n 'root-key-change': (_details: PayloadOf<HierarchyChartProps, 'onRootKeyChange'>) => true,\n 'update:rootKey': (_key: PayloadOf<HierarchyChartProps, 'onRootKeyChange'>['rootKey']) => true,\n 'active-key-change': (_details: PayloadOf<HierarchyChartProps, 'onActiveKeyChange'>) => true,\n 'update:activeKey': (_key: PayloadOf<HierarchyChartProps, 'onActiveKeyChange'>['activeKey']) => true,\n 'datum-active': (_details: PayloadOf<HierarchyChartProps, 'onDatumActive'>) => true,\n 'datum-press': (_details: PayloadOf<HierarchyChartProps, 'onDatumPress'>) => true,\n },\n slots: Object as SlotsType<{\n /** 自行摆放部件;不写时铺开缺省结构:下钻路径、视口(绘图区与空态)、提示框。 */\n default?: (props: HierarchyChartRootSlotProps) => VNode[]\n /** 缺省结构里的标题内容。 */\n caption?: () => VNode[]\n /** 缺省结构里的提示框内容。 */\n tooltip?: (props: HierarchyChartTooltipSlotProps) => VNode[]\n /** 缺省结构里的空态内容。 */\n empty?: () => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useHierarchyChart(withXhConfig('hierarchy-chart', props) as HierarchyChartProps, {\n onRootKeyChange: (details) => {\n emit('root-key-change', details)\n emit('update:rootKey', details.rootKey)\n },\n onActiveKeyChange: (details) => {\n emit('active-key-change', details)\n emit('update:activeKey', details.activeKey)\n },\n onDatumActive: details => emit('datum-active', details),\n onDatumPress: details => emit('datum-press', details),\n })\n provideHierarchyChart(ctx)\n return () => {\n const api = ctx.api.value\n const content = slots.default\n ? slots.default({\n active: api.active,\n tooltip: api.tooltip,\n empty: api.empty,\n table: api.table,\n path: api.path,\n rootKey: api.rootKey,\n activeKey: api.activeKey,\n drillTo: api.drillTo,\n drillUp: api.drillUp,\n setFocusedDatum: api.setFocusedDatum,\n })\n : [\n ...(slots.caption ? [h(XhHierarchyChartCaption, null, () => slots.caption?.())] : []),\n h(XhHierarchyChartPath),\n h(XhHierarchyChartLegend),\n // 空态放进视口:叠在绘图区上,标题与路径不被盖住\n h(XhHierarchyChartViewport, null, () => [\n h(XhHierarchyChartPlot),\n h(XhHierarchyChartEmpty, null, slots.empty ? () => slots.empty?.() : undefined),\n ]),\n h(XhHierarchyChartTooltip, null, slots.tooltip ? { default: slots.tooltip } : undefined),\n ]\n return h('figure', {\n ...api.getRootProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.rootRef.value = el as HTMLElement },\n }, [...content, ...renderA11y(api)])\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -78,7 +78,8 @@ container: { type: Object } },
|
|
|
78
78
|
});
|
|
79
79
|
return () => h(XhPortal, {
|
|
80
80
|
to: props.container ?? ctx.portalTarget.value,
|
|
81
|
-
source: ctx.triggerRef
|
|
81
|
+
source: ctx.triggerRef,
|
|
82
|
+
present: ctx.visible.value
|
|
82
83
|
}, () => [h("div", {
|
|
83
84
|
...mergeProps(ctx.api.value.getPositionerProps(), attrs),
|
|
84
85
|
ref: (el) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-card.js","names":[],"sources":["../../../src/components/hover-card/hover-card.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 hover card 相关实现。\n\nimport type { Direction, Placement, Size } from '@xihan-ui/core'\nimport type { HoverCardApi, HoverCardSchema } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { provideHoverCard, useHoverCardContext } from './context'\nimport { useHoverCard } from './use-hover-card'\n\ntype HoverCardProps = HoverCardSchema['props']\n\n/** 默认插槽的载荷:浮层的开合状态与程序化开合的方法。 */\nexport type HoverCardRootSlotProps = Pick<HoverCardApi, 'open' | 'setOpen'>\n\nexport const XhHoverCardRoot = defineComponent({\n name: 'XhHoverCardRoot',\n // 缺省值由机器与 connect 给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n openDelay: { type: Number },\n closeDelay: { type: Number },\n dir: { type: String as PropType<Direction> },\n disabled: Boolean,\n size: { type: String as PropType<Size> },\n },\n // open-change 携带 { open },update:open 携带裸布尔\n emits: {\n 'open-change': (_details: PayloadOf<HoverCardProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<HoverCardProps, 'onOpenChange'>['open']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: HoverCardRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notify: HoverCardProps['onOpenChange'] = (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n }\n const ctx = useHoverCard(props as HoverCardProps, notify)\n provideHoverCard(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n open: ctx.api.value.open,\n setOpen: ctx.api.value.setOpen,\n }))\n },\n})\n\nexport const XhHoverCardTrigger = defineComponent({\n name: 'XhHoverCardTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useHoverCardContext()\n return () => {\n const part = mergePartProps({\n ...ctx.api.value.getTriggerProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.triggerRef.value = el as HTMLElement },\n }, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'hover-card')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhHoverCardPositioner = defineComponent({\n name: 'XhHoverCardPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useHoverCardContext()\n // 卡片内容的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner;浮层里走 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 搬到 portal 落点:留在原地的话,宿主祖先只要建了层叠上下文就能盖住浮层\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.triggerRef }, () => [\n h('div', {\n ...mergeProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhHoverCardContent = defineComponent({\n name: 'XhHoverCardContent',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardTitle = defineComponent({\n name: 'XhHoverCardTitle',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('h2', {\n ...ctx.api.value.getTitleProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.titleRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardDescription = defineComponent({\n name: 'XhHoverCardDescription',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('p', {\n ...ctx.api.value.getDescriptionProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.descriptionRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardArrow = defineComponent({\n name: 'XhHoverCardArrow',\n setup() {\n const ctx = useHoverCardContext()\n return () => h('div', ctx.api.value.getArrowProps() as Record<string, unknown>)\n },\n})\n"],"mappings":";;;;;;;;AAwBA,MAAa,kBAAkB,gBAAgB;CAC7C,MAAM;CAEN,OAAO;EACL,MAAM;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC1C,aAAa;EACb,WAAW,EAAE,MAAM,OAA8B;EACjD,QAAQ,EAAE,MAAM,OAAO;EACvB,WAAW,EAAE,MAAM,OAAO;EAC1B,YAAY,EAAE,MAAM,OAAO;EAC3B,KAAK,EAAE,MAAM,OAA8B;EAC3C,UAAU;EACV,MAAM,EAAE,MAAM,OAAyB;CACzC;CAEA,OAAO;EACL,gBAAgB,aAAwD;EACxE,gBAAgB,UAA6D;CAC/E;CACA,OAAO;CAGP,MAAM,OAAO,EAAE,OAAO,QAAQ;EAC5B,MAAM,UAA0C,YAAY;GAC1D,KAAK,eAAe,OAAO;GAC3B,KAAK,eAAe,QAAQ,IAAI;EAClC;EACA,MAAM,MAAM,aAAa,OAAyB,MAAM;EACxD,iBAAiB,GAAG;EACpB,aAAa,EAAE,OAAO,IAAI,IAAI,MAAM,aAAa,GAA8B,MAAM,UAAU;GAC7F,MAAM,IAAI,IAAI,MAAM;GACpB,SAAS,IAAI,IAAI,MAAM;EACzB,CAAC,CAAC;CACJ;AACF,CAAC;AAED,MAAa,qBAAqB,gBAAgB;CAChD,MAAM;CAEN,cAAc;CACd,OAAO;;AAEL,SAAS,QACX;CACA,MAAM,OAAO,EAAE,OAAO,SAAS;EAC7B,MAAM,MAAM,oBAAoB;EAChC,aAAa;GACX,MAAM,OAAO,eAAe;IAC1B,GAAG,IAAI,IAAI,MAAM,gBAAgB;IACjC,MAAM,OAAgB;KAAE,IAAI,WAAW,QAAQ;IAAkB;GACnE,GAAG,KAAK;GACR,MAAM,WAAW,MAAM,UAAU;GAEjC,IAAI,MAAM,SAAS;IACjB,MAAM,SAAS,eAAe,UAAU,MAAM,YAAY;IAC1D,IAAI,QACF,OAAO;GACX;GACA,OAAO,EAAE,UAAU,MAAM,QAAQ;EACnC;CACF;AACF,CAAC;AAED,MAAa,wBAAwB,gBAAgB;CACnD,MAAM;CACN,OAAO;;AAEL,WAAW,EAAE,MAAM,OAA4B,EACjD;CAEA,cAAc;CACd,MAAM,OAAO,EAAE,OAAO,SAAS;EAC7B,MAAM,MAAM,oBAAoB;EAEhC,MAAM,OAAO,cAAc;GAAE,kBAAkB,IAAI,WAAW;GAAO,OAAO,EAAE,MAAM,KAAK;EAAE,CAAC;EAE5F,aAAa,EAAE,UAAU;GAAE,IAAI,MAAM,aAAa,IAAI,aAAa;GAAO,QAAQ,IAAI;
|
|
1
|
+
{"version":3,"file":"hover-card.js","names":[],"sources":["../../../src/components/hover-card/hover-card.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 hover card 相关实现。\n\nimport type { Direction, Placement, Size } from '@xihan-ui/core'\nimport type { HoverCardApi, HoverCardSchema } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { useScrollbars } from '../../runtime/use-scrollbars'\nimport { provideHoverCard, useHoverCardContext } from './context'\nimport { useHoverCard } from './use-hover-card'\n\ntype HoverCardProps = HoverCardSchema['props']\n\n/** 默认插槽的载荷:浮层的开合状态与程序化开合的方法。 */\nexport type HoverCardRootSlotProps = Pick<HoverCardApi, 'open' | 'setOpen'>\n\nexport const XhHoverCardRoot = defineComponent({\n name: 'XhHoverCardRoot',\n // 缺省值由机器与 connect 给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n placement: { type: String as PropType<Placement> },\n offset: { type: Number },\n openDelay: { type: Number },\n closeDelay: { type: Number },\n dir: { type: String as PropType<Direction> },\n disabled: Boolean,\n size: { type: String as PropType<Size> },\n },\n // open-change 携带 { open },update:open 携带裸布尔\n emits: {\n 'open-change': (_details: PayloadOf<HoverCardProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<HoverCardProps, 'onOpenChange'>['open']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: HoverCardRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notify: HoverCardProps['onOpenChange'] = (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n }\n const ctx = useHoverCard(props as HoverCardProps, notify)\n provideHoverCard(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n open: ctx.api.value.open,\n setOpen: ctx.api.value.setOpen,\n }))\n },\n})\n\nexport const XhHoverCardTrigger = defineComponent({\n name: 'XhHoverCardTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useHoverCardContext()\n return () => {\n const part = mergePartProps({\n ...ctx.api.value.getTriggerProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.triggerRef.value = el as HTMLElement },\n }, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'hover-card')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhHoverCardPositioner = defineComponent({\n name: 'XhHoverCardPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useHoverCardContext()\n // 卡片内容的自绘条:与 content 同级、绝对定位不占布局,壳是这层已经 fixed 的 positioner;浮层里走 4px 档\n const bars = useScrollbars({ scrollable: () => ctx.contentRef.value, props: { size: 'sm' } })\n // 搬到 portal 落点:留在原地的话,宿主祖先只要建了层叠上下文就能盖住浮层\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, source: ctx.triggerRef, present: ctx.visible.value }, () => [\n h('div', {\n ...mergeProps(ctx.api.value.getPositionerProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n }, [...(slots.default?.() ?? []), ...bars.render()]),\n ])\n },\n})\n\nexport const XhHoverCardContent = defineComponent({\n name: 'XhHoverCardContent',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('div', {\n ...ctx.api.value.getContentProps() as Record<string, unknown>,\n // 收起跟着退场闸门走:皮肤刻意没给 content 补 [hidden]{display:none}(补了退场\n // 就一帧都播不出来),所以真正的收起落成内联 display——节点始终留在原地\n style: ctx.visible.value ? undefined : { display: 'none' },\n ref: (el: unknown) => { ctx.contentRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardTitle = defineComponent({\n name: 'XhHoverCardTitle',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('h2', {\n ...ctx.api.value.getTitleProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.titleRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardDescription = defineComponent({\n name: 'XhHoverCardDescription',\n setup(_, { slots }) {\n const ctx = useHoverCardContext()\n return () => h('p', {\n ...ctx.api.value.getDescriptionProps() as Record<string, unknown>,\n ref: (el: unknown) => { ctx.descriptionRef.value = el as HTMLElement },\n }, slots.default?.())\n },\n})\n\nexport const XhHoverCardArrow = defineComponent({\n name: 'XhHoverCardArrow',\n setup() {\n const ctx = useHoverCardContext()\n return () => h('div', ctx.api.value.getArrowProps() as Record<string, unknown>)\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PayloadOf } from "../../runtime/payload.js";
|
|
2
2
|
import { PropType, SlotsType, VNode } from "vue";
|
|
3
|
-
import { OverlayBackdropVariant } from "@xihan-ui/core";
|
|
3
|
+
import { OverlayBackdropVariant, Size } from "@xihan-ui/core";
|
|
4
4
|
import { ImageViewerApi, ImageViewerItem, ImageViewerSchema } from "@xihan-ui/headless";
|
|
5
5
|
//#region src/components/image-viewer/image-viewer.d.ts
|
|
6
6
|
type ImageViewerProps = ImageViewerSchema['props'];
|
|
@@ -49,6 +49,9 @@ declare const XhImageViewerRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
49
49
|
variant: {
|
|
50
50
|
type: PropType<OverlayBackdropVariant>;
|
|
51
51
|
};
|
|
52
|
+
size: {
|
|
53
|
+
type: PropType<Size>;
|
|
54
|
+
};
|
|
52
55
|
translations: {
|
|
53
56
|
type: PropType<ImageViewerProps["translations"]>;
|
|
54
57
|
};
|
|
@@ -102,6 +105,9 @@ declare const XhImageViewerRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
102
105
|
variant: {
|
|
103
106
|
type: PropType<OverlayBackdropVariant>;
|
|
104
107
|
};
|
|
108
|
+
size: {
|
|
109
|
+
type: PropType<Size>;
|
|
110
|
+
};
|
|
105
111
|
translations: {
|
|
106
112
|
type: PropType<ImageViewerProps["translations"]>;
|
|
107
113
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-viewer.d.ts","names":[],"sources":["../../../src/components/image-viewer/image-viewer.ts"],"mappings":";;;;;KAoBK,mBAAmB;;KAGZ,2BAA2B,KACrC;cAuBW,iCAAiB,8BAAA;;IAIG,MAAA,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYX,MAAA,SAAS;;;
|
|
1
|
+
{"version":3,"file":"image-viewer.d.ts","names":[],"sources":["../../../src/components/image-viewer/image-viewer.ts"],"mappings":";;;;;KAoBK,mBAAmB;;KAGZ,2BAA2B,KACrC;cAuBW,iCAAiB,8BAAA;;IAIG,MAAA,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYX,MAAA,SAAS;;;IACZ,MAAA,SAAS;;;IACD,MAAA,SAAS;;;;;EAIf,gBAAA,UAAA,UAAU;EACb,gBAAA,OAAA,UAAU;EACN,iBAAA,UAAA,UAAU;EACZ,iBAAA,QAAA,UAAU;;;IArBN,MAAA,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAYX,MAAA,SAAS;;;IACZ,MAAA,SAAS;;;IACD,MAAA,SAAS;;;;;;;;;;;;;;;EAU/B,WAAC,OAAO,6BAA6B;kCAsCjD;cAEW,oCAAoB,8BAAA;;;;;;;;;;qCAsB/B;cAEW,oCAAoB,8BAAA;;;IAIA,MAAA,SAAS;;;;;;;IAAT,MAAA,SAAS;;MA4BxC,oDAAA;cAEW,qCAAqB,0BAAA,oBAAA,4BAAA;;8BAMhC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAM7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAM/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAaW;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cACA;cAEA,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAe/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-viewer.js","names":[],"sources":["../../../src/components/image-viewer/image-viewer.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 image viewer 相关实现。\n\nimport type { OverlayBackdropVariant } from '@xihan-ui/core'\nimport type { imageViewerCounterText as counterTextFn, ImageViewerApi, ImageViewerItem, ImageViewerSchema } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { imageViewerCounterText } from '@xihan-ui/headless'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { provideImageViewer, useImageViewerContext } from './context'\nimport { useImageViewer } from './use-image-viewer'\n\ntype ImageViewerProps = ImageViewerSchema['props']\n\n/** 默认插槽的载荷:当前图与下标、变换与可翻页状态,以及翻页、缩放、旋转、翻转、归零等命令。 */\nexport type ImageViewerRootSlotProps = Pick<\n ImageViewerApi,\n | 'open'\n | 'index'\n | 'count'\n | 'currentItem'\n | 'transform'\n | 'imageStatus'\n | 'canPrev'\n | 'canNext'\n | 'setOpen'\n | 'setIndex'\n | 'next'\n | 'prev'\n | 'zoomIn'\n | 'zoomOut'\n | 'setScale'\n | 'rotateLeft'\n | 'rotateRight'\n | 'flipHorizontal'\n | 'flipVertical'\n | 'reset'\n>\n\nexport const XhImageViewerRoot = defineComponent({\n name: 'XhImageViewerRoot',\n // 缺省值由 connect 与机器给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n collection: { type: Array as PropType<ImageViewerItem[]> },\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n index: { type: Number },\n defaultIndex: { type: Number },\n loop: { type: Boolean, default: undefined },\n zoomStep: { type: Number },\n minScale: { type: Number },\n maxScale: { type: Number },\n closeOnEscape: { type: Boolean, default: undefined },\n closeOnInteractOutside: { type: Boolean, default: undefined },\n restoreFocus: { type: Boolean, default: undefined },\n variant: { type: String as PropType<OverlayBackdropVariant> },\n translations: { type: Object as PropType<ImageViewerProps['translations']> },\n },\n // *-change 携带 details 对象,update:* 携带裸值,支持 v-model:open 与 v-model:index\n emits: {\n 'open-change': (_details: PayloadOf<ImageViewerProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<ImageViewerProps, 'onOpenChange'>['open']) => true,\n 'index-change': (_details: PayloadOf<ImageViewerProps, 'onIndexChange'>) => true,\n 'update:index': (_index: PayloadOf<ImageViewerProps, 'onIndexChange'>['index']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: ImageViewerRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useImageViewer(withXhConfig('image-viewer', props) as ImageViewerProps, {\n onOpenChange: (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n },\n onIndexChange: (details) => {\n emit('index-change', details)\n emit('update:index', details.index)\n },\n })\n provideImageViewer(ctx)\n // 经插槽暴露状态与命令,供浮层外的按钮(如缩略图)使用\n return () => slots.default?.({\n open: ctx.api.value.open,\n index: ctx.api.value.index,\n count: ctx.api.value.count,\n currentItem: ctx.api.value.currentItem,\n transform: ctx.api.value.transform,\n imageStatus: ctx.api.value.imageStatus,\n canPrev: ctx.api.value.canPrev,\n canNext: ctx.api.value.canNext,\n setOpen: ctx.api.value.setOpen,\n setIndex: ctx.api.value.setIndex,\n next: ctx.api.value.next,\n prev: ctx.api.value.prev,\n zoomIn: ctx.api.value.zoomIn,\n zoomOut: ctx.api.value.zoomOut,\n setScale: ctx.api.value.setScale,\n rotateLeft: ctx.api.value.rotateLeft,\n rotateRight: ctx.api.value.rotateRight,\n flipHorizontal: ctx.api.value.flipHorizontal,\n flipVertical: ctx.api.value.flipVertical,\n reset: ctx.api.value.reset,\n })\n },\n})\n\nexport const XhImageViewerTrigger = defineComponent({\n name: 'XhImageViewerTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useImageViewerContext()\n return () => {\n const part = mergePartProps(ctx.api.value.getTriggerProps() as Record<string, unknown>, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'image-viewer')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhImageViewerContent = defineComponent({\n name: 'XhImageViewerContent',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 content 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useImageViewerContext()\n return () => {\n if (!ctx.rendered.value)\n return null\n const api = ctx.api.value\n return h(XhPortal, { to: props.container ?? ctx.portalTarget.value }, () => [\n h('div', {\n ...api.getBackdropProps() as Record<string, unknown>,\n ref: (el: unknown) => {\n ctx.backdropRef.value = el as HTMLElement\n },\n }),\n h('div', api.getPositionerProps() as Record<string, unknown>, [\n h('div', {\n ...mergeProps(api.getContentProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => {\n ctx.contentRef.value = el as HTMLElement\n },\n }, slots.default?.()),\n ]),\n ])\n }\n },\n})\n\nexport const XhImageViewerViewport = defineComponent({\n name: 'XhImageViewerViewport',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('div', ctx.api.value.getViewportProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhImageViewerImage = defineComponent({\n name: 'XhImageViewerImage',\n setup() {\n const ctx = useImageViewerContext()\n return () => h('img', ctx.api.value.getImageProps() as Record<string, unknown>)\n },\n})\n\nexport const XhImageViewerToolbar = defineComponent({\n name: 'XhImageViewerToolbar',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('div', ctx.api.value.getToolbarProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 工具条按钮共用的组件工厂:未写插槽内容时留空,皮肤据 :empty 绘制兜底图标;提供文字的(1:1)填入文字。 */\nfunction toolTrigger(name: string, getProps: (api: ReturnType<typeof useImageViewerContext>['api']['value']) => Record<string, unknown>, fallback?: string): ReturnType<typeof defineComponent> {\n return defineComponent({\n name,\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('button', getProps(ctx.api.value) as Record<string, unknown>, slots.default ? slots.default() : fallback)\n },\n })\n}\n\nexport const XhImageViewerZoomInTrigger = toolTrigger('XhImageViewerZoomInTrigger', api => api.getZoomInTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerZoomOutTrigger = toolTrigger('XhImageViewerZoomOutTrigger', api => api.getZoomOutTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerRotateLeftTrigger = toolTrigger('XhImageViewerRotateLeftTrigger', api => api.getRotateLeftTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerRotateRightTrigger = toolTrigger('XhImageViewerRotateRightTrigger', api => api.getRotateRightTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerFlipHorizontalTrigger = toolTrigger('XhImageViewerFlipHorizontalTrigger', api => api.getFlipHorizontalTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerFlipVerticalTrigger = toolTrigger('XhImageViewerFlipVerticalTrigger', api => api.getFlipVerticalTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerResetTrigger = toolTrigger('XhImageViewerResetTrigger', api => api.getResetTriggerProps() as Record<string, unknown>, '1:1')\nexport const XhImageViewerPrevTrigger = toolTrigger('XhImageViewerPrevTrigger', api => api.getPrevTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerNextTrigger = toolTrigger('XhImageViewerNextTrigger', api => api.getNextTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerCloseTrigger = toolTrigger('XhImageViewerCloseTrigger', api => api.getCloseTriggerProps() as Record<string, unknown>)\n\nexport const XhImageViewerCounter = defineComponent({\n name: 'XhImageViewerCounter',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => {\n const api = ctx.api.value\n // 无插槽内容时用「第 n / 共 m」的缺省文本兜底\n const fallback: ReturnType<typeof counterTextFn> = imageViewerCounterText(\n ctx.service.prop('translations'),\n api.index,\n api.count,\n )\n return h('div', api.getCounterProps() as Record<string, unknown>, slots.default ? slots.default() : fallback)\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-viewer.js","names":[],"sources":["../../../src/components/image-viewer/image-viewer.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 image viewer 相关实现。\n\nimport type { OverlayBackdropVariant, Size } from '@xihan-ui/core'\nimport type { imageViewerCounterText as counterTextFn, ImageViewerApi, ImageViewerItem, ImageViewerSchema } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { imageViewerCounterText } from '@xihan-ui/headless'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { XhPortal } from '../../runtime/portal'\nimport { provideImageViewer, useImageViewerContext } from './context'\nimport { useImageViewer } from './use-image-viewer'\n\ntype ImageViewerProps = ImageViewerSchema['props']\n\n/** 默认插槽的载荷:当前图与下标、变换与可翻页状态,以及翻页、缩放、旋转、翻转、归零等命令。 */\nexport type ImageViewerRootSlotProps = Pick<\n ImageViewerApi,\n | 'open'\n | 'index'\n | 'count'\n | 'currentItem'\n | 'transform'\n | 'imageStatus'\n | 'canPrev'\n | 'canNext'\n | 'setOpen'\n | 'setIndex'\n | 'next'\n | 'prev'\n | 'zoomIn'\n | 'zoomOut'\n | 'setScale'\n | 'rotateLeft'\n | 'rotateRight'\n | 'flipHorizontal'\n | 'flipVertical'\n | 'reset'\n>\n\nexport const XhImageViewerRoot = defineComponent({\n name: 'XhImageViewerRoot',\n // 缺省值由 connect 与机器给出;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n collection: { type: Array as PropType<ImageViewerItem[]> },\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n index: { type: Number },\n defaultIndex: { type: Number },\n loop: { type: Boolean, default: undefined },\n zoomStep: { type: Number },\n minScale: { type: Number },\n maxScale: { type: Number },\n closeOnEscape: { type: Boolean, default: undefined },\n closeOnInteractOutside: { type: Boolean, default: undefined },\n restoreFocus: { type: Boolean, default: undefined },\n variant: { type: String as PropType<OverlayBackdropVariant> },\n size: { type: String as PropType<Size> },\n translations: { type: Object as PropType<ImageViewerProps['translations']> },\n },\n // *-change 携带 details 对象,update:* 携带裸值,支持 v-model:open 与 v-model:index\n emits: {\n 'open-change': (_details: PayloadOf<ImageViewerProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<ImageViewerProps, 'onOpenChange'>['open']) => true,\n 'index-change': (_details: PayloadOf<ImageViewerProps, 'onIndexChange'>) => true,\n 'update:index': (_index: PayloadOf<ImageViewerProps, 'onIndexChange'>['index']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: ImageViewerRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useImageViewer(withXhConfig('image-viewer', props) as ImageViewerProps, {\n onOpenChange: (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n },\n onIndexChange: (details) => {\n emit('index-change', details)\n emit('update:index', details.index)\n },\n })\n provideImageViewer(ctx)\n // 经插槽暴露状态与命令,供浮层外的按钮(如缩略图)使用\n return () => slots.default?.({\n open: ctx.api.value.open,\n index: ctx.api.value.index,\n count: ctx.api.value.count,\n currentItem: ctx.api.value.currentItem,\n transform: ctx.api.value.transform,\n imageStatus: ctx.api.value.imageStatus,\n canPrev: ctx.api.value.canPrev,\n canNext: ctx.api.value.canNext,\n setOpen: ctx.api.value.setOpen,\n setIndex: ctx.api.value.setIndex,\n next: ctx.api.value.next,\n prev: ctx.api.value.prev,\n zoomIn: ctx.api.value.zoomIn,\n zoomOut: ctx.api.value.zoomOut,\n setScale: ctx.api.value.setScale,\n rotateLeft: ctx.api.value.rotateLeft,\n rotateRight: ctx.api.value.rotateRight,\n flipHorizontal: ctx.api.value.flipHorizontal,\n flipVertical: ctx.api.value.flipVertical,\n reset: ctx.api.value.reset,\n })\n },\n})\n\nexport const XhImageViewerTrigger = defineComponent({\n name: 'XhImageViewerTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useImageViewerContext()\n return () => {\n const part = mergePartProps(ctx.api.value.getTriggerProps() as Record<string, unknown>, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'image-viewer')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhImageViewerContent = defineComponent({\n name: 'XhImageViewerContent',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 content 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useImageViewerContext()\n return () => {\n if (!ctx.rendered.value)\n return null\n const api = ctx.api.value\n return h(XhPortal, { to: props.container ?? ctx.portalTarget.value }, () => [\n h('div', {\n ...api.getBackdropProps() as Record<string, unknown>,\n ref: (el: unknown) => {\n ctx.backdropRef.value = el as HTMLElement\n },\n }),\n h('div', api.getPositionerProps() as Record<string, unknown>, [\n h('div', {\n ...mergeProps(api.getContentProps() as Record<string, unknown>, attrs),\n ref: (el: unknown) => {\n ctx.contentRef.value = el as HTMLElement\n },\n }, slots.default?.()),\n ]),\n ])\n }\n },\n})\n\nexport const XhImageViewerViewport = defineComponent({\n name: 'XhImageViewerViewport',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('div', ctx.api.value.getViewportProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhImageViewerImage = defineComponent({\n name: 'XhImageViewerImage',\n setup() {\n const ctx = useImageViewerContext()\n return () => h('img', ctx.api.value.getImageProps() as Record<string, unknown>)\n },\n})\n\nexport const XhImageViewerToolbar = defineComponent({\n name: 'XhImageViewerToolbar',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('div', ctx.api.value.getToolbarProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 工具条按钮共用的组件工厂:未写插槽内容时留空,皮肤据 :empty 绘制兜底图标;提供文字的(1:1)填入文字。 */\nfunction toolTrigger(name: string, getProps: (api: ReturnType<typeof useImageViewerContext>['api']['value']) => Record<string, unknown>, fallback?: string): ReturnType<typeof defineComponent> {\n return defineComponent({\n name,\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => h('button', getProps(ctx.api.value) as Record<string, unknown>, slots.default ? slots.default() : fallback)\n },\n })\n}\n\nexport const XhImageViewerZoomInTrigger = toolTrigger('XhImageViewerZoomInTrigger', api => api.getZoomInTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerZoomOutTrigger = toolTrigger('XhImageViewerZoomOutTrigger', api => api.getZoomOutTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerRotateLeftTrigger = toolTrigger('XhImageViewerRotateLeftTrigger', api => api.getRotateLeftTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerRotateRightTrigger = toolTrigger('XhImageViewerRotateRightTrigger', api => api.getRotateRightTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerFlipHorizontalTrigger = toolTrigger('XhImageViewerFlipHorizontalTrigger', api => api.getFlipHorizontalTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerFlipVerticalTrigger = toolTrigger('XhImageViewerFlipVerticalTrigger', api => api.getFlipVerticalTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerResetTrigger = toolTrigger('XhImageViewerResetTrigger', api => api.getResetTriggerProps() as Record<string, unknown>, '1:1')\nexport const XhImageViewerPrevTrigger = toolTrigger('XhImageViewerPrevTrigger', api => api.getPrevTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerNextTrigger = toolTrigger('XhImageViewerNextTrigger', api => api.getNextTriggerProps() as Record<string, unknown>)\nexport const XhImageViewerCloseTrigger = toolTrigger('XhImageViewerCloseTrigger', api => api.getCloseTriggerProps() as Record<string, unknown>)\n\nexport const XhImageViewerCounter = defineComponent({\n name: 'XhImageViewerCounter',\n setup(_, { slots }) {\n const ctx = useImageViewerContext()\n return () => {\n const api = ctx.api.value\n // 无插槽内容时用「第 n / 共 m」的缺省文本兜底\n const fallback: ReturnType<typeof counterTextFn> = imageViewerCounterText(\n ctx.service.prop('translations'),\n api.index,\n api.count,\n )\n return h('div', api.getCounterProps() as Record<string, unknown>, slots.default ? slots.default() : fallback)\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -150,7 +150,7 @@ declare const XhMentionRoot: import("vue").DefineComponent<import("vue").Extract
|
|
|
150
150
|
'item-prefix'?: (props: MentionNodeMeta) => VNode[];
|
|
151
151
|
/** 只接管行尾那一格(计数、徽标、次级图标),其余槽照旧由数据铺 */
|
|
152
152
|
'item-suffix'?: (props: MentionNodeMeta) => VNode[];
|
|
153
|
-
/** 铺开 collection
|
|
153
|
+
/** 铺开 collection 时空态中的文案;未写时取 translations.empty(缺省走英文语言包)。 */
|
|
154
154
|
empty?: () => VNode[];
|
|
155
155
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
156
156
|
/** 标题;必须是原生 label,getLabelProps 的 for 恒指向输入框。 */
|
|
@@ -76,7 +76,7 @@ const XhMentionRoot = defineComponent({
|
|
|
76
76
|
mentions: ctx.api.value.mentions,
|
|
77
77
|
setValue: ctx.api.value.setValue,
|
|
78
78
|
close: ctx.api.value.close
|
|
79
|
-
}) : props.collection ? renderDefaultTree(ctx.api.value.collection, slots.item, slots["item-prefix"], slots["item-suffix"], slots.empty) : []);
|
|
79
|
+
}) : props.collection ? renderDefaultTree(ctx.api.value.collection, ctx.api.value.emptyText, slots.item, slots["item-prefix"], slots["item-suffix"], slots.empty) : []);
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
/** 标题;必须是原生 label,getLabelProps 的 for 恒指向输入框。 */
|
|
@@ -126,7 +126,8 @@ container: { type: Object } },
|
|
|
126
126
|
});
|
|
127
127
|
return () => h(XhPortal, {
|
|
128
128
|
to: props.container ?? ctx.portalTarget.value,
|
|
129
|
-
source: ctx.inputRef
|
|
129
|
+
source: ctx.inputRef,
|
|
130
|
+
present: ctx.visible.value
|
|
130
131
|
}, () => [h("div", {
|
|
131
132
|
...mergeProps(ctx.api.value.getPositionerProps(), attrs),
|
|
132
133
|
ref: (el) => {
|
|
@@ -229,8 +230,8 @@ const XhMentionItemDescription = defineComponent({
|
|
|
229
230
|
* 与手写部件产出的 DOM 完全一致,需要修改结构时写默认插槽,行为不变。
|
|
230
231
|
* 过滤仍归调用方:collection 就是当前应显示的候选。
|
|
231
232
|
*/
|
|
232
|
-
function renderDefaultTree(collection, itemSlot, prefixSlot, suffixSlot, emptySlot) {
|
|
233
|
-
const emptyText = emptySlot?.() ??
|
|
233
|
+
function renderDefaultTree(collection, defaultEmpty, itemSlot, prefixSlot, suffixSlot, emptySlot) {
|
|
234
|
+
const emptyText = emptySlot?.() ?? defaultEmpty;
|
|
234
235
|
return [h(XhMentionInput), h(XhMentionPositioner, null, () => [h(XhMentionContent, null, () => collection.map((node) => h(XhMentionItem, {
|
|
235
236
|
key: node.value,
|
|
236
237
|
value: node.value
|