diff --git a/packages/actionsheet/index.js b/packages/actionsheet/index.js
deleted file mode 100644
index 6af3d1313..000000000
--- a/packages/actionsheet/index.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import { use } from '../utils';
-import { PopupMixin } from '../mixins/popup';
-import Icon from '../icon';
-import Loading from '../loading';
-import Popup from '../popup';
-
-const [sfc, bem] = use('actionsheet');
-
-export default sfc({
- props: {
- ...PopupMixin.props,
- title: String,
- actions: Array,
- cancelText: String,
- overlay: {
- type: Boolean,
- default: true
- },
- closeOnClickOverlay: {
- type: Boolean,
- default: true
- }
- },
-
- methods: {
- onSelect(event, item) {
- event.stopPropagation();
-
- if (!item.disabled && !item.loading) {
- if (item.callback) {
- item.callback(item);
- }
-
- this.$emit('select', item);
- }
- },
-
- onCancel() {
- this.$emit('input', false);
- this.$emit('cancel');
- }
- },
-
- render(h) {
- const { title, cancelText, onCancel } = this;
-
- const Header = () => (
-
- );
-
- const Option = item => (
- {
- this.onSelect(event, item);
- }}
- >
- {item.loading ? (
-
- ) : (
- [
- {item.name},
- item.subname && {item.subname}
- ]
- )}
-
- );
-
- const Footer = cancelText ? (
-
- {cancelText}
-
- ) : (
- {this.slots()}
- );
-
- return (
- {
- this.$emit('input', value);
- }}
- >
- {title ? Header() : this.actions.map(Option)}
- {Footer}
-
- );
- }
-});
diff --git a/packages/actionsheet/index.tsx b/packages/actionsheet/index.tsx
new file mode 100644
index 000000000..72d12312d
--- /dev/null
+++ b/packages/actionsheet/index.tsx
@@ -0,0 +1,119 @@
+import { use } from '../utils';
+import { emit, inherit } from '../utils/functional';
+import { PopupMixin } from '../mixins/popup';
+import Icon from '../icon';
+import Loading from '../loading';
+import Popup from '../popup';
+
+// Types
+import { CreateElement, RenderContext } from 'vue/types';
+import { DefaultSlots } from '../utils/use/sfc';
+import { PopupMixinProps } from '../mixins/popup/type';
+
+export type ActionsheetItem = {
+ name: string;
+ subname?: string;
+ loading?: boolean;
+ disabled?: boolean;
+ className?: string;
+ callback?: (item: ActionsheetItem) => void;
+};
+
+export type ActionsheetProps = PopupMixinProps & {
+ title?: string;
+ actions: ActionsheetItem[];
+ cancelText?: string;
+};
+
+const [sfc, bem] = use('actionsheet');
+
+function Actionsheet(
+ h: CreateElement,
+ props: ActionsheetProps,
+ slots: DefaultSlots,
+ ctx: RenderContext
+) {
+ const { title, cancelText } = props;
+
+ const onCancel = () => {
+ emit(ctx, 'input', false);
+ emit(ctx, 'cancel');
+ };
+
+ const Header = () => (
+
+ );
+
+ const Option = (item: ActionsheetItem) => (
+ {
+ event.stopPropagation();
+
+ if (!item.disabled && !item.loading) {
+ if (item.callback) {
+ item.callback(item);
+ }
+
+ emit(ctx, 'select', item);
+ }
+ }}
+ >
+ {item.loading ? (
+
+ ) : (
+ [
+ {item.name},
+ item.subname && {item.subname}
+ ]
+ )}
+
+ );
+
+ const Footer = cancelText ? (
+
+ {cancelText}
+
+ ) : (
+ {slots.default && slots.default()}
+ );
+
+ return (
+ {
+ emit(ctx, 'input', value);
+ }}
+ {...inherit(ctx)}
+ >
+ {title ? Header() : props.actions.map(Option)}
+ {Footer}
+
+ );
+}
+
+Actionsheet.props = {
+ ...PopupMixin.props,
+ title: String,
+ actions: Array,
+ cancelText: String,
+ overlay: {
+ type: Boolean,
+ default: true
+ },
+ closeOnClickOverlay: {
+ type: Boolean,
+ default: true
+ }
+};
+
+export default sfc(Actionsheet);
diff --git a/packages/actionsheet/test/index.spec.js b/packages/actionsheet/test/index.spec.js
index b51ff3792..e3b5933d7 100644
--- a/packages/actionsheet/test/index.spec.js
+++ b/packages/actionsheet/test/index.spec.js
@@ -3,6 +3,10 @@ import Actionsheet from '..';
test('callback events', () => {
const callback = jest.fn();
+ const onInput = jest.fn();
+ const onCancel = jest.fn();
+ const onSelect = jest.fn();
+
const wrapper = mount(Actionsheet, {
propsData: {
value: true,
@@ -11,6 +15,13 @@ test('callback events', () => {
{ name: 'Option', disabled: true }
],
cancelText: 'Cancel'
+ },
+ context: {
+ on: {
+ input: onInput,
+ cancel: onCancel,
+ select: onSelect
+ }
}
});
@@ -20,9 +31,9 @@ test('callback events', () => {
wrapper.find('.van-actionsheet__cancel').trigger('click');
expect(callback.mock.calls.length).toBe(1);
- expect(wrapper.emitted('cancel')).toBeTruthy();
- expect(wrapper.emitted('input')[0][0]).toBeFalsy();
- expect(wrapper.emitted('select')[0][0]).toBeTruthy();
- expect(wrapper.emitted('select')[0][1]).toBeFalsy();
+ expect(onCancel.mock.calls.length).toBeTruthy();
+ expect(onInput.mock.calls[0][0]).toBeFalsy();
+ expect(onSelect.mock.calls[0][0]).toBeTruthy();
+ expect(onSelect.mock.calls[0][1]).toBeFalsy();
expect(wrapper).toMatchSnapshot();
});
diff --git a/packages/mixins/popup/type.ts b/packages/mixins/popup/type.ts
new file mode 100644
index 000000000..9694ad6e7
--- /dev/null
+++ b/packages/mixins/popup/type.ts
@@ -0,0 +1,13 @@
+export type GetContainer = (container: HTMLElement) => void;
+
+export type PopupMixinProps = {
+ value: boolean;
+ zIndex: string | number;
+ overlay?: boolean;
+ lockScroll: boolean;
+ lazyRender: boolean;
+ overlayClass?: any;
+ overlayStyle?: object | object[];
+ getContainer?: string | GetContainer;
+ closeOnClickOverlay?: boolean;
+};