index.tsx 8.6 KB
Newer Older
D
DCloud_LXH 已提交
1 2 3 4 5 6 7 8
import {
  inject,
  onBeforeUnmount,
  ref,
  defineComponent,
  Text,
  computed,
} from 'vue'
9 10
import { uniLabelKey, UniLabelCtx } from '../label'
import { useListeners } from '../../helpers/useListeners'
D
DCloud_LXH 已提交
11
import { useAttrs } from '../../helpers/useAttrs'
fxy060608's avatar
fxy060608 已提交
12 13 14 15 16
import {
  createNVueTextVNode,
  NVueComponentStyles,
  useHoverClass,
} from '../utils'
17 18
import { buttonProps } from '../../components/button'
import { extend } from '@vue/shared'
19
import { uniFormKey, UniFormCtx } from '../../components/form'
20

fxy060608's avatar
fxy060608 已提交
21
const buttonStyle: NVueComponentStyles = [
22 23
  {
    ub: {
fxy060608's avatar
fxy060608 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
      '': {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        position: 'relative',
        paddingLeft: '5',
        paddingRight: '5',
        overflow: 'hidden',
        color: '#000000',
        backgroundColor: '#f8f8f8',
        borderRadius: '5',
        borderStyle: 'solid',
        borderWidth: '1',
        borderColor: '#dbdbdb',
      },
39 40
    },
    'ub-t': {
fxy060608's avatar
fxy060608 已提交
41 42 43 44 45 46
      '': {
        color: '#000000',
        fontSize: '18',
        textDecoration: 'none',
        lineHeight: '46',
      },
47 48
    },
    'ub-d': {
fxy060608's avatar
fxy060608 已提交
49 50 51
      '': {
        backgroundColor: '#f8f8f8',
      },
52 53
    },
    'ub-p': {
fxy060608's avatar
fxy060608 已提交
54 55 56 57
      '': {
        backgroundColor: '#007aff',
        borderColor: '#0062cc',
      },
58 59
    },
    'ub-w': {
fxy060608's avatar
fxy060608 已提交
60 61 62 63
      '': {
        backgroundColor: '#e64340',
        borderColor: '#b83633',
      },
64 65
    },
    'ub-d-t': {
fxy060608's avatar
fxy060608 已提交
66 67 68
      '': {
        color: '#000000',
      },
69 70
    },
    'ub-p-t': {
fxy060608's avatar
fxy060608 已提交
71 72 73
      '': {
        color: '#ffffff',
      },
74 75
    },
    'ub-w-t': {
fxy060608's avatar
fxy060608 已提交
76 77 78
      '': {
        color: '#ffffff',
      },
79 80
    },
    'ub-d-d': {
fxy060608's avatar
fxy060608 已提交
81 82 83
      '': {
        backgroundColor: '#f7f7f7',
      },
84 85
    },
    'ub-p-d': {
fxy060608's avatar
fxy060608 已提交
86 87 88 89
      '': {
        backgroundColor: '#63acfc',
        borderColor: '#4f8aca',
      },
90 91
    },
    'ub-w-d': {
fxy060608's avatar
fxy060608 已提交
92 93 94 95
      '': {
        backgroundColor: '#ec8b89',
        borderColor: '#bd6f6e',
      },
96 97
    },
    'ub-d-t-d': {
fxy060608's avatar
fxy060608 已提交
98 99 100
      '': {
        color: '#cccccc',
      },
101 102
    },
    'ub-p-t-d': {
fxy060608's avatar
fxy060608 已提交
103 104 105
      '': {
        color: 'rgba(255,255,255,0.6)',
      },
106 107
    },
    'ub-w-t-d': {
fxy060608's avatar
fxy060608 已提交
108 109 110
      '': {
        color: 'rgba(255,255,255,0.6)',
      },
111 112
    },
    'ub-d-plain': {
fxy060608's avatar
fxy060608 已提交
113 114 115 116
      '': {
        borderColor: '#353535',
        backgroundColor: 'rgba(0,0,0,0)',
      },
117 118
    },
    'ub-p-plain': {
fxy060608's avatar
fxy060608 已提交
119 120 121 122
      '': {
        borderColor: '#007aff',
        backgroundColor: 'rgba(0,0,0,0)',
      },
123 124
    },
    'ub-w-plain': {
fxy060608's avatar
fxy060608 已提交
125 126 127 128
      '': {
        borderColor: '#e64340',
        backgroundColor: 'rgba(0,0,0,0)',
      },
129 130
    },
    'ub-d-t-plain': {
fxy060608's avatar
fxy060608 已提交
131 132 133
      '': {
        color: '#353535',
      },
134 135
    },
    'ub-p-t-plain': {
fxy060608's avatar
fxy060608 已提交
136 137 138
      '': {
        color: '#007aff',
      },
139 140
    },
    'ub-w-t-plain': {
fxy060608's avatar
fxy060608 已提交
141 142 143
      '': {
        color: '#e64340',
      },
144 145
    },
    'ub-d-d-plain': {
fxy060608's avatar
fxy060608 已提交
146 147 148 149
      '': {
        borderColor: '#c6c6c6',
        backgroundColor: 'rgba(0,0,0,0)',
      },
150 151
    },
    'ub-p-d-plain': {
fxy060608's avatar
fxy060608 已提交
152 153 154 155
      '': {
        borderColor: '#c6c6c6',
        backgroundColor: 'rgba(0,0,0,0)',
      },
156 157
    },
    'ub-w-d-plain': {
fxy060608's avatar
fxy060608 已提交
158 159 160 161
      '': {
        borderColor: '#c6c6c6',
        backgroundColor: 'rgba(0,0,0,0)',
      },
162 163
    },
    'ub-d-t-d-plain': {
fxy060608's avatar
fxy060608 已提交
164 165 166
      '': {
        color: 'rgba(0,0,0,0.2)',
      },
167 168
    },
    'ub-p-t-d-plain': {
fxy060608's avatar
fxy060608 已提交
169 170 171
      '': {
        color: 'rgba(0,0,0,0.2)',
      },
172 173
    },
    'ub-w-t-d-plain': {
fxy060608's avatar
fxy060608 已提交
174 175 176
      '': {
        color: 'rgba(0,0,0,0.2)',
      },
177 178
    },
    'ub-mini': {
fxy060608's avatar
fxy060608 已提交
179 180 181 182 183 184 185 186
      '': {
        lineHeight: '30',
        fontSize: '13',
        paddingTop: 0,
        paddingRight: '17.5',
        paddingBottom: 0,
        paddingLeft: '17.5',
      },
187 188
    },
    'ub-loading': {
fxy060608's avatar
fxy060608 已提交
189 190 191 192 193
      '': {
        width: '18',
        height: '18',
        marginRight: '10',
      },
194 195
    },
    'ub-d-loading': {
fxy060608's avatar
fxy060608 已提交
196 197 198 199
      '': {
        color: 'rgba(255,255,255,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
200 201
    },
    'ub-p-loading': {
fxy060608's avatar
fxy060608 已提交
202 203 204 205
      '': {
        color: 'rgba(255,255,255,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
206 207
    },
    'ub-w-loading': {
fxy060608's avatar
fxy060608 已提交
208 209 210 211
      '': {
        color: 'rgba(255,255,255,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
212 213
    },
    'ub-d-loading-plain': {
fxy060608's avatar
fxy060608 已提交
214
      '': { color: '#353535' },
215 216
    },
    'ub-p-loading-plain': {
fxy060608's avatar
fxy060608 已提交
217 218 219 220
      '': {
        color: '#007aff',
        backgroundColor: '#0062cc',
      },
221 222
    },
    'ub-w-loading-plain': {
fxy060608's avatar
fxy060608 已提交
223 224 225 226
      '': {
        color: '#e64340',
        backgroundColor: 'rgba(0,0,0,0)',
      },
227 228
    },
    'ub-d-hover': {
fxy060608's avatar
fxy060608 已提交
229 230 231 232
      '': {
        opacity: 0.8,
        backgroundColor: '#dedede',
      },
233 234
    },
    'ub-p-hover': {
fxy060608's avatar
fxy060608 已提交
235 236 237 238
      '': {
        opacity: 0.8,
        backgroundColor: '#0062cc',
      },
239 240
    },
    'ub-w-hover': {
fxy060608's avatar
fxy060608 已提交
241 242 243 244
      '': {
        opacity: 0.8,
        backgroundColor: '#ce3c39',
      },
245 246
    },
    'ub-d-t-hover': {
fxy060608's avatar
fxy060608 已提交
247 248 249
      '': {
        color: 'rgba(0,0,0,0.6)',
      },
250 251
    },
    'ub-p-t-hover': {
fxy060608's avatar
fxy060608 已提交
252 253 254
      '': {
        color: 'rgba(255,255,255,0.6)',
      },
255 256
    },
    'ub-w-t-hover': {
fxy060608's avatar
fxy060608 已提交
257 258 259
      '': {
        color: 'rgba(255,255,255,0.6)',
      },
260 261
    },
    'ub-d-hover-plain': {
fxy060608's avatar
fxy060608 已提交
262 263 264 265 266
      '': {
        color: 'rgba(53,53,53,0.6)',
        borderColor: 'rgba(53,53,53,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
267 268
    },
    'ub-p-hover-plain': {
fxy060608's avatar
fxy060608 已提交
269 270 271 272 273
      '': {
        color: 'rgba(26,173,25,0.6)',
        borderColor: 'rgba(0,122,255,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
274 275
    },
    'ub-w-hover-plain': {
fxy060608's avatar
fxy060608 已提交
276 277 278 279 280
      '': {
        color: 'rgba(230,67,64,0.6)',
        borderColor: 'rgba(230,67,64,0.6)',
        backgroundColor: 'rgba(0,0,0,0)',
      },
281 282 283 284 285 286 287 288 289 290
    },
  },
]
const TYPES = {
  default: 'd',
  primary: 'p',
  warn: 'w',
}

export default defineComponent({
D
DCloud_LXH 已提交
291
  inheritAttrs: false,
292 293 294 295 296 297 298 299 300 301 302 303 304
  name: 'Button',
  props: extend(buttonProps, {
    type: {
      type: String,
      default: 'default',
    },
    size: {
      type: String,
      default: 'default',
    },
  }),
  styles: buttonStyle,
  setup(props, { slots, attrs }) {
D
DCloud_LXH 已提交
305 306 307
    const { $attrs, $excludeAttrs, $listeners } = useAttrs({
      excludeListeners: true,
    })
308 309
    const type = props.type as keyof typeof TYPES
    const rootRef = ref<HTMLElement | null>(null)
310 311 312 313
    const uniForm = inject<UniFormCtx>(
      uniFormKey,
      false as unknown as UniFormCtx
    )
314
    const onClick = (e: Event, isLabelClick?: boolean) => {
D
DCloud_LXH 已提交
315
      const _onClick = ($listeners.value as any).onClick || (() => {})
316 317 318
      if (props.disabled) {
        return
      }
D
DCloud_LXH 已提交
319
      _onClick(e)
320
      const formType = props.formType
321 322 323 324 325 326 327 328 329
      if (formType) {
        if (!uniForm) {
          return
        }
        if (formType === 'submit') {
          uniForm.submit(e)
        } else if (formType === 'reset') {
          uniForm.reset(e)
        }
330
      }
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
    }

    const _getClass = (t: string) => {
      let cl = 'ub-' + TYPES[type] + t
      props.disabled && (cl += '-d')
      props.plain && (cl += '-plain')
      props.size === 'mini' && t === '-t' && (cl += ' ub-mini')
      return cl
    }
    const _getHoverClass = (t: string) => {
      if (props.disabled) {
        return ''
      }
      let cl = 'ub-' + TYPES[type] + t + '-hover'
      props.plain && (cl += '-plain')
      return cl
    }

    const uniLabel = inject<UniLabelCtx>(
      uniLabelKey,
      false as unknown as UniLabelCtx
    )
    if (uniLabel) {
      uniLabel.addHandler(onClick)
      onBeforeUnmount(() => {
        uniLabel.removeHandler(onClick)
      })
    }
    useListeners(props, { 'label-click': onClick })

D
DCloud_LXH 已提交
361 362 363 364 365 366 367 368 369
    const _listeners = computed(() => {
      const obj = {}
      for (const eventName in $listeners.value) {
        const event = ($listeners.value as any)[eventName]
        if (eventName !== 'onClick') (obj as any)[eventName] = event
      }
      return obj
    })

370 371
    const wrapSlots = () => {
      if (!slots.default) return []
fxy060608's avatar
fxy060608 已提交
372 373 374 375 376 377 378 379 380
      const vnodes = slots.default()
      if (vnodes.length === 1 && vnodes[0].type === Text) {
        return [
          createNVueTextVNode(vnodes[0].children as string, {
            class: 'ub-t ' + _getClass('-t'),
          }),
        ]
      }
      return vnodes
381 382 383
    }

    return () => {
D
DCloud_LXH 已提交
384 385 386 387 388 389 390 391
      const _attrs = extend(
        {},
        useHoverClass(props),
        { hoverClass: _getHoverClass('') },
        $attrs.value,
        $excludeAttrs.value,
        _listeners.value
      )
392
      return (
D
DCloud_LXH 已提交
393
        <view
394 395 396 397 398
          ref={rootRef}
          class="ub"
          // @ts-expect-error
          class={_getClass('')}
          onClick={onClick}
D
DCloud_LXH 已提交
399
          {..._attrs}
400 401 402 403 404 405 406 407 408 409
        >
          {props.loading ? (
            <loading-indicator
              class="ub-loading"
              // @ts-expect-error
              class={`ub-${TYPES[type]}-loading`}
              {...{ arrow: 'false', animating: 'true' }}
            ></loading-indicator>
          ) : null}
          {...wrapSlots()}
D
DCloud_LXH 已提交
410
        </view>
411 412 413 414
      )
    }
  },
})