@farris/cli 2.0.2 → 2.0.3

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 (75) hide show
  1. package/package.json +2 -2
  2. package/templates/lib/.eslintrc.cjs +15 -0
  3. package/templates/lib/.prettierrc.json +8 -0
  4. package/templates/lib/components/button/index.ts +7 -0
  5. package/templates/lib/components/button/src/button.component.tsx +84 -0
  6. package/templates/lib/components/button/src/button.props.ts +55 -0
  7. package/templates/lib/components/button/src/button.scss +179 -0
  8. package/templates/lib/components/common/index.ts +6 -0
  9. package/templates/lib/components/common/src/common.scss +4 -0
  10. package/templates/lib/components/common/src/compositions/index.ts +19 -0
  11. package/templates/lib/components/common/src/compositions/types.ts +6 -0
  12. package/templates/lib/components/common/src/compositions/use-bem/index.ts +46 -0
  13. package/templates/lib/components/common/src/compositions/use-click-away/index.ts +40 -0
  14. package/templates/lib/components/common/src/compositions/use-context/use-children-contexts.ts +40 -0
  15. package/templates/lib/components/common/src/compositions/use-context/use-parent-context.ts +24 -0
  16. package/templates/lib/components/common/src/compositions/use-event-listener/index.ts +45 -0
  17. package/templates/lib/components/common/src/compositions/use-expose/index.ts +9 -0
  18. package/templates/lib/components/common/src/compositions/use-lay-render/index.ts +17 -0
  19. package/templates/lib/components/common/src/compositions/use-link/index.ts +14 -0
  20. package/templates/lib/components/common/src/compositions/use-lock-scroll/index.ts +25 -0
  21. package/templates/lib/components/common/src/compositions/use-long-press/index.ts +141 -0
  22. package/templates/lib/components/common/src/compositions/use-momentum/index.ts +82 -0
  23. package/templates/lib/components/common/src/compositions/use-mount-component/index.ts +48 -0
  24. package/templates/lib/components/common/src/compositions/use-rect/index.ts +31 -0
  25. package/templates/lib/components/common/src/compositions/use-refs/index.ts +21 -0
  26. package/templates/lib/components/common/src/compositions/use-resize-observer/index.ts +85 -0
  27. package/templates/lib/components/common/src/compositions/use-resize-observer/utils.ts +37 -0
  28. package/templates/lib/components/common/src/compositions/use-scroll-parent/index.ts +42 -0
  29. package/templates/lib/components/common/src/compositions/use-touch/index.ts +82 -0
  30. package/templates/lib/components/common/src/compositions/use-touch-move/index.ts +120 -0
  31. package/templates/lib/components/common/src/entity/base-property.ts +129 -0
  32. package/templates/lib/components/common/src/entity/entity-schema.ts +274 -0
  33. package/templates/lib/components/common/src/entity/input-base-property.ts +285 -0
  34. package/templates/lib/components/common/src/style/animation/index.scss +150 -0
  35. package/templates/lib/components/common/src/style/base.scss +63 -0
  36. package/templates/lib/components/common/src/style/fonts/farris-mobile-icon.ttf +0 -0
  37. package/templates/lib/components/common/src/style/icon.scss +6 -0
  38. package/templates/lib/components/common/src/style/index.scss +4 -0
  39. package/templates/lib/components/common/src/style/mixins/bem.scss +204 -0
  40. package/templates/lib/components/common/src/style/mixins/border-radius.scss +13 -0
  41. package/templates/lib/components/common/src/style/mixins/ellipsis.scss +15 -0
  42. package/templates/lib/components/common/src/style/mixins/hairline.scss +113 -0
  43. package/templates/lib/components/common/src/style/mixins/index.scss +6 -0
  44. package/templates/lib/components/common/src/style/mixins/margin.scss +10 -0
  45. package/templates/lib/components/common/src/style/mixins/safe-area.scss +9 -0
  46. package/templates/lib/components/common/src/style/variables.scss +113 -0
  47. package/templates/lib/components/common/src/utils/index.ts +15 -0
  48. package/templates/lib/components/common/src/utils/src/common.ts +83 -0
  49. package/templates/lib/components/common/src/utils/src/date.ts +134 -0
  50. package/templates/lib/components/common/src/utils/src/dom/event.ts +37 -0
  51. package/templates/lib/components/common/src/utils/src/hook.ts +18 -0
  52. package/templates/lib/components/common/src/utils/src/number.ts +26 -0
  53. package/templates/lib/components/common/src/utils/src/query-filter.ts +40 -0
  54. package/templates/lib/components/common/src/utils/src/resove-asset.ts +33 -0
  55. package/templates/lib/components/common/src/utils/src/string.ts +18 -0
  56. package/templates/lib/components/common/src/utils/src/throttle.ts +41 -0
  57. package/templates/lib/components/common/src/utils/src/transition.ts +14 -0
  58. package/templates/lib/components/common/src/utils/src/type.ts +105 -0
  59. package/templates/lib/components/common/src/utils/src/use-appearance.ts +33 -0
  60. package/templates/lib/components/common/src/utils/src/with-install.ts +16 -0
  61. package/templates/lib/components/common/src/utils/src/with-register-designer.ts +16 -0
  62. package/templates/lib/components/common/src/utils/src/with-register.ts +16 -0
  63. package/templates/lib/components/common/types.ts +131 -0
  64. package/templates/lib/components/index.scss +2 -0
  65. package/templates/lib/components/index.ts +21 -0
  66. package/templates/lib/farris.config.mjs +56 -0
  67. package/templates/lib/index.html +12 -0
  68. package/templates/lib/package.json +32 -0
  69. package/templates/lib/src/App.vue +80 -0
  70. package/templates/lib/src/components/TheButton.vue +3 -0
  71. package/templates/lib/src/main.ts +10 -0
  72. package/templates/lib/src/router/index.ts +23 -0
  73. package/templates/lib/src/views/AboutView.vue +15 -0
  74. package/templates/lib/src/views/HomeView.vue +9 -0
  75. package/templates/lib/tsconfig.json +20 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@farris/cli",
