Skip to content

Commit

Permalink
Size prop typings
Browse files Browse the repository at this point in the history
  • Loading branch information
Fsss126 committed May 2, 2024
1 parent a56337e commit 5c90152
Show file tree
Hide file tree
Showing 22 changed files with 101 additions and 46 deletions.
4 changes: 2 additions & 2 deletions packages/ui/src/components/va-avatar/VaAvatar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import { extractComponentProps, filterComponentProps } from '../../utils/compone
import { VaIcon, VaProgressCircle, VaFallback } from '../index'
import { useComponentVariables } from '../../composables/useComponentVariables'
import { variables } from './const'
import type { Variables, Sizes } from './const'
const VaFallbackPropsDeclaration = extractComponentProps(VaFallback)
</script>
Expand All @@ -62,7 +62,7 @@ defineOptions({
const props = defineProps({
...useLoadingProps,
...useSizeProps,
...useSizeProps<Variables, Sizes>(),
...useComponentPresetProp,
...VaFallbackPropsDeclaration,
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/components/va-avatar/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { ArrayElementType } from '../../utils/types/array'
export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

export const variables = [
'display',
'justifyContent',
Expand All @@ -10,3 +13,5 @@ export const variables = [
'size',
'fontSize',
] as const

export type Variables = ArrayElementType<typeof variables>
10 changes: 2 additions & 8 deletions packages/ui/src/components/va-button/VaButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ import { useButtonTextColor } from './hooks/useButtonTextColor'
import { VaIcon } from '../va-icon'
import { VaProgressCircle } from '../va-progress-circle'
import { useComponentVariables } from '../../composables/useComponentVariables'
import { variables } from './const'
import { Variables, Sizes } from './const'
defineOptions({
name: 'VaButton',
})
const props = defineProps({
...useComponentPresetProp,
...useSizeProps,
...useSizeProps<Variables, Sizes>('medium'),
...useHoverStyleProps,
...usePressedStyleProps,
...useLoadingProps,
Expand All @@ -108,12 +108,6 @@ const props = defineProps({
gradient: { type: Boolean, default: false },
plain: { type: Boolean, default: false },
round: { type: Boolean, default: false },
size: {
type: [String, Number] as PropType<
'small' | 'medium' | 'large' | string | number
>,
default: 'medium',
},
icon: { type: String, default: '' },
iconRight: { type: String, default: '' },
iconColor: { type: String, default: '' },
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/components/va-button/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { ArrayElementType } from '../../utils/types/array'
export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

export const variables = [
'display',
'justifyContent',
Expand All @@ -24,3 +27,5 @@ export const variables = [
'borderedBorder',
'borderedStyle',
] as const

export type Variables = ArrayElementType<typeof variables>
4 changes: 2 additions & 2 deletions packages/ui/src/components/va-icon/VaIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ import {
useIcon,
} from '../../composables'
import { useComponentVariables } from '../../composables/useComponentVariables'
import { variables } from './const'
import { Variables, Sizes } from './const'
defineOptions({
name: 'VaIcon',
})
const props = defineProps({
...useSizeProps,
...useSizeProps<Variables, Sizes>(),
...useComponentPresetProp,
name: { type: String, default: '' },
tag: { type: String },
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/src/components/va-icon/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { ArrayElementType } from '../../utils/types/array'
export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

export const variables = [
'verticalAlign',
'userSelect',
'size',
] as const

export type Variables = ArrayElementType<typeof variables>
7 changes: 2 additions & 5 deletions packages/ui/src/components/va-modal/VaModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ import { defineChildProps, useChildComponents } from '../../composables/useChild
import { useComponentVariables } from '../../composables/useComponentVariables'
import pick from 'lodash/pick'
import { Sizes, Variables } from './const'
const WithTransition = defineComponent({
name: 'ModalElement',
Expand Down Expand Up @@ -205,11 +206,7 @@ const props = defineProps({
maxWidth: { type: String, default: '' },
maxHeight: { type: String, default: '' },
anchorClass: { type: String },
...useSizeProps,
size: {
type: String as PropType<StringWithAutocomplete<'medium' | 'small' | 'large' | 'auto'>>,
default: 'medium',
},
...useSizeProps<Variables, Sizes>('medium'),
fixedLayout: { type: Boolean, default: false },
withoutTransitions: { type: Boolean, default: false },
overlay: { type: Boolean, default: true },
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/va-modal/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
--va-modal-padding-left: 1.5rem;

/* Dialog */
--va-modal-dialog-size: 768px;
--va-modal-dialog-min-height: 3.125rem;
--va-modal-dialog-height: fit-content;
--va-modal-dialog-border-radius: 0.375rem;
Expand Down
13 changes: 13 additions & 0 deletions packages/ui/src/components/va-modal/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ArrayElementType } from '../../utils/types/array'
import { defaultSizes } from '../../composables'

export const variables = [] as const

export type Variables = ArrayElementType<typeof variables>

export const sizes = [
...defaultSizes,
'auto',
] as const

export type Sizes = ArrayElementType<typeof sizes>
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ import {
useBem,
} from '../../composables'
import { useComponentVariables } from '../../composables/useComponentVariables'
import { variables } from './const'
import { Variables, Sizes } from './const'
import pick from 'lodash/pick'
defineOptions({
name: 'VaProgressCircle',
})
const props = defineProps({
...useSizeProps,
...useSizeProps<Variables, Sizes>(),
...useComponentPresetProp,
modelValue: { type: [Number, String], default: 0 },
indeterminate: { type: Boolean, default: false },
Expand Down
6 changes: 6 additions & 0 deletions packages/ui/src/components/va-progress-circle/const.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { ArrayElementType } from '../../utils/types/array'

export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

export const variables = [
'position',
'overflow',
Expand All @@ -7,3 +11,5 @@ export const variables = [
'size',
'fontSize',
] as const

export type Variables = ArrayElementType<typeof variables>
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ import { useColors, useSyncProp } from '../../../../composables'
import { RatingValue } from '../../types'
import { VaIcon } from '../../../va-icon'
import { useRatingItemCommonProps } from '../../util'
defineOptions({
name: 'VaRatingItem',
})
const props = defineProps({
modelValue: { type: Number, default: 0 },
...useRatingItemCommonProps,
icon: { type: String, default: 'star' },
halfIcon: { type: String, default: 'star_half' },
emptyIcon: { type: String, default: 'star_outline' },
Expand All @@ -46,9 +47,6 @@ const props = defineProps({
tabindex: { type: [String, Number], default: 0 },
disabled: { type: Boolean, default: false },
readonly: { type: Boolean, default: false },
size: { type: [String, Number], default: 'medium' },
unselectedColor: { type: String },
color: { type: String, default: 'primary' },
})
const emit = defineEmits(['update:modelValue', 'click', 'hover'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,16 @@
</template>

<script lang="ts" setup>
import { useSizeProps } from '../../../composables'
import { useVaRatingColorsProps, useVaRatingColors } from '../hooks/useVaRatingColors'
import { useVaRatingColors } from '../hooks/useVaRatingColors'
import { useRatingItemCommonProps } from '../util'
defineOptions({
name: 'VaRatingNumberItem',
})
const props = defineProps({
...useVaRatingColorsProps,
...useSizeProps,
...useRatingItemCommonProps,
itemNumber: { type: Number, required: true },
modelValue: { type: Number, required: true },
})
const {
Expand Down
7 changes: 6 additions & 1 deletion packages/ui/src/components/va-rating/const.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { ArrayElementType } from '../../utils/types/array'
export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

const variables = [
'display',
'numberItemMargin',
'numberItemFontWeight',
'numberItemCursor',
'numberItemSize',
'itemWrapperCursor',
'size',
'fontSize',
'borderRadius',
'fontWeight',
'margin',
] as const

export type Variables = ArrayElementType<typeof variables>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { RatingValue } from '../types'
export const useVaRatingColorsProps = {
unselectedColor: { type: String },
color: { type: String, default: 'primary' },
modelValue: { type: Number },
modelValue: { type: Number, required: true, default: 0 },
}

export const useVaRatingColors = (props: ExtractPropTypes<typeof useVaRatingColorsProps>) => {
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/components/va-rating/util/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useSizeProps } from '../../../composables'
import { Sizes, Variables } from '../const'
import { useVaRatingColorsProps } from '../hooks/useVaRatingColors'

export const useRatingItemCommonProps = {
...useVaRatingColorsProps,
...useSizeProps<Variables, Sizes>(),
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@ import { computed, PropType } from 'vue'
import { useColors, useSizeProps } from '../../composables'
import { useComponentVariables } from '../../composables/useComponentVariables'
import { Sizes, Variables } from './const'
defineOptions({
name: 'VaScrollContainer',
})
const props = defineProps({
...useSizeProps,
...useSizeProps<Variables, Sizes>('small'),
vertical: { type: Boolean, default: false },
horizontal: { type: Boolean, default: false },
color: { type: String, default: 'secondary' },
rtl: { type: Boolean, default: false },
gradient: { type: Boolean, default: false },
size: {
type: [String, Number] as PropType<'small' | 'medium' | 'large' | string | number>,
default: 'small',
},
})
const { getColor } = useColors()
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/components/va-scroll-container/const.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ArrayElementType } from '../../utils/types/array'
export { defaultSizes as sizes, DefaultSizes as Sizes } from '../../composables'

export const variables = [
'scrollbarGradientTo',
'scrollbarSize',
] as const

export type Variables = ArrayElementType<typeof variables>
4 changes: 2 additions & 2 deletions packages/ui/src/composables/useComponentVariables.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { cssVariableName } from '../utils/css-variables'
import { ReadonlyOrPlainArray } from '../utils/types/array'
import { computed, getCurrentInstance } from 'vue'
import { computed, CSSProperties, getCurrentInstance } from 'vue'
import { isCSSSizeValue, isCSSVariable } from '../utils/css'
import isNil from 'lodash/isNil'
import { SizeProps, SizesConfig } from '../services/component-config/theme'
Expand Down Expand Up @@ -47,7 +47,7 @@ export const useComponentVariables = <Variables extends string>(props: SizeProps
return undefined
}

return Object.entries<string>(sizePreset.variables).reduce<Record<string, string>>((acc, [property, value]) => {
return Object.entries(sizePreset.variables as Record<string, string>).reduce<CSSProperties>((acc, [property, value]) => {
acc[cssVariableName({ componentName, property })] = value

return acc
Expand Down
20 changes: 15 additions & 5 deletions packages/ui/src/composables/useSize.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
import { PropType } from 'vue'
import { SizesConfig } from '../services/component-config/theme'
import { SizesConfig, SizeValue } from '../services/component-config/theme'
import { ArrayElementType } from '../utils/types/array'

export const defaultSizes = [
'small',
'medium',
'large',
] as const

export type DefaultSizes = ArrayElementType<typeof defaultSizes>

/**
* You could add these props to any component by destructuring them inside props option.
* @example
* props: { ...useSizeProps, componentsOwnProp, etc. }
* It's better to add props at the beginning, to make sure that Component own props will be used instead in case of collision
*/
export const useSizeProps = {
export const useSizeProps = <Variables extends string, SizeName extends string>(defaultSize?: SizeName) => ({
size: {
type: [String, Number],
type: [String, Number] as PropType<SizeValue<SizeName>>,
validator: (size: string | number) => {
return typeof size === 'string' || typeof size === 'number'
},
default: defaultSize,
},

sizesConfig: {
type: Object as PropType<SizesConfig<string, string>>,
type: Object as PropType<SizesConfig<Variables, SizeName>>,
},
}
})
11 changes: 8 additions & 3 deletions packages/ui/src/services/component-config/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
export interface SizePreset<Variables extends string> {
variables: Record<Variables, string>;
variables: Partial<Record<Variables, string>>;
}

export type SizesConfig<Variables extends string, SizeName extends string> = Record<SizeName, SizePreset<Variables>>;
/**
* @see To allow union of string and string literals https://stackoverflow.com/questions/61047551/typescript-union-of-string-and-string-literals
*/
export type SizeValue<T> = T | (string & {}) | number

export type SizesConfig<Variables extends string, SizeName extends string> = Partial<Record<SizeValue<SizeName>, SizePreset<Variables>>>;

export interface SizeProps<T extends SizesConfig<string, string>> {
size?: (T extends SizesConfig<string, infer SizeName> ? SizeName : never) | string | number;
size?: SizeValue<T extends SizesConfig<string, infer SizeName> ? SizeName : never>;
sizesConfig?: T;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { renderCSSRule } from '../../../utils/css'
import { ComponentConfig } from '../types'

const renderComponentStyles = (sizesConfig: SizesConfig<string, string>, componentName: string, scopeSelector?: string) => {
return Object.entries(sizesConfig).reduce((acc, [size, { variables }]) => {
return Object.entries(sizesConfig).reduce((acc, [size, sizePreset]) => {
const { variables } = sizePreset || {}
const definitions: CSSProperties = {}

for (const property in variables) {
Expand Down

0 comments on commit 5c90152

Please sign in to comment.