Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Respect members/events/attributes inherited from superclass #8

Merged
merged 5 commits into from Oct 25, 2023

Conversation

GREsau
Copy link
Contributor

@GREsau GREsau commented Oct 25, 2023

Supersedes #7

We were previously generating the vue component props from the vivid component's fields, instead of the vivid component's attributes. This led to a few quirks, e.g. VwcCard declared graphicSlottedContent and hasMetaSlottedContent props which don't correspond to any vvd3-card attributes (and I don't think are intended to be set by vivid consumers). This led to more obvious problems when inheriting members from superclasses, as some fields defined in superclasses were clearly not meant to be set via attributes - so this PR switches the generator to use attributes instead, which should be more "correct".

This also changes the generated vue files to set vivid component attributes as kebab-case (<vvd3-button :icon-trailing="iconTrailing">) instead of camelCase (<vvd3-button :iconTrailing="iconTrailing">) - this is largely insignificant, but now conforms to the vue recommended practice "the convention is using kebab-case in all cases to align with HTML attributes"

VwcButton.vue Before:

<!-- VWC stands for "Vivid Web Component" for more context visit https://vivid.deno.dev -->
<!-- Do not edit this file manually - this component has been auto-generated using `definition.json` model -->
<!-- For more info on this Vivid element please visit https://vivid.deno.dev/components/button -->
<template>
  <vvd3-button
    v-bind="$props"
    :style="style"
    :title="title"
    :connotation="connotation"
    :shape="shape"
    :appearance="appearance"
    :size="size"
    :stacked="stacked"
    :pending="pending"
    :label="label"
    :icon="icon"
    :iconTrailing="iconTrailing"
    @click="$emit('click', $event)"
  ></vvd3-button>
</template>

<script setup lang="ts">
import { IconId } from '../../src/generated/types'
import { CSSProperties } from 'vue'
import { registerButton, ButtonConnotation, ButtonShape, ButtonAppearance, ButtonSize } from '@vonage/vivid'
export interface VwcButtonProps {
  /**
  * Inline styles object includes standard CSSProperties plus custom css variables suitable for this Vivid element
  */
  style?: CSSProperties & {
    /**
    * undefined
    */
    '--vvd-button-cta-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-success-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-success-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-success-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-success-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-success-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-faint'?: any
  }
  title?: string
  /**
  * The connotation the button should have.
  */
  connotation?: ButtonConnotation | undefined
  /**
  * The shape the button should have.
  */
  shape?: ButtonShape | undefined
  /**
  * The appearance the button should have.
  */
  appearance?: ButtonAppearance | undefined
  /**
  * The size the button should have.
  */
  size?: ButtonSize | undefined
  /**
  * Indicates the icon is stacked.
  */
  stacked?: boolean
  /**
  * Displays the button in pending state.
  */
  pending?: boolean
  /**
  * Indicates the button's label.
  */
  label?: string | undefined
  /**
  * Icon id. One of 1149 icons. Catalog with preview/search can be found at https://icons.vivid.vonage.com
  */
  icon?: IconId
  /**
  * Indicates the icon affix alignment.
  */
  iconTrailing?: boolean
}
defineProps<VwcButtonProps>()
defineEmits<{
  (event: 'click', payload: PointerEvent): void
}>()
registerButton('vvd3')
</script>

And after:

<!-- VWC stands for "Vivid Web Component" for more context visit https://vivid.deno.dev -->
<!-- Do not edit this file manually - this component has been auto-generated using `definition.json` model -->
<!-- For more info on this Vivid element please visit https://vivid.deno.dev/components/button -->
<template>
  <vvd3-button
    v-bind="$props"
    ref="element"
    :style="style"
    :aria-current="ariaCurrent"
    :disabled="disabled"
    :value="value"
    :current-value="currentValue"
    :name="name"
    :required="required"
    :autofocus="autofocus"
    :form="form"
    :formaction="formaction"
    :formenctype="formenctype"
    :formmethod="formmethod"
    :formnovalidate="formnovalidate"
    :formtarget="formtarget"
    :type="type"
    :connotation="connotation"
    :shape="shape"
    :appearance="appearance"
    :size="size"
    :stacked="stacked"
    :pending="pending"
    :label="label"
    :icon="icon"
    :icon-trailing="iconTrailing"
    @click="$emit('click', $event)"
    @focus="$emit('focus', $event)"
    @blur="$emit('blur', $event)"
    @keydown="$emit('keydown', $event)"
    @keyup="$emit('keyup', $event)"
    @input="$emit('input', $event)"
  ></vvd3-button>
</template>

