@cypress-design/vue-checkbox 0.1.0 → 0.3.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @cypress-design/vue-checkbox
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#44](https://github.com/cypress-io/cypress-design/pull/44) [`2fdaf6b`](https://github.com/cypress-io/cypress-design/commit/2fdaf6be6f81a2a851761258347ed213577c5b26) Thanks [@elevatebart](https://github.com/elevatebart)! - Add missing descriptions of props in button, tooltip, checkbox
8
+
9
+ ## 0.2.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [`e3eb9c7`](https://github.com/cypress-io/cypress-design/commit/e3eb9c7fee2d7a6e0a773e85ed4b73be04d83587) Thanks [@elevatebart](https://github.com/elevatebart)! - downgrade typescript to 4.4 for compat with app
14
+
15
+ - Updated dependencies [[`e3eb9c7`](https://github.com/cypress-io/cypress-design/commit/e3eb9c7fee2d7a6e0a773e85ed4b73be04d83587)]:
16
+ - @cypress-design/vue-icon@0.4.2
17
+
18
+ ## 0.2.0
19
+
20
+ ### Minor Changes
21
+
22
+ - [#33](https://github.com/cypress-io/cypress-design/pull/33) [`5f9cf10`](https://github.com/cypress-io/cypress-design/commit/5f9cf10ff4709fcd7d322c2dc5dbc676473b433e) Thanks [@elevatebart](https://github.com/elevatebart)! - fix design and api of checkboxes
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [[`5f9cf10`](https://github.com/cypress-io/cypress-design/commit/5f9cf10ff4709fcd7d322c2dc5dbc676473b433e)]:
27
+ - @cypress-design/vue-icon@0.3.0
28
+
3
29
  ## 0.1.0
4
30
 
5
31
  ### Minor Changes
@@ -0,0 +1,75 @@
1
+ import { ArgsTable, Canvas, Meta, Story, Description } from '@storybook/addon-docs'
2
+ import { version } from "./package.json"
3
+ import changelog from "./CHANGELOG.md?raw"
4
+
5
+ import Checkbox from './Checkbox.vue'
6
+
7
+ <h1>Checkbox<span className="text-lg font-normal"> - v{version}</span></h1>
8
+
9
+ <Meta title="Checkbox" component={Checkbox}
10
+ argTypes={{
11
+ color: {
12
+ options: ['indigo', 'red', 'jade'],
13
+ control: {
14
+ type: 'select',
15
+ },
16
+ },
17
+ }}
18
+ parameters={{
19
+ design: {
20
+ type: "figma",
21
+ url: 'https://www.figma.com/file/1WJ3GVQyMV5e7xVxPg3yID/Design-System?node-id=1027%3A9825',
22
+ }
23
+ }} />
24
+
25
+ <Canvas withSource="none">
26
+ <Story name="Checkbox">
27
+ {({ color }) => ({
28
+ template: `
29
+ <Checkbox checked label="Checked" :color="color"/>
30
+ <br />
31
+ <Checkbox label="Unchecked" :color="color"/>
32
+ <br />
33
+ <Checkbox chedked disabled label="Disabled & checked" :color="color"/>
34
+ <br />
35
+ <Checkbox disabled label="Disabled & unchecked" :color="color"/>
36
+ `,
37
+ components: { Checkbox },
38
+ data: () => ({
39
+ color
40
+ })
41
+ })}
42
+ </Story>
43
+ </Canvas>
44
+
45
+ <ArgsTable />
46
+
47
+ ## Usage
48
+
49
+ Install the component
50
+
51
+ ```
52
+ yarn add @cypress-design/vue-checkbox
53
+ ```
54
+
55
+ In the script, import the component
56
+
57
+ ```js
58
+ import Checkbox from '@cypress-design/vue-checkbox'
59
+ ```
60
+
61
+ then in the template, use it
62
+
63
+ ```html
64
+ <Checkbox checked label="Checked" color="indigo"/>
65
+ ```
66
+
67
+ or with the v-model
68
+
69
+ ```html
70
+ <Checkbox v-model="checked" label="Checked" color="indigo"/>
71
+ ```
72
+
73
+ <Description>
74
+ {changelog.replace(/^# .+/, '## Changelog')}
75
+ </Description>
package/Checkbox.vue CHANGED
@@ -1,48 +1,78 @@
1
- <template>
2
- <div class="relative flex items-center">
3
- <div class="flex items-center h-5">
4
- <input :id="id" :checked="modelValue" :aria-describedby="`${id}-description`" :name="id" type="checkbox"
5
- class="border-1 rounded border-gray-200 bg-white h-4 w-4 text-indigo-500 disabled:bg-gray-100 checked:bg-indigo-500"
6
- :class="{
7
- 'text-indigo-500 checked:border-indigo-300 checked:bg-indigo-600 checked:text-indigo-600':
8
- state === 'default',
9
- 'checked:border-jade-300 checked:bg-jade-600 checked:text-jade-600':
10
- state === 'success',
11
- 'checked:border-red-300 checked:bg-red-600 checked:text-red-600':
12
- state === 'danger',
13
- }" @click="updated()" />
14
- </div>
15
- <div class="ml-2 text-16px leading-normal">
16
- <slot name="label">
17
- <label v-if="label" :for="id" class="disabled:text-gray-500 text-gray-800 font-light select-none">
18
- {{ label }}
19
- </label>
20
- </slot>
21
- </div>
22
- </div>
23
- </template>
24
-
25
1
  <script lang="ts" setup>
26
- type InputState = 'success' | 'danger' | 'default';
2
+ import { ref, computed } from 'vue'
3
+ import { IconCheckmarkSmall } from '@cypress-design/vue-icon'
27
4
 
28
5
  const props = withDefaults(
29
6
  defineProps<{
30
- id: string;
31
- modelValue: boolean;
32
- state?: InputState;
33
- label?: string;
7
+ /**
8
+ * A unique identifier for the checkbox on the whole page.
9
+ * It will be used to give match label with input for a11y.
10
+ */
11
+ id?: string
12
+ /**
13
+ * Is the checkbox checked when it is first rendered.
14
+ */
15
+ checked?: boolean
16
+ /**
17
+ * The color of the background in the checkbox.
18
+ * The checkmark will always be white.
19
+ */
20
+ color?: 'red' | 'indigo' | 'jade'
21
+ /**
22
+ * If the checkbox is disabled, it will not be clickable.
23
+ */
24
+ disabled?: boolean
25
+ modelValue?: boolean
26
+ /**
27
+ * Label for the checkbox.
28
+ * It is very important to set this to make the checkbox accessible.
29
+ */
30
+ label?: string
34
31
  }>(),
35
32
  {
36
- state: 'default',
37
- label: undefined,
33
+ // @ts-ignore
34
+ id: crypto.randomUUID(),
35
+ color: 'indigo',
38
36
  }
39
- );
37
+ )
38
+
39
+ const localChecked = ref(props.modelValue || props.checked)
40
40
 
41
41
  const emit = defineEmits<{
42
- (event: 'update:modelValue', value: boolean): void;
43
- }>();
42
+ (event: 'update:modelValue', value: boolean): void
43
+ }>()
44
44
 
45
45
  function updated() {
46
- emit('update:modelValue', !props.modelValue)
46
+ localChecked.value = !localChecked.value
47
+ emit('update:modelValue', localChecked.value)
47
48
  }
49
+
50
+ const checkboxClasses = computed(() => [
51
+ 'block border-1 rounded h-16px w-16px',
52
+ props.disabled
53
+ ? 'border-gray-200 bg-gray-100'
54
+ : localChecked.value
55
+ ? {
56
+ 'border-indigo-500 bg-indigo-400': props.color === 'indigo',
57
+ 'border-jade-500 bg-jade-400': props.color === 'jade',
58
+ 'border-red-500 bg-red-400': props.color === 'red',
59
+ }
60
+ : 'border-gray-200 bg-white']
61
+ )
62
+
48
63
  </script>
64
+
65
+ <template>
66
+ <label class="relative flex items-center">
67
+ <input :id="id" class="absolute inset-0 w-0 h-0 opacity-0" :name="id" type="checkbox" @change="updated"
68
+ :disabled="props.disabled" :checked="localChecked" />
69
+ <IconCheckmarkSmall v-if="localChecked" strokeColor="white" class="absolute" />
70
+ <span :class="checkboxClasses" />
71
+ <slot name="label">
72
+ <span v-if="label"
73
+ :class="['block ml-2 text-16px leading-normal font-light select-none', disabled ? 'text-gray-500' : 'text-gray-800']">
74
+ {{ label }}
75
+ </span>
76
+ </slot>
77
+ </label>
78
+ </template>
@@ -0,0 +1,50 @@
1
+ /// <reference types="cypress" />
2
+
3
+ import { ref } from 'vue'
4
+ import { mount } from 'cypress/vue'
5
+ import Checkbox from './Checkbox.vue'
6
+
7
+ describe('<Checkbox />', () => {
8
+ it('renders', () => {
9
+ mount(() => {
10
+ return (
11
+ <Checkbox
12
+ label="Welcome guide settings"
13
+ id="welcome-opt-out"
14
+ checked
15
+ class="m-2 px-2 py-1 border-1 border-gray-300 rounded"
16
+ />
17
+ )
18
+ })
19
+
20
+ cy.get('input[type="checkbox"]').should('be.checked')
21
+ cy.contains('Welcome guide settings').click()
22
+ cy.get('input[type="checkbox"]').should('not.be.checked')
23
+ })
24
+
25
+ it('renders vModel', () => {
26
+ const isChecked = ref(false)
27
+ mount(() => {
28
+ return (
29
+ <div>
30
+ <Checkbox
31
+ label="Welcome guide settings"
32
+ vModel={isChecked.value}
33
+ class="m-2 px-2 py-1 border-1 border-gray-300 rounded"
34
+ />
35
+ <div
36
+ class="m-2 px-2 py-1 border-1 border-gray-300 rounded"
37
+ data-cy="result"
38
+ >
39
+ isChecked = {isChecked.value.toString()}
40
+ </div>
41
+ </div>
42
+ )
43
+ })
44
+
45
+ cy.get('[data-cy="result"]').should('contain', 'isChecked = false')
46
+ cy.contains('Welcome guide settings').click()
47
+ cy.get('input[type="checkbox"]').should('be.checked')
48
+ cy.get('[data-cy="result"]').should('contain', 'isChecked = true')
49
+ })
50
+ })
@@ -1,26 +1,66 @@
1
1
  declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
- id: string;
3
- modelValue: boolean;
4
- state?: ("default" | "success" | "danger") | undefined;
2
+ /**
3
+ * A unique identifier for the checkbox on the whole page.
4
+ * It will be used to give match label with input for a11y.
5
+ */
6
+ id?: string | undefined;
7
+ /**
8
+ * Is the checkbox checked when it is first rendered.
9
+ */
10
+ checked?: boolean | undefined;
11
+ /**
12
+ * The color of the background in the checkbox.
13
+ * The checkmark will always be white.
14
+ */
15
+ color?: "indigo" | "red" | "jade" | undefined;
16
+ /**
17
+ * If the checkbox is disabled, it will not be clickable.
18
+ */
19
+ disabled?: boolean | undefined;
20
+ modelValue?: boolean | undefined;
21
+ /**
22
+ * Label for the checkbox.
23
+ * It is very important to set this to make the checkbox accessible.
24
+ */
5
25
  label?: string | undefined;
6
26
  }>, {
7
- state: string;
8
- label: undefined;
27
+ id: any;
28
+ color: string;
9
29
  }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
30
  "update:modelValue": (value: boolean) => void;
11
31
  }, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
12
- id: string;
13
- modelValue: boolean;
14
- state?: ("default" | "success" | "danger") | undefined;
32
+ /**
33
+ * A unique identifier for the checkbox on the whole page.
34
+ * It will be used to give match label with input for a11y.
35
+ */
36
+ id?: string | undefined;
37
+ /**
38
+ * Is the checkbox checked when it is first rendered.
39
+ */
40
+ checked?: boolean | undefined;
41
+ /**
42
+ * The color of the background in the checkbox.
43
+ * The checkmark will always be white.
44
+ */
45
+ color?: "indigo" | "red" | "jade" | undefined;
46
+ /**
47
+ * If the checkbox is disabled, it will not be clickable.
48
+ */
49
+ disabled?: boolean | undefined;
50
+ modelValue?: boolean | undefined;
51
+ /**
52
+ * Label for the checkbox.
53
+ * It is very important to set this to make the checkbox accessible.
54
+ */
15
55
  label?: string | undefined;
16
56
  }>, {
17
- state: string;
18
- label: undefined;
57
+ id: any;
58
+ color: string;
19
59
  }>>> & {
20
60
  "onUpdate:modelValue"?: ((value: boolean) => any) | undefined;
21
61
  }, {
22
- state: "default" | "success" | "danger";
23
- label: string;
62
+ id: string;
63
+ color: 'red' | 'indigo' | 'jade';
24
64
  }>;
25
65
  export default _default;
26
66
  declare type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.vue.d.ts","sourceRoot":"","sources":["../Checkbox.vue.ts"],"names":[],"mappings":";QA8BQ,MAAM;gBACE,OAAO;;;;;;;;;QADf,MAAM;gBACE,OAAO;;;;;;;;;;;;AA9BvB,wBAwFK;AACL,aAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,aAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,aAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE5B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QACzD,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,GAAG,CAAC,CAAC,CAAC,CAAC;CACR,CAAC"}
1
+ {"version":3,"file":"Checkbox.vue.d.ts","sourceRoot":"","sources":["../Checkbox.vue.ts"],"names":[],"mappings":";IAsEI;;;OAGG;;IAEH;;OAEG;;IAEH;;;OAGG;;IAEH;;OAEG;;;IAGH;;;OAGG;;;;;;;;IAtBH;;;OAGG;;IAEH;;OAEG;;IAEH;;;OAGG;;IAEH;;OAEG;;;IAGH;;;OAGG;;;;;;;;QAlBE,MAAM;WASH,KAAK,GAAG,QAAQ,GAAG,MAAM;;AA/ErC,wBAwIK;AACL,aAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,aAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,aAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE5B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QACzD,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,GAAG,CAAC,CAAC,CAAC,CAAC;CACR,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/index.es.js CHANGED
@@ -1,47 +1,98 @@
1
- import { defineComponent, openBlock, createElementBlock, createElementVNode, normalizeClass, renderSlot, toDisplayString, createCommentVNode } from "vue";
1
+ import { h, defineComponent, ref, computed, openBlock, createElementBlock, createElementVNode, createBlock, unref, createCommentVNode, normalizeClass, renderSlot, toDisplayString } from "vue";
2
+ import * as iconsRegistry from "@cypress-design/icon-registry";
3
+ const compileVueIconProperties = ({
4
+ body,
5
+ compiledClasses,
6
+ size,
7
+ class: className,
8
+ interactiveColorsOnGroup,
9
+ ...attributes
10
+ }) => {
11
+ Object.keys(attributes).forEach((key) => {
12
+ if (key.toLowerCase().endsWith("color")) {
13
+ delete attributes[key];
14
+ }
15
+ });
16
+ const componentProps = {
17
+ width: size,
18
+ height: size,
19
+ fill: "none",
20
+ innerHTML: body,
21
+ ...attributes
22
+ };
23
+ if (compiledClasses.length) {
24
+ componentProps.class = compiledClasses.join(" ");
25
+ }
26
+ return componentProps;
27
+ };
28
+ const IconCheckmarkSmall = (props) => {
29
+ const { sizeWithDefault: size, compiledClasses } = iconsRegistry.getComponentAttributes({ ...props, availableSizes: ["16"] });
30
+ const iconBodies = {
31
+ "16": '<path d="M5 8.5 7.5 11 11 5" stroke="currentColor" class="icon-dark" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
32
+ };
33
+ const body = iconBodies[size];
34
+ if (!body) {
35
+ throw Error(`Icon "checkmark-small" is not available in size ${size}`);
36
+ }
37
+ return h("svg", compileVueIconProperties({
38
+ ...props,
39
+ size,
40
+ body,
41
+ compiledClasses
42
+ }));
43
+ };
2
44
  const _hoisted_1 = { class: "relative flex items-center" };
3
- const _hoisted_2 = { class: "flex items-center h-5" };
4
- const _hoisted_3 = ["id", "checked", "aria-describedby", "name"];
5
- const _hoisted_4 = { class: "ml-2 text-16px leading-normal" };
6
- const _hoisted_5 = ["for"];
45
+ const _hoisted_2 = ["id", "name", "disabled", "checked"];
7
46
  const _sfc_main = /* @__PURE__ */ defineComponent({
47
+ __name: "Checkbox",
8
48
  props: {
9
- id: null,
49
+ id: { default: crypto.randomUUID() },
50
+ checked: { type: Boolean },
51
+ color: { default: "indigo" },
52
+ disabled: { type: Boolean },
10
53
  modelValue: { type: Boolean },
11
- state: { default: "default" },
12
- label: { default: void 0 }
54
+ label: null
13
55
  },
14
56
  emits: ["update:modelValue"],
15
57
  setup(__props, { emit }) {
16
58
  const props = __props;
59
+ const localChecked = ref(props.modelValue || props.checked);
17
60
  function updated() {
18
- emit("update:modelValue", !props.modelValue);
61
+ localChecked.value = !localChecked.value;
62
+ emit("update:modelValue", localChecked.value);
19
63
  }
64
+ const checkboxClasses = computed(() => [
65
+ "block border-1 rounded h-16px w-16px",
66
+ props.disabled ? "border-gray-200 bg-gray-100" : localChecked.value ? {
67
+ "border-indigo-500 bg-indigo-400": props.color === "indigo",
68
+ "border-jade-500 bg-jade-400": props.color === "jade",
69
+ "border-red-500 bg-red-400": props.color === "red"
70
+ } : "border-gray-200 bg-white"
71
+ ]);
20
72
  return (_ctx, _cache) => {
21
- return openBlock(), createElementBlock("div", _hoisted_1, [
22
- createElementVNode("div", _hoisted_2, [
23
- createElementVNode("input", {
24
- id: __props.id,
25
- checked: __props.modelValue,
26
- "aria-describedby": `${__props.id}-description`,
27
- name: __props.id,
28
- type: "checkbox",
29
- class: normalizeClass(["border-1 rounded border-gray-200 bg-white h-4 w-4 text-indigo-500 disabled:bg-gray-100 checked:bg-indigo-500", {
30
- "text-indigo-500 checked:border-indigo-300 checked:bg-indigo-600 checked:text-indigo-600": __props.state === "default",
31
- "checked:border-jade-300 checked:bg-jade-600 checked:text-jade-600": __props.state === "success",
32
- "checked:border-red-300 checked:bg-red-600 checked:text-red-600": __props.state === "danger"
33
- }]),
34
- onClick: _cache[0] || (_cache[0] = ($event) => updated())
35
- }, null, 10, _hoisted_3)
36
- ]),
37
- createElementVNode("div", _hoisted_4, [
38
- renderSlot(_ctx.$slots, "label", {}, () => [
39
- __props.label ? (openBlock(), createElementBlock("label", {
40
- key: 0,
41
- for: __props.id,
42
- class: "disabled:text-gray-500 text-gray-800 font-light select-none"
43
- }, toDisplayString(__props.label), 9, _hoisted_5)) : createCommentVNode("", true)
44
- ])
73
+ return openBlock(), createElementBlock("label", _hoisted_1, [
74
+ createElementVNode("input", {
75
+ id: __props.id,
76
+ class: "absolute inset-0 w-0 h-0 opacity-0",
77
+ name: __props.id,
78
+ type: "checkbox",
79
+ onChange: updated,
80
+ disabled: props.disabled,
81
+ checked: localChecked.value
82
+ }, null, 40, _hoisted_2),
83
+ localChecked.value ? (openBlock(), createBlock(unref(IconCheckmarkSmall), {
84
+ key: 0,
85
+ strokeColor: "white",
86
+ class: "absolute"
87
+ })) : createCommentVNode("", true),
88
+ createElementVNode("span", {
89
+ class: normalizeClass(unref(checkboxClasses))
90
+ }, null, 2),
91
+ renderSlot(_ctx.$slots, "label", {}, () => [
92
+ __props.label ? (openBlock(), createElementBlock("span", {
93
+ key: 0,
94
+ class: normalizeClass(["block ml-2 text-16px leading-normal font-light select-none", __props.disabled ? "text-gray-500" : "text-gray-800"])
95
+ }, toDisplayString(__props.label), 3)) : createCommentVNode("", true)
45
96
  ])
46
97
  ]);
47
98
  };