3
3
  "private": false,
4
- "version": "2.0.2",
4
+ "version": "2.0.3",
5
5
  "type": "module",
6
6
  "typings": "lib/index.d.ts",
7
7
  "bin": {
@@ -29,7 +29,7 @@
29
29
  "inquirer": "^9.3.0",
30
30
  "ora": "^8.0.1",
31
31
  "typescript": "^4.6.4",
32
- "vite": "^4.4.1",
32
+ "vite": "^4.5.10",
33
33
  "vite-plugin-css-injected-by-js": "^3.5.2",
34
34
  "vite-plugin-dts": "^3.9.1",
35
35
  "glob": "11.0.3"
@@ -0,0 +1,15 @@
1
+ /* eslint-env node */
2
+ require('@rushstack/eslint-patch/modern-module-resolution');
3
+
4
+ module.exports = {
5
+ root: true,
6
+ 'extends': [
7
+ 'plugin:vue/vue3-essential',
8
+ 'eslint:recommended',
9
+ '@vue/eslint-config-typescript',
10
+ '@vue/eslint-config-prettier/skip-formatting'
11
+ ],
12
+ parserOptions: {
13
+ ecmaVersion: 'latest'
14
+ }
15
+ };
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/prettierrc",
3
+ "semi": false,
4
+ "tabWidth": 2,
5
+ "singleQuote": true,
6
+ "printWidth": 100,
7
+ "trailingComma": "none"
8
+ }
@@ -0,0 +1,7 @@
1
+ import { Plugin } from 'vue';
2
+ import { withInstall } from '@components/common';
3
+ import ButtonInstallless from './src/button.component';
4
+
5
+ const Button = withInstall(ButtonInstallless);
6
+ export { Button };
7
+ export default Button as typeof Button & Plugin;
@@ -0,0 +1,84 @@
1
+ import { CSSProperties, computed, defineComponent } from 'vue';
2
+ import { useBem } from '@/components/common';
3
+ import { BUTTON_NAME, ButtonProps, buttonProps } from './button.props';
4
+
5
+ export default defineComponent({
6
+ name: BUTTON_NAME,
7
+ props: buttonProps,
8
+ emits: ['click'],
9
+ setup(props: ButtonProps, context) {
10
+ const { slots } = context;
11
+
12
+ const { bem, getModifierClass } = useBem(BUTTON_NAME);
13
+
14
+ const buttonClass = computed(() => {
15
+ const classList = [bem(), getModifierClass(props.type)];
16
+ props.disabled && classList.push(getModifierClass('disabled'));
17
+ props.block && classList.push(getModifierClass('block'));
18
+ props.round && classList.push(getModifierClass('round'));
19
+ props.plain && classList.push(getModifierClass('plain'));
20
+ props.noBorder && classList.push(getModifierClass('noborder'));
21
+ props.loading && classList.push(getModifierClass('loading'));
22
+ props.size && classList.push(getModifierClass(props.size));
23
+ return classList;
24
+ });
25
+
26
+ const applyGradientBorderBehavior = (style: CSSProperties, color: string) =>{
27
+ const isGradientColor = color.includes('gradient');
28
+ if (isGradientColor) {
29
+ style.border = 0;
30
+ } else {
31
+ style.borderColor = color;
32
+ }
33
+ };
34
+
35
+ const buttonStyle = computed(() => {
36
+ const textColor = props.plain ? props.color : '#fff';
37
+ const backgroundColor = !props.plain ? props.color : null;
38
+
39
+ const style: CSSProperties = {};
40
+ if (props.color) {
41
+ style.color = textColor;
42
+ style.boxShadow = 'none';
43
+ backgroundColor && (style.background = backgroundColor);
44
+ applyGradientBorderBehavior(style, props.color);
45
+ }
46
+ return style;
47
+ });
48
+
49
+ const onClickButton = ($event: Event) =>{
50
+ $event.stopPropagation();
51
+ if (!props.disabled) {
52
+ context.emit('click', $event);
53
+ }
54
+ };
55
+
56
+ const renderLoading = () => {
57
+ return (
58
+ props.loading && <>
59
+ <span class={bem('loading')}>
60
+ <svg viewBox="25 25 50 50" class={bem('loading-icon-circular')}>
61
+ <circle cx="50" cy="50" r="20" fill="none" />
62
+ </svg>
63
+ </span>
64
+ {props.loadingText && <span class={bem('loading-text')}>{props.loadingText}</span>}
65
+ </>
66
+ );
67
+ };
68
+
69
+ const renderText = ()=> {
70
+ return slots.default && <span class={bem('text')}>{slots.default()}</span>;
71
+ };
72
+
73
+ return () => (
74
+ <button
75
+ class={buttonClass.value}
76
+ style={buttonStyle.value}
77
+ onClick={onClickButton}
78
+ >
79
+ {renderLoading()}
80
+ {renderText()}
81
+ </button>
82
+ );
83
+ }
84
+ });
@@ -0,0 +1,55 @@
1
+ import { ExtractPropTypes, PropType } from 'vue';
2
+
3
+ export type ButtonType = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
4
+ export type ButtonSize = 'large' | 'normal' | 'small' | 'mini';
5
+
6
+ export const BUTTON_NAME = "fm-button";
7
+
8
+ export const buttonProps = {
9
+ type: {
10
+ type: String as PropType<ButtonType>,
11
+ default: 'primary'
12
+ },
13
+ size: {
14
+ type: String as PropType<ButtonSize>,
15
+ default: ''
16
+ },
17
+ color: {
18
+ type: String,
19
+ default: ''
20
+ },
21
+ block: {
22
+ type: Boolean,
23
+ default: false
24
+ },
25
+ noBorder: {
26
+ type: Boolean,
27
+ default: false
28
+ },
29
+ plain: {
30
+ type: Boolean,
31
+ default: false
32
+ },
33
+ round: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ disabled: {
38
+ type: Boolean,
39
+ default: false
40
+ },
41
+ icon: {
42
+ type: String,
43
+ default: ''
44
+ },
45
+ loading: {
46
+ type: Boolean,
47
+ default: false
48
+ },
49
+ loadingText: {
50
+ type: String,
51
+ default: ''
52
+ }
53
+ };
54
+
55
+ export type ButtonProps = ExtractPropTypes<typeof buttonProps>;
@@ -0,0 +1,179 @@
1
+ @use '../../common/src/style/mixins/index.scss' as *;
2
+
3
+ :root {
4
+ --fm-button-height: 42px;
5
+ --fm-button-padding: 0 14px;
6
+ --fm-button-radius: 2px;
7
+ --fm-button-border-width: 1px;
8
+ --fm-button-color: var(--fm-white);
9
+ --fm-button-line-height: var(--fm-line-height);
10
+ --fm-button-font-size: var(--fm-font-size);
11
+ --fm-button-plain-background: var(--fm-white);
12
+ --fm-button-lg-height: 46px;
13
+ --fm-button-lg-font-size: 18px;
14
+ --fm-button-md-height: 38px;
15
+ --fm-button-md-font-size: 14px;
16
+ --fm-button-sm-height: 34px;
17
+ --fm-button-sm-padding: 0 8px;
18
+ --fm-button-sm-font-size: 12px;
19
+ --fm-button-xs-height: 28px;
20
+ --fm-button-xs-font-size: 10px;
21
+ --fm-button-secondary-color: var(--fm-blue-light);
22
+ }
23
+
24
+ @include b(button){
25
+ position: relative;
26
+ cursor: pointer;
27
+ display: inline-flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+ box-sizing: border-box;
31
+ text-align: center;
32
+ margin: 0;
33
+ border: none;
34
+ transition: opacity 0.2s;
35
+ color: var(--fm-button-color);
36
+ height: var(--fm-button-height);
37
+ padding: var(--fm-button-padding);
38
+ font-size: var(--fm-button-font-size);
39
+ line-height: var(--fm-button-line-height);
40
+ border-radius: var(--fm-button-radius);
41
+
42
+ @include m((primary, info)) {
43
+ background: var(--fm-primary-color);
44
+ }
45
+
46
+ @include m(secondary) {
47
+ color: var(--fm-primary-color);
48
+ background: var(--fm-button-secondary-color);
49
+ }
50
+
51
+ @include m(danger) {
52
+ background-color: var(--fm-danger-color);
53
+ }
54
+
55
+ @include m(warning) {
56
+ background-color: var(--fm-warning-color);
57
+ }
58
+
59
+ @include m(success) {
60
+ background-color: var(--fm-success-color);
61
+ }
62
+
63
+ @include m(plain) {
64
+ box-shadow: none;
65
+ background: var(--fm-button-plain-background);
66
+ @include root-m((primary, info)) {
67
+ color: var(--fm-primary-color);
68
+ border: var(--fm-button-border-width) solid var(--fm-primary-color);
69
+ }
70
+ @include root-m(success) {
71
+ color: var(--fm-success-color);
72
+ border: var(--fm-button-border-width) solid var(--fm-success-color);
73
+ }
74
+ @include root-m(danger) {
75
+ color: var(--fm-danger-color);
76
+ border: var(--fm-button-border-width) solid var(--fm-danger-color);
77
+ }
78
+ @include root-m(warning) {
79
+ color: var(--fm-button-warning-color);
80
+ border: var(--fm-button-border-width) solid var(--fm-button-warning-color);
81
+ }
82
+ }
83
+
84
+ @include m(noborder) {
85
+ border: none !important;
86
+ }
87
+
88
+ @include m(large) {
89
+ height: var(--fm-button-lg-height);
90
+ font-size: var(--fm-button-lg-font-size);
91
+ }
92
+
93
+ @include m(normal) {
94
+ height: var(--fm-button-md-height);
95
+ font-size: var(--fm-button-md-font-size);
96
+ }
97
+
98
+ @include m(small) {
99
+ height: var(--fm-button-sm-height);
100
+ padding: var(--fm-button-sm-padding);
101
+ font-size: var(--fm-button-sm-font-size);
102
+ }
103
+
104
+ @include m(mini) {
105
+ height: var(--fm-button-xs-height);
106
+ padding: var(--fm-button-sm-padding);
107
+ font-size: var(--fm-button-xs-font-size);
108
+ }
109
+
110
+ @include m(block) {
111
+ display: flex;
112
+ width: 100%;
113
+ }
114
+
115
+ @include m(disabled) {
116
+ cursor: not-allowed;
117
+ opacity: var(--fm-disabled-opacity);
118
+ }
119
+
120
+ @include m((loading, disabled)) {
121
+ &::before {
122
+ display: none;
123
+ }
124
+ }
125
+
126
+ @include m(round) {
127
+ border-radius: var(--fm-radius-max);
128
+ }
129
+
130
+ @include m(square) {
131
+ border-radius: 0;
132
+ }
133
+
134
+ @include e(loading) {
135
+ display: inline-block;
136
+ width: 20px;
137
+ max-width: 100%;
138
+ height: 20px;
139
+ max-height: 100%;
140
+ vertical-align: middle;
141
+ animation: fm-rotate 2s linear infinite;
142
+ circle {
143
+ animation: fm-circular 1.5s ease-in-out infinite;
144
+ stroke: currentColor;
145
+ stroke-width: 4;
146
+ stroke-linecap: round;
147
+ }
148
+ }
149
+ @include e(loading-icon-circular) {
150
+ color: #fff;
151
+ }
152
+ @include e(loading-text) {
153
+ margin-left: 6px;
154
+ }
155
+ @include e(icon) {
156
+ &:not(:last-child) {
157
+ margin-right: 6px;
158
+ }
159
+ }
160
+
161
+ &::before {
162
+ position: absolute;
163
+ top: 50%;
164
+ left: 50%;
165
+ width: 100%;
166
+ height: 100%;
167
+ background-color: #000;
168
+ border: inherit;
169
+ border-color: #000;
170
+ border-radius: inherit;
171
+ -webkit-transform: translate(-50%, -50%);
172
+ transform: translate(-50%, -50%);
173
+ opacity: 0;
174
+ content: ' ';
175
+ }
176
+ &:active::before {
177
+ opacity: 0.1;
178
+ }
179
+ }
@@ -0,0 +1,6 @@
1
+ export * from './src/compositions';
2
+ export * from './src/utils';
3
+ export * from './types';
4
+
5
+ export const FM_UI_PROVIDER_SERVICE_TOKEN = Symbol('UIProviderService');
6
+
@@ -0,0 +1,4 @@
1
+ @use './style/variables';
2
+ @use './style/base';
3
+ @use './style/icon';
4
+ @use './style/animation';
@@ -0,0 +1,19 @@
1
+ export * from './types';
2
+ export * from './use-context/use-parent-context';
3
+ export * from './use-context/use-children-contexts';
4
+ export * from './use-event-listener';
5
+ export * from './use-touch-move';
6
+ export * from './use-touch';
7
+ export * from './use-lay-render';
8
+ export * from './use-refs';
9
+ export * from './use-rect';
10
+ export * from './use-expose';
11
+ export * from './use-mount-component';
12
+ export * from './use-bem';
13
+ export * from './use-link';
14
+ export * from './use-click-away';
15
+ export * from './use-lock-scroll';
16
+ export * from './use-momentum';
17
+ export * from './use-scroll-parent';
18
+ export * from './use-resize-observer';
19
+ export * from './use-long-press';
@@ -0,0 +1,6 @@
1
+ export interface ParentProvideValue<ParentContext, ChildContext> {
2
+ addChild(childContext: ChildContext): void;
3
+ removeChild(childContext: ChildContext): void;
4
+ childContexts: Array<ChildContext>;
5
+ parentContext: ParentContext;
6
+ };
@@ -0,0 +1,46 @@
1
+ import { isArray, camelToKebabCase } from '../../utils';
2
+
3
+ export const useBem = (name: string) => {
4
+
5
+ const snakeCaseName = camelToKebabCase(name);
6
+
7
+ /**
8
+ * @param element 元素类名
9
+ * @returns .block__element
10
+ */
11
+ const getElementClass = (element?: string | string[])=>{
12
+ if(!element) {
13
+ return snakeCaseName;
14
+ }
15
+ const elementClass = isArray(element) ? element.join('__') : element;
16
+ return `${snakeCaseName}__${elementClass}`;
17
+ };
18
+
19
+ /**
20
+ * @param modifier 修饰符
21
+ * @param element 元素类名
22
+ * @returns .block[__element]--modifier
23
+ */
24
+ const getModifierClass = (modifier: string, element?: string | string[])=>{
25
+ const modifierClass = modifier ? `--${modifier}` : '';
26
+ if(element){
27
+ return getElementClass(element) + modifierClass;
28
+ }
29
+ return snakeCaseName + modifierClass;
30
+ };
31
+
32
+ /**
33
+ * @param element 元素类名
34
+ * @param modifier 修饰符
35
+ * @returns .block__element--modifier
36
+ */
37
+ const bem = (element?: string | string[], modifier?: string) => {
38
+ return modifier ? getModifierClass(modifier, element) : getElementClass(element);
39
+ };
40
+
41
+ return {
42
+ bem,
43
+ getElementClass,
44
+ getModifierClass
45
+ };
46
+ };
@@ -0,0 +1,40 @@
1
+ import { Ref, unref } from 'vue';
2
+ import { useEventListener } from '../use-event-listener';
3
+ import { inBrowser, initNodePath } from '../../utils';
4
+
5
+ export type ClickAwayOptions = {
6
+ eventName?: string
7
+ active?: Ref<boolean> | boolean
8
+ }
9
+
10
+ export function useClickAway(
11
+ target: Element | Ref<Element | undefined>,
12
+ listener: EventListener,
13
+ options: ClickAwayOptions = {},
14
+ ) {
15
+ if (!inBrowser) {
16
+ return;
17
+ }
18
+
19
+ const { eventName = 'click', active = true } = options;
20
+
21
+ const isOutsideElement = (event: Event)=>{
22
+ const _target = unref(target);
23
+ if(!_target){
24
+ return false;
25
+ }
26
+ // 多重条件,防止节点被删除后误触发
27
+ return document.contains(event.target as Node) && !_target.contains(event.target as Node);
28
+ };
29
+
30
+ const onClick = (event: Event) => {
31
+ const _active = unref(active);
32
+
33
+ const enableListener = _active && isOutsideElement(event);
34
+
35
+ if (enableListener) {
36
+ listener(event);
37
+ }
38
+ };
39
+ useEventListener(eventName, onClick, { target: document });
40
+ }
@@ -0,0 +1,40 @@
1
+ import { provide, InjectionKey } from 'vue';
2
+ import { ParentProvideValue } from '../types';
3
+
4
+ export function useChildrenContexts<ParentContext, ChildContext>(
5
+ parentKey: InjectionKey<ParentProvideValue<ParentContext, ChildContext>>,
6
+ parentContext?: ParentContext
7
+ ): { childContexts: Array<ChildContext> } {
8
+ const childContexts: Array<ChildContext> = [];
9
+
10
+ /**
11
+ * 注册子上下文
12
+ */
13
+ function addChild(childContext: ChildContext): void {
14
+ childContexts.push(childContext);
15
+ }
16
+
17
+ /**
18
+ * 移除子上下文
19
+ */
20
+ function removeChild(childContext: ChildContext): void {
21
+ const childIndex = childContexts.indexOf(childContext);
22
+ if (childIndex === -1) {
23
+ return;
24
+ }
25
+ childContexts.splice(childIndex, 1);
26
+ }
27
+
28
+ // 注入父上下文
29
+ const provideValue: ParentProvideValue<ParentContext, ChildContext> = {
30
+ addChild,
31
+ removeChild,
32
+ childContexts,
33
+ parentContext
34
+ };
35
+ provide(parentKey, provideValue);
36
+
37
+ return {
38
+ childContexts
39
+ };
40
+ }
@@ -0,0 +1,24 @@
1
+ import { inject, onUnmounted, InjectionKey } from 'vue';
2
+ import { ParentProvideValue } from '../types';
3
+
4
+ export function useParentContext<ParentContext, ChildContext>(
5
+ key: InjectionKey<ParentProvideValue<ParentContext, ChildContext>>,
6
+ childContext?: ChildContext
7
+ ): { parentContext: ParentContext } {
8
+ const parent = inject(key, null);
9
+ if (!parent) {
10
+ return {
11
+ parentContext: null
12
+ };
13
+ }
14
+
15
+ const { addChild, removeChild, parentContext } = parent;
16
+
17
+ addChild(childContext);
18
+ onUnmounted(() => {
19
+ removeChild(childContext);
20
+ });
21
+ return {
22
+ parentContext
23
+ };
24
+ }
@@ -0,0 +1,45 @@
1
+ import { onMountedOrActivated, inBrowser } from '../../utils';
2
+ import { unref, onUnmounted, onDeactivated, Ref } from 'vue';
3
+
4
+ export const supportsPassive = false;
5
+
6
+ export type UseEventListenerOptions = {
7
+ target?: EventTarget | Ref<EventTarget | undefined>;
8
+ capture?: boolean;
9
+ passive?: boolean;
10
+ immediate?: boolean;
11
+ };
12
+
13
+ export function useEventListener(type: string, listener: EventListener, options: UseEventListenerOptions = {}) {
14
+ if (!inBrowser) {
15
+ return;
16
+ }
17
+
18
+ const { target = window, passive = false, capture = false, immediate = false } = options;
19
+ let attached = false;
20
+
21
+ const add = () => {
22
+ const element = unref(target);
23
+
24
+ if (element && !attached) {
25
+ element.addEventListener(type, listener, supportsPassive ? {
26
+ capture,
27
+ passive
28
+ } : capture);
29
+ attached = true;
30
+ }
31
+ };
32
+
33
+ const remove = () => {
34
+ const element = unref(target);
35
+
36
+ if (element && attached) {
37
+ element.removeEventListener(type, listener, capture);
38
+ attached = false;
39
+ }
40
+ };
41
+
42
+ immediate ? add() : onMountedOrActivated(add);
43
+ onUnmounted(remove);
44
+ onDeactivated(remove);
45
+ }
@@ -0,0 +1,9 @@
1
+ import { getCurrentInstance } from 'vue';
2
+
3
+ // expose public api
4
+ export function useExpose(apis: Record<string, any>) {
5
+ const instance = getCurrentInstance();
6
+ if (instance) {
7
+ Object.assign(instance.proxy, apis);
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ import { ref, watch, WatchSource } from 'vue';
2
+
3
+ export function useLazyRender(show: WatchSource<boolean | undefined>) {
4
+ const inited = ref(false);
5
+
6
+ watch(
7
+ show,
8
+ (value) => {
9
+ if (value) {
10
+ inited.value = value;
11
+ }
12
+ },
13
+ { immediate: true }
14
+ );
15
+
16
+ return (render: () => JSX.Element) => () => (inited.value ? render() : null);
17
+ }
@@ -0,0 +1,14 @@
1
+ import { inject, provide } from "vue";
2
+
3
+ export const useLink = (key: string) => {
4
+ const setParent = <T>(context: T)=>{
5
+ provide(key, context);
6
+ };
7
+ const getParent = <T>(defaultValue?: any): T=>{
8
+ return inject(key, defaultValue);
9
+ };
10
+ return {
11
+ setParent,
12
+ getParent
13
+ };
14
+ };
@@ -0,0 +1,25 @@
1
+ let count = 0;
2
+
3
+ const CLASSNAME = 'fm-overflow-hidden';
4
+
5
+ export function useLockScroll(shouldLock: () => boolean) {
6
+ const lock = () => {
7
+ if (shouldLock()) {
8
+ if (!count) {
9
+ document.body.classList.add(CLASSNAME);
10
+ }
11
+ count++;
12
+ }
13
+ };
14
+
15
+ const unlock = () => {
16
+ if (shouldLock() && count) {
17
+ count--;
18
+ if (!count) {
19
+ document.body.classList.remove(CLASSNAME);
20
+ }
21
+ }
22
+ };
23
+
24
+ return [lock, unlock];
25
+ }