<script setup lang="ts">
import { IconId } from '../../src/generated/types'
import { CSSProperties } from 'vue'
import { registerButton, ButtonConnotation, ButtonShape, ButtonAppearance, ButtonSize } from '@vonage/vivid'
import { ref } from 'vue'
export interface VwcButtonProps {
  /**
  * Inline styles object includes standard CSSProperties plus custom css variables suitable for this Vivid element
  */
  style?: CSSProperties & {
    /**
    * undefined
    */
    '--vvd-button-cta-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-cta-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-success-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-success-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-success-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-success-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-success-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-success-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-alert-faint'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary-text'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-primary-increment'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-contrast'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-fierce'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-firm'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-soft'?: any
    /**
    * undefined
    */
    '--vvd-button-accent-faint'?: any
  }
  /**
  * Indicates the element that represents the current item within a container or set of related elements.
  */
  ariaCurrent?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false'
  /**
  * Sets the element's disabled state. A disabled element will not be included during form submission.
  */
  disabled?: boolean
  /**
  * The initial value of the form. This value sets the `value` property
only when the `value` property has not been explicitly set.
  */
  value?: string
  /**
  * The current value of the element. This property serves as a mechanism
to set the `value` property through both property assignment and the
.setAttribute() method. This is useful for setting the field's value
in UI libraries that bind data through the .setAttribute() API
and don't support IDL attribute binding.
  */
  currentValue?: string
  /**
  * The name of the element. This element's value will be surfaced during form submission under the provided name.
  */
  name?: string
  /**
  * Require the field to be completed prior to form submission.
  */
  required?: boolean
  /**
  * Determines if the element should receive document focus on page load.
  */
  autofocus?: boolean
  /**
  * The id of a form to associate the element to.
  */
  form?: string
  /**
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element for more details.
  */
  formaction?: string
  /**
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element for more details.
  */
  formenctype?: string
  /**
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element for more details.
  */
  formmethod?: string
  /**
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element for more details.
  */
  formnovalidate?: boolean
  /**
  * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button | <button> element for more details.
  */
  formtarget?: "_self" | "_blank" | "_parent" | "_top"
  /**
  * The button type.
  */
  type?: "submit" | "reset" | "button"
  /**
  * The connotation the button should have.
  */
  connotation?: ButtonConnotation | undefined
  /**
  * The shape the button should have.
  */
  shape?: ButtonShape | undefined
  /**
  * The appearance the button should have.
  */
  appearance?: ButtonAppearance | undefined
  /**
  * The size the button should have.
  */
  size?: ButtonSize | undefined
  /**
  * Indicates the icon is stacked.
  */
  stacked?: boolean
  /**
  * Displays the button in pending state.
  */
  pending?: boolean
  /**
  * Indicates the button's label.
  */
  label?: string | undefined
  /**
  * Icon id. One of 1145 icons. Catalog with preview/search can be found at https://icons.vivid.vonage.com
  */
  icon?: IconId
  /**
  * Indicates the icon affix alignment.
  */
  iconTrailing?: boolean
}
defineProps<VwcButtonProps>()
defineEmits<{
  /**
  * Fires when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.
  */
  (event: 'click', payload: MouseEvent): void
  /**
  * Fires when the element receives focus.
  */
  (event: 'focus', payload: FocusEvent): void
  /**
  * Fires when the element loses focus.
  */
  (event: 'blur', payload: FocusEvent): void
  /**
  * Fires when a key is pressed.
  */
  (event: 'keydown', payload: KeyboardEvent): void
  /**
  * Fires when a key is released.
  */
  (event: 'keyup', payload: KeyboardEvent): void
  /**
  * Fires when the value of an element has been changed.
  */
  (event: 'input', payload: Event): void
}>()
const element = ref<HTMLElement | null>(null)
defineExpose({
  /**
  *  {@inheritDoc (FormAssociated:interface).validate}
  */
  validate: (): void => (element.value as any)?.validate()
})
registerButton('vvd3')
</script>

@GREsau GREsau marked this pull request as ready for review October 25, 2023 10:28
@GREsau
Copy link
Contributor Author

GREsau commented Oct 25, 2023

This does cause the generated vue files to have some typescript errors due to missing imports for the newly-defined props:

VwcCombobox/VwcCombobox.vue(78,18): error TS2304: Cannot find name 'ComboboxAutocomplete'.
VwcCombobox/VwcCombobox.vue(90,14): error TS2304: Cannot find name 'SelectPosition'.
VwcDataGrid/VwcDataGrid.vue(46,20): error TS2304: Cannot find name 'GenerateHeaderOptions'.
VwcDivider/VwcDivider.vue(34,10): error TS2304: Cannot find name 'DividerRole'.
VwcDivider/VwcDivider.vue(38,17): error TS2304: Cannot find name 'Orientation'.
VwcMenuItem/VwcMenuItem.vue(80,10): error TS2304: Cannot find name 'MenuItemRole'.
VwcPagination/VwcPagination.vue(24,30): error TS2305: Module '"@vonage/vivid"' has no exported member 'PaginationSize'.
VwcPagination/VwcPagination.vue(71,33): error TS2304: Cannot find name 'Button'.
VwcPagination/VwcPagination.vue(71,65): error TS2304: Cannot find name 'Button'.
VwcRadioGroup/VwcRadioGroup.vue(52,17): error TS2304: Cannot find name 'Orientation'.
VwcSelect/VwcSelect.vue(130,14): error TS2304: Cannot find name 'SelectPosition'.
VwcSlider/VwcSlider.vue(80,17): error TS2304: Cannot find name 'Orientation'.
VwcSlider/VwcSlider.vue(84,10): error TS2304: Cannot find name 'SliderMode'.
VwcSlider/VwcSlider.vue(140,47): error TS2304: Cannot find name 'Direction'.
VwcTabs/VwcTabs.vue(55,17): error TS2304: Cannot find name 'TabsOrientation'.
VwcTextField/VwcTextField.vue(158,10): error TS2304: Cannot find name 'TextFieldType'.

But I think this can be solved in a separate commit. Until then, the props with those types will just be treated as though they were defined as the any type, which is still an improvement over them not being defined at all IMO

@GREsau GREsau merged commit 0156ca8 into main Oct 25, 2023
2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants