@manohub/ui 0.6.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.
Files changed (169) hide show
  1. package/README.md +141 -0
  2. package/dist/components/avatar/index.d.ts +283 -0
  3. package/dist/components/avatar/index.js +167 -0
  4. package/dist/components/badge/index.d.ts +132 -0
  5. package/dist/components/badge/index.js +99 -0
  6. package/dist/components/button/index.d.ts +578 -0
  7. package/dist/components/button/index.js +191 -0
  8. package/dist/components/capsule/index.d.ts +161 -0
  9. package/dist/components/capsule/index.js +101 -0
  10. package/dist/components/card/index.d.ts +456 -0
  11. package/dist/components/card/index.js +231 -0
  12. package/dist/components/checkbox/index.d.ts +331 -0
  13. package/dist/components/checkbox/index.js +165 -0
  14. package/dist/components/code/index.d.ts +134 -0
  15. package/dist/components/code/index.js +117 -0
  16. package/dist/components/code-editor/index.d.ts +163 -0
  17. package/dist/components/code-editor/index.js +98 -0
  18. package/dist/components/collapse/index.d.ts +125 -0
  19. package/dist/components/collapse/index.js +95 -0
  20. package/dist/components/control-size.d.ts +8 -0
  21. package/dist/components/dialog/index.d.ts +224 -0
  22. package/dist/components/dialog/index.js +194 -0
  23. package/dist/components/divider/index.d.ts +64 -0
  24. package/dist/components/divider/index.js +62 -0
  25. package/dist/components/drawer/index.d.ts +226 -0
  26. package/dist/components/drawer/index.js +190 -0
  27. package/dist/components/filter/index.d.ts +391 -0
  28. package/dist/components/filter/index.js +203 -0
  29. package/dist/components/form/index.d.ts +704 -0
  30. package/dist/components/form/index.js +329 -0
  31. package/dist/components/input/index.d.ts +980 -0
  32. package/dist/components/input/index.js +334 -0
  33. package/dist/components/layout/index.d.ts +162 -0
  34. package/dist/components/layout/index.js +100 -0
  35. package/dist/components/list-view/index.d.ts +563 -0
  36. package/dist/components/list-view/index.js +221 -0
  37. package/dist/components/loading/index.d.ts +77 -0
  38. package/dist/components/loading/index.js +40 -0
  39. package/dist/components/nav/index.d.ts +293 -0
  40. package/dist/components/nav/index.js +164 -0
  41. package/dist/components/notice/index.d.ts +137 -0
  42. package/dist/components/notice/index.js +101 -0
  43. package/dist/components/notification/index.d.ts +118 -0
  44. package/dist/components/notification/index.js +99 -0
  45. package/dist/components/page/index.d.ts +276 -0
  46. package/dist/components/page/index.js +351 -0
  47. package/dist/components/page/split-resize.d.ts +42 -0
  48. package/dist/components/page/split-resize.js +36 -0
  49. package/dist/components/pagination/index.d.ts +171 -0
  50. package/dist/components/pagination/index.js +226 -0
  51. package/dist/components/panel/index.d.ts +401 -0
  52. package/dist/components/panel/index.js +193 -0
  53. package/dist/components/part-padding.d.ts +27 -0
  54. package/dist/components/part-padding.js +23 -0
  55. package/dist/components/query-state/index.d.ts +207 -0
  56. package/dist/components/query-state/index.js +181 -0
  57. package/dist/components/radio/index.d.ts +473 -0
  58. package/dist/components/radio/index.js +250 -0
  59. package/dist/components/search/index.d.ts +167 -0
  60. package/dist/components/search/index.js +105 -0
  61. package/dist/components/select/index.d.ts +252 -0
  62. package/dist/components/select/index.js +281 -0
  63. package/dist/components/skeleton/index.d.ts +88 -0
  64. package/dist/components/skeleton/index.js +56 -0
  65. package/dist/components/steps/index.d.ts +199 -0
  66. package/dist/components/steps/index.js +117 -0
  67. package/dist/components/switch/index.d.ts +150 -0
  68. package/dist/components/switch/index.js +103 -0
  69. package/dist/components/table/index.d.ts +351 -0
  70. package/dist/components/table/index.js +286 -0
  71. package/dist/components/tabs/index.d.ts +179 -0
  72. package/dist/components/tabs/index.js +153 -0
  73. package/dist/components/tabset/index.d.ts +105 -0
  74. package/dist/components/tabset/index.js +68 -0
  75. package/dist/components/tag/index.d.ts +203 -0
  76. package/dist/components/tag/index.js +144 -0
  77. package/dist/components/toast/index.d.ts +271 -0
  78. package/dist/components/toast/index.js +116 -0
  79. package/dist/components/tooltip/index.d.ts +126 -0
  80. package/dist/components/tooltip/index.js +97 -0
  81. package/dist/components/tree/index.d.ts +317 -0
  82. package/dist/components/tree/index.js +251 -0
  83. package/dist/components/upload/index.d.ts +384 -0
  84. package/dist/components/upload/index.js +172 -0
  85. package/dist/index.d.ts +63 -0
  86. package/dist/index.js +102 -0
  87. package/dist/services/base.d.ts +21 -0
  88. package/dist/services/base.js +42 -0
  89. package/dist/services/dialog.d.ts +41 -0
  90. package/dist/services/dialog.js +83 -0
  91. package/dist/services/index.d.ts +12 -0
  92. package/dist/services/loading.d.ts +21 -0
  93. package/dist/services/loading.js +41 -0
  94. package/dist/services/toast.d.ts +40 -0
  95. package/dist/services/toast.js +74 -0
  96. package/dist/styles/components/avatar.css +128 -0
  97. package/dist/styles/components/avatar.tokens.css +24 -0
  98. package/dist/styles/components/badge.css +237 -0
  99. package/dist/styles/components/button.css +454 -0
  100. package/dist/styles/components/button.tokens.css +56 -0
  101. package/dist/styles/components/capsule.css +120 -0
  102. package/dist/styles/components/capsule.tokens.css +27 -0
  103. package/dist/styles/components/card.css +192 -0
  104. package/dist/styles/components/checkbox.css +145 -0
  105. package/dist/styles/components/checkbox.tokens.css +26 -0
  106. package/dist/styles/components/code-editor.css +91 -0
  107. package/dist/styles/components/code-editor.tokens.css +24 -0
  108. package/dist/styles/components/code.css +153 -0
  109. package/dist/styles/components/code.tokens.css +29 -0
  110. package/dist/styles/components/collapse.css +62 -0
  111. package/dist/styles/components/collapse.tokens.css +20 -0
  112. package/dist/styles/components/dialog.css +106 -0
  113. package/dist/styles/components/dialog.tokens.css +24 -0
  114. package/dist/styles/components/divider.css +71 -0
  115. package/dist/styles/components/divider.tokens.css +21 -0
  116. package/dist/styles/components/drawer.css +143 -0
  117. package/dist/styles/components/drawer.tokens.css +22 -0
  118. package/dist/styles/components/filter.css +41 -0
  119. package/dist/styles/components/filter.tokens.css +14 -0
  120. package/dist/styles/components/form.css +220 -0
  121. package/dist/styles/components/form.tokens.css +15 -0
  122. package/dist/styles/components/input.css +445 -0
  123. package/dist/styles/components/input.tokens.css +41 -0
  124. package/dist/styles/components/layout.css +198 -0
  125. package/dist/styles/components/list-view.css +244 -0
  126. package/dist/styles/components/loading.css +76 -0
  127. package/dist/styles/components/loading.tokens.css +23 -0
  128. package/dist/styles/components/nav.css +48 -0
  129. package/dist/styles/components/notice.css +153 -0
  130. package/dist/styles/components/notice.tokens.css +17 -0
  131. package/dist/styles/components/notification.css +159 -0
  132. package/dist/styles/components/notification.tokens.css +37 -0
  133. package/dist/styles/components/page.css +473 -0
  134. package/dist/styles/components/pagination.css +297 -0
  135. package/dist/styles/components/pagination.tokens.css +32 -0
  136. package/dist/styles/components/panel.css +77 -0
  137. package/dist/styles/components/query-state.css +88 -0
  138. package/dist/styles/components/radio.css +271 -0
  139. package/dist/styles/components/radio.tokens.css +26 -0
  140. package/dist/styles/components/search.css +30 -0
  141. package/dist/styles/components/select.css +242 -0
  142. package/dist/styles/components/select.tokens.css +33 -0
  143. package/dist/styles/components/skeleton.css +60 -0
  144. package/dist/styles/components/skeleton.tokens.css +27 -0
  145. package/dist/styles/components/steps.css +157 -0
  146. package/dist/styles/components/steps.tokens.css +42 -0
  147. package/dist/styles/components/switch.css +165 -0
  148. package/dist/styles/components/switch.tokens.css +26 -0
  149. package/dist/styles/components/table.css +439 -0
  150. package/dist/styles/components/table.tokens.css +41 -0
  151. package/dist/styles/components/tabs.css +234 -0
  152. package/dist/styles/components/tabs.tokens.css +30 -0
  153. package/dist/styles/components/tag.css +200 -0
  154. package/dist/styles/components/tag.tokens.css +30 -0
  155. package/dist/styles/components/toast.css +150 -0
  156. package/dist/styles/components/toast.tokens.css +26 -0
  157. package/dist/styles/components/tooltip.css +89 -0
  158. package/dist/styles/components/tooltip.tokens.css +25 -0
  159. package/dist/styles/components/tree.css +139 -0
  160. package/dist/styles/components/tree.tokens.css +20 -0
  161. package/dist/styles/components/upload.css +150 -0
  162. package/dist/styles/components/upload.tokens.css +27 -0
  163. package/dist/styles/index.css +149 -0
  164. package/dist/styles/operations/collapse.css +84 -0
  165. package/dist/styles/operations/popup.css +189 -0
  166. package/dist/styles/operations/tabset.css +57 -0
  167. package/dist/utils/state-illustration.d.ts +31 -0
  168. package/dist/utils/state-illustration.js +156 -0
  169. package/package.json +62 -0
@@ -0,0 +1,191 @@
1
+ import { defineComponent, computed, createVNode, mergeProps, Fragment } from "vue";
2
+ import { Icon } from "@manohub/icon";
3
+ const Button = /* @__PURE__ */ defineComponent({
4
+ name: "Button",
5
+ inheritAttrs: false,
6
+ props: {
7
+ /** 按钮型(缺省 `secondary`,与规范「次要为默认」一致) */
8
+ variant: {
9
+ type: String,
10
+ default: "secondary"
11
+ },
12
+ /** 尺寸:`sm` 24 / `md` 32(标准)/ `lg` 40 */
13
+ size: {
14
+ type: String,
15
+ default: "md"
16
+ },
17
+ /** 外形:胶囊 / 正圆(缺省方角,跟主题圆角令牌) */
18
+ shape: {
19
+ type: String,
20
+ default: "default"
21
+ },
22
+ /** 危险色(正交修饰:把该型的色彩槽位换成错误色;`variant="danger"` 是它的等价写法) */
23
+ danger: {
24
+ type: Boolean,
25
+ default: false
26
+ },
27
+ /** 撑满父容器宽度(表单底栏 / 移动端主操作) */
28
+ block: {
29
+ type: Boolean,
30
+ default: false
31
+ },
32
+ disabled: {
33
+ type: Boolean,
34
+ default: false
35
+ },
36
+ /** 加载态:吞掉点击(置 disabled)+ 环 + **主色底降透明**(显式合成,字与环不变) */
37
+ loading: {
38
+ type: Boolean,
39
+ default: false
40
+ },
41
+ /** 图标名(`@manohub/icon` 的闭合枚举,写错名字编译期即报错);自定义图标走 `icon` 插槽 */
42
+ icon: {
43
+ type: String,
44
+ default: void 0
45
+ },
46
+ /** 尾部图标名(菜单按钮的箭头用 `caret`,这个是普通尾图标) */
47
+ trailingIcon: {
48
+ type: String,
49
+ default: void 0
50
+ },
51
+ /** 渲染下拉箭头(菜单按钮形态;转向由 popup.css 承担) */
52
+ caret: {
53
+ type: Boolean,
54
+ default: false
55
+ },
56
+ /** 菜单按钮结构(文本区 ‖ 分割线 ‖ 箭头区) */
57
+ menu: {
58
+ type: Boolean,
59
+ default: false
60
+ },
61
+ /** 原生按钮类型(缺省 `button`:不给默认值会让表单里的按钮意外提交) */
62
+ type: {
63
+ type: String,
64
+ default: "button"
65
+ },
66
+ /** 给了就渲染成 `<a>`(链接按钮:新窗口打开 / 复制链接地址都靠它) */
67
+ href: {
68
+ type: String,
69
+ default: void 0
70
+ },
71
+ /** `<a>` 形态的打开方式(如 `_blank`) */
72
+ target: {
73
+ type: String,
74
+ default: void 0
75
+ },
76
+ /** 原生 title(图标按钮的无障碍提示) */
77
+ title: {
78
+ type: String,
79
+ default: void 0
80
+ },
81
+ /** 原生 popover 目标 id(菜单按钮用;开合交给操作层) */
82
+ popoverTarget: {
83
+ type: String,
84
+ default: void 0
85
+ },
86
+ onClick: {
87
+ type: Function,
88
+ default: void 0
89
+ }
90
+ },
91
+ slots: Object,
92
+ setup(props, {
93
+ slots,
94
+ attrs
95
+ }) {
96
+ const isDanger = computed(() => props.danger || props.variant === "danger");
97
+ const baseVariant = computed(() => props.variant === "danger" ? "primary" : props.variant);
98
+ const classes = computed(() => ["mh-button", `mh-button--${baseVariant.value}`, props.size === "md" ? "" : `mh-button--${props.size}`, props.shape === "default" ? "" : `mh-button--${props.shape}`, isDanger.value ? "mh-button--danger" : "", props.block ? "mh-button--block" : "", props.menu ? "mh-button--menu" : "", props.loading ? "mh-button--loading" : "", props.disabled ? "is-disabled" : "", attrs.class].filter(Boolean).join(" "));
99
+ const renderIcon = (name, cls) => slots.icon && cls === "mh-button__icon" ? slots.icon() : name ? createVNode(Icon, {
100
+ "name": name,
101
+ "class": cls
102
+ }, null) : null;
103
+ const content = () => {
104
+ const body = props.menu ? createVNode("span", {
105
+ "class": "mh-button__label"
106
+ }, [slots.default?.()]) : slots.default?.();
107
+ return createVNode(Fragment, null, [props.loading ? createVNode("span", {
108
+ "class": "mh-button__spinner"
109
+ }, null) : renderIcon(props.icon, "mh-button__icon"), body, props.menu ? createVNode("span", {
110
+ "class": "mh-button__divider"
111
+ }, null) : null, props.caret ? createVNode(Icon, {
112
+ "name": "chevron-down",
113
+ "class": "mh-button__caret mh-popup-caret"
114
+ }, null) : null, props.trailingIcon ? createVNode(Icon, {
115
+ "name": props.trailingIcon,
116
+ "class": "mh-button__icon"
117
+ }, null) : null]);
118
+ };
119
+ return () => {
120
+ const common = {
121
+ ...attrs,
122
+ class: classes.value,
123
+ style: attrs.style,
124
+ title: props.title
125
+ };
126
+ if (props.href) {
127
+ return createVNode("a", mergeProps(common, {
128
+ "href": props.href,
129
+ "target": props.target,
130
+ "rel": props.target === "_blank" ? "noopener noreferrer" : void 0,
131
+ "aria-disabled": props.disabled || props.loading ? "true" : void 0,
132
+ "onClick": (event) => {
133
+ if (props.disabled || props.loading) {
134
+ event.preventDefault();
135
+ return;
136
+ }
137
+ props.onClick?.(event);
138
+ }
139
+ }), [content()]);
140
+ }
141
+ return createVNode("button", mergeProps(common, {
142
+ "type": props.type,
143
+ "disabled": props.disabled || props.loading
144
+ }, {
145
+ popovertarget: props.popoverTarget
146
+ }, {
147
+ "onClick": props.onClick
148
+ }), [content()]);
149
+ };
150
+ }
151
+ });
152
+ const ButtonGroup = /* @__PURE__ */ defineComponent({
153
+ name: "ButtonGroup",
154
+ inheritAttrs: false,
155
+ props: {
156
+ /** 连体档(工具条 / 连体切换:相邻边重合,首末保留圆角) */
157
+ compact: {
158
+ type: Boolean,
159
+ default: false
160
+ }
161
+ },
162
+ slots: Object,
163
+ setup(props, {
164
+ slots,
165
+ attrs
166
+ }) {
167
+ return () => createVNode("span", {
168
+ "class": ["mh-button__group", props.compact ? "mh-button__group--compact" : "", attrs.class].filter(Boolean).join(" "),
169
+ "style": attrs.style
170
+ }, [slots.default?.()]);
171
+ }
172
+ });
173
+ const ButtonDivider = /* @__PURE__ */ defineComponent({
174
+ name: "ButtonDivider",
175
+ inheritAttrs: false,
176
+ setup(_props, {
177
+ attrs
178
+ }) {
179
+ return () => createVNode("span", {
180
+ "class": ["mh-button__divider", attrs.class].filter(Boolean).join(" "),
181
+ "style": attrs.style
182
+ }, null);
183
+ }
184
+ });
185
+ Object.assign(Button, {
186
+ Group: ButtonGroup,
187
+ Divider: ButtonDivider
188
+ });
189
+ export {
190
+ Button
191
+ };
@@ -0,0 +1,161 @@
1
+ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
2
+ import type { ControlSize } from '../control-size';
3
+ export interface CapsuleOption {
4
+ label: string;
5
+ value: string | number;
6
+ disabled?: boolean;
7
+ }
8
+ /** 外形档:`pill` = 胶囊(缺省);`square` = 圆角矩形(轨道与选中项同取复选框档圆角) */
9
+ export type CapsuleShape = 'pill' | 'square';
10
+ /**
11
+ * 胶囊选择器(**自绘**;一组互斥选项,选中项白底胶囊浮在轨道上)。
12
+ *
13
+ * ## 结构与键盘全靠原生
14
+ *
15
+ * 渲染的是「**平级相邻、开关在前**」的 `<input type="radio">` + `<label for>`:
16
+ * 样式层靠 `input:checked + .mh-capsule__item` 选态,故**顺序不能调**(input 必须紧邻项之前);
17
+ * 项上带 `for`/`id` 是为了整项可点(开关自身是 1px 隐身盒、`pointer-events: none`)。
18
+ * Tab 进组、← → 换项、空格选中、跳过禁用项 —— 都是原生 radio 组的行为,本件不写键盘代码。
19
+ *
20
+ * ## 外形档(`shape`)
21
+ *
22
+ * - `pill`(缺省):整条轨道与选中项都是胶囊形(圆角取圆角满档令牌);
23
+ * - `square`:整组变圆角矩形,**轨道与选中项同取复选框档圆角**(比控件档更方),
24
+ * 与方角控件并排排版时用;只覆盖圆角令牌,几何与颜色一律不变。
25
+ *
26
+ * ## 与面板组合(页签用法)
27
+ *
28
+ * 外面套 `styles/operations/tabset.css` 的 `.mh-tabset`:**同一组 `name` 的 radio** 既是本件的选项、
29
+ * 也是操作层的档位开关(第 n 项 ↔ 第 n 块面板)。本件不认识 tabset,tabset 也不认识本件(两层零互指)。
30
+ *
31
+ * 状态三源等价:原生 `input:checked` / 组件下发 `[data-state='active'|'inactive']` / 静态档 `.is-selected`。
32
+ *
33
+ * ## 必须有值
34
+ *
35
+ * 单选语义就是必选其一:受控传 `modelValue`,非受控由 `defaultValue` 起,**两者都没给时缺省选中第一个
36
+ * 可选项**(跳过禁用项;没有可选项才是空值)—— 与 `Radio.Group` / `Radio.Card` / `Tabset` 同一条口径。
37
+ *
38
+ * @example 选项表
39
+ * <Capsule :options="[{label:'全部',value:'all'}]" v-model="v" />
40
+ *
41
+ * @example 方形档(与方角控件并排时用)
42
+ * <Capsule shape="square" :options="[{label:'全部',value:'all'}]" v-model="v" />
43
+ *
44
+ * @example 与面板组合(页签)
45
+ * <div class="mh-tabset">
46
+ * <Capsule name="t1" :options="tabs" v-model="v" />
47
+ * <div class="mh-tabset-panels">…第 n 块面板…</div>
48
+ * </div>
49
+ */
50
+ export declare const Capsule: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
51
+ /** 选项表(也可用默认插槽自排) */
52
+ options: {
53
+ type: PropType<CapsuleOption[]>;
54
+ default: undefined;
55
+ };
56
+ /** 受控值;不传即非受控(由 `defaultValue` 起,再缺省则为第一个可选项) */
57
+ modelValue: {
58
+ type: PropType<string | number | undefined>;
59
+ default: undefined;
60
+ };
61
+ /** 非受控初始值(缺省 = 第一个可选项) */
62
+ defaultValue: {
63
+ type: PropType<string | number | undefined>;
64
+ default: undefined;
65
+ };
66
+ /** 原生分组名(与 tabset 组合时**必须**给,操作层靠它认组;缺省自动生成) */
67
+ name: {
68
+ type: StringConstructor;
69
+ default: undefined;
70
+ };
71
+ /** 整组禁用 */
72
+ disabled: {
73
+ type: BooleanConstructor;
74
+ default: boolean;
75
+ };
76
+ /** 尺寸档(24 / 32 / 40,只覆盖令牌) */
77
+ size: {
78
+ type: PropType<ControlSize>;
79
+ default: string;
80
+ };
81
+ /** 外形:`pill` 胶囊(缺省)/ `square` 圆角矩形(轨道与选中项同取复选框档圆角) */
82
+ shape: {
83
+ type: PropType<CapsuleShape>;
84
+ default: string;
85
+ };
86
+ /** 撑满父容器(每项等分宽度) */
87
+ block: {
88
+ type: BooleanConstructor;
89
+ default: boolean;
90
+ };
91
+ /** 选中变化回调 */
92
+ onChange: {
93
+ type: PropType<(value: string | number) => void>;
94
+ default: undefined;
95
+ };
96
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
97
+ 'update:modelValue': (v: string | number) => true;
98
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
99
+ /** 选项表(也可用默认插槽自排) */
100
+ options: {
101
+ type: PropType<CapsuleOption[]>;
102
+ default: undefined;
103
+ };
104
+ /** 受控值;不传即非受控(由 `defaultValue` 起,再缺省则为第一个可选项) */
105
+ modelValue: {
106
+ type: PropType<string | number | undefined>;
107
+ default: undefined;
108
+ };
109
+ /** 非受控初始值(缺省 = 第一个可选项) */
110
+ defaultValue: {
111
+ type: PropType<string | number | undefined>;
112
+ default: undefined;
113
+ };
114
+ /** 原生分组名(与 tabset 组合时**必须**给,操作层靠它认组;缺省自动生成) */
115
+ name: {
116
+ type: StringConstructor;
117
+ default: undefined;
118
+ };
119
+ /** 整组禁用 */
120
+ disabled: {
121
+ type: BooleanConstructor;
122
+ default: boolean;
123
+ };
124
+ /** 尺寸档(24 / 32 / 40,只覆盖令牌) */
125
+ size: {
126
+ type: PropType<ControlSize>;
127
+ default: string;
128
+ };
129
+ /** 外形:`pill` 胶囊(缺省)/ `square` 圆角矩形(轨道与选中项同取复选框档圆角) */
130
+ shape: {
131
+ type: PropType<CapsuleShape>;
132
+ default: string;
133
+ };
134
+ /** 撑满父容器(每项等分宽度) */
135
+ block: {
136
+ type: BooleanConstructor;
137
+ default: boolean;
138
+ };
139
+ /** 选中变化回调 */
140
+ onChange: {
141
+ type: PropType<(value: string | number) => void>;
142
+ default: undefined;
143
+ };
144
+ }>> & Readonly<{
145
+ "onUpdate:modelValue"?: ((v: string | number) => any) | undefined;
146
+ }>, {
147
+ block: boolean;
148
+ size: ControlSize;
149
+ disabled: boolean;
150
+ name: string;
151
+ onChange: (value: string | number) => void;
152
+ shape: CapsuleShape;
153
+ options: CapsuleOption[];
154
+ defaultValue: string | number | undefined;
155
+ modelValue: string | number | undefined;
156
+ }, SlotsType<{
157
+ default?: (context: {
158
+ value: string | number | undefined;
159
+ select: (value: string | number) => void;
160
+ }) => VNodeChild;
161
+ }>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,101 @@
1
+ import { defineComponent, ref, computed, createVNode, Fragment } from "vue";
2
+ const Capsule = /* @__PURE__ */ defineComponent({
3
+ name: "Capsule",
4
+ inheritAttrs: false,
5
+ props: {
6
+ /** 选项表(也可用默认插槽自排) */
7
+ options: {
8
+ type: Array,
9
+ default: void 0
10
+ },
11
+ /** 受控值;不传即非受控(由 `defaultValue` 起,再缺省则为第一个可选项) */
12
+ modelValue: {
13
+ type: [String, Number],
14
+ default: void 0
15
+ },
16
+ /** 非受控初始值(缺省 = 第一个可选项) */
17
+ defaultValue: {
18
+ type: [String, Number],
19
+ default: void 0
20
+ },
21
+ /** 原生分组名(与 tabset 组合时**必须**给,操作层靠它认组;缺省自动生成) */
22
+ name: {
23
+ type: String,
24
+ default: void 0
25
+ },
26
+ /** 整组禁用 */
27
+ disabled: {
28
+ type: Boolean,
29
+ default: false
30
+ },
31
+ /** 尺寸档(24 / 32 / 40,只覆盖令牌) */
32
+ size: {
33
+ type: String,
34
+ default: "md"
35
+ },
36
+ /** 外形:`pill` 胶囊(缺省)/ `square` 圆角矩形(轨道与选中项同取复选框档圆角) */
37
+ shape: {
38
+ type: String,
39
+ default: "pill"
40
+ },
41
+ /** 撑满父容器(每项等分宽度) */
42
+ block: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+ /** 选中变化回调 */
47
+ onChange: {
48
+ type: Function,
49
+ default: void 0
50
+ }
51
+ },
52
+ emits: {
53
+ "update:modelValue": (v) => true
54
+ },
55
+ slots: Object,
56
+ setup(props, {
57
+ emit,
58
+ slots,
59
+ attrs
60
+ }) {
61
+ const group = `mh-capsule-${Math.random().toString(36).slice(2, 10)}`;
62
+ const inner = ref(props.defaultValue);
63
+ const current = computed(() => props.modelValue ?? inner.value ?? props.options?.find((option) => !option.disabled)?.value);
64
+ const select = (value) => {
65
+ const option = props.options?.find((item) => item.value === value);
66
+ if (props.disabled || option?.disabled) return;
67
+ if (props.modelValue === void 0) inner.value = value;
68
+ emit("update:modelValue", value);
69
+ props.onChange?.(value);
70
+ };
71
+ return () => createVNode("div", {
72
+ "class": ["mh-capsule", props.size === "md" ? "" : `mh-capsule--${props.size}`, props.shape === "square" ? "mh-capsule--square" : "", props.block ? "mh-capsule--block" : "", attrs.class].filter(Boolean).join(" "),
73
+ "style": attrs.style
74
+ }, [slots.default ? slots.default({
75
+ value: current.value,
76
+ select
77
+ }) : props.options?.map((option, index) => {
78
+ const id = `${group}-${index}`;
79
+ const checked = option.value === current.value;
80
+ return createVNode(Fragment, {
81
+ "key": String(option.value)
82
+ }, [createVNode("input", {
83
+ "class": "mh-capsule__input",
84
+ "type": "radio",
85
+ "id": id,
86
+ "name": props.name ?? group,
87
+ "value": option.value,
88
+ "checked": checked,
89
+ "disabled": props.disabled || option.disabled,
90
+ "onChange": () => select(option.value)
91
+ }, null), createVNode("label", {
92
+ "class": ["mh-capsule__item", props.disabled || option.disabled ? "is-disabled" : "", checked ? "is-selected" : ""].filter(Boolean).join(" "),
93
+ "for": id,
94
+ "data-state": checked ? "active" : "inactive"
95
+ }, [option.label])]);
96
+ })]);
97
+ }
98
+ });
99
+ export {
100
+ Capsule
101
+ };