@cypress-design/vue-accordion 0.1.0 → 0.1.1

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.
@@ -7,6 +7,7 @@ export default (options: AccordionStoryOptions = {}) => {
7
7
  title = 'Accordion Title',
8
8
  description = 'Vestibulum id ligula porta felis euismod semper. Nulla vitae elit libero, a pharetra augue. Aenean lacinia bibendum nulla.',
9
9
  icon = IconActionQuestionMarkCircle,
10
+ iconEl,
10
11
  separator = true,
11
12
  open = false,
12
13
  fullWidthContent = false,
@@ -24,11 +25,23 @@ export default (options: AccordionStoryOptions = {}) => {
24
25
  fullWidthContent={fullWidthContent}
25
26
  headingClassName={headingClassName}
26
27
  >
27
- <p data-cy="content">
28
- Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio dolore
29
- omnis nemo minus, sapiente magni laudantium eligendi modi deserunt ea
30
- non iure consequatur sed id quidem! Ad.
31
- </p>
28
+ {{
29
+ default: () => (
30
+ <p data-cy="content">
31
+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio
32
+ dolore omnis nemo minus, sapiente magni laudantium eligendi modi
33
+ deserunt ea non iure consequatur sed id quidem! Ad.
34
+ </p>
35
+ ),
36
+ iconEl: iconEl
37
+ ? () => (
38
+ <IconActionQuestionMarkCircle
39
+ strokeColor="red-600"
40
+ fillColor="red-50"
41
+ />
42
+ )
43
+ : null,
44
+ }}
32
45
  </Accordion>
33
46
  </div>
34
47
  )
@@ -6,6 +6,7 @@ import { FIGMA_URL } from '../constants'
6
6
  import Accordion from './Accordion.vue'
7
7
 
8
8
  import AccordionStory from './Accordion.rootstory'
9
+ import { IconActionQuestionMarkCircle } from '@cypress-design/vue-icon'
9
10
 
10
11
  <h1>Accordion<span className="text-lg font-normal"> - v{version}</span></h1>
11
12
 
@@ -101,6 +102,34 @@ import Accordion from '@cypress-design/vue-accordion'
101
102
  </Accordion>
102
103
  ```
103
104
 
105
+ ### Icon slot
106
+
107
+ If you need classes or props for your icon, you can pass it in via the `iconEl` slot instead of the `icon` prop.
108
+
109
+ <Canvas withSource="none">
110
+ <Story name="Icon slot">
111
+ {AccordionStory({iconEl: true})}
112
+ </Story>
113
+ </Canvas>
114
+
115
+ ```html
116
+ <Accordion
117
+ title="Accordion Title"
118
+ description="Vestibulum id ligula porta felis euismod semper. Nulla... "
119
+ separator
120
+ open
121
+ >
122
+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio dolore omnis
123
+ nemo minus, sapiente magni ...
124
+ <template #iconEl>
125
+ <IconActionQuestionMarkCircle
126
+ strokeColor="jade-600"
127
+ fillColor="jade-50"
128
+ />
129
+ </template>
130
+ </Accordion>
131
+ ```
132
+
104
133
  <ArgsTable />
105
134
 
106
135
  <Description>
package/Accordion.vue CHANGED
@@ -1,11 +1,17 @@
1
1
  <template>
2
2
  <details ref="details">
3
3
  <summary
4
- class="flex items-center"
5
4
  :class="[CssClasses.summary, headingClassName ?? CssClasses.summaryColor]"
6
5
  >
7
- <Icon v-if="props.icon" :class="CssClasses.icon" />
8
- <hr v-if="props.icon && separator" :class="CssClasses.separator" />
6
+ <span :class="CssClasses.icon">
7
+ <slot name="iconEl">
8
+ <Icon />
9
+ </slot>
10
+ </span>
11
+ <hr
12
+ v-if="(props.icon || slots.iconEl) && separator"
13
+ :class="CssClasses.separator"
14
+ />
9
15
  <div class="flex-grow pr-16px">
10
16
  <div
11
17
  :class="[
@@ -45,12 +51,20 @@
45
51
  import { CssClasses } from '../constants'
46
52
  import { DetailsAnimation } from '@cypress-design/details-animation'
47
53
  import { IconChevronDownSmall } from '@cypress-design/vue-icon'
48
- import { FunctionalComponent, onMounted, ref, SVGAttributes } from 'vue'
54
+ import {
55
+ FunctionalComponent,
56
+ SVGAttributes,
57
+ onMounted,
58
+ ref,
59
+ useSlots,
60
+ } from 'vue'
61
+
62
+ const slots = useSlots()
49
63
 
50
64
  const props = defineProps<{
51
65
  /**
52
66
  * Main indigo title.
53
- * [NOTE] It's color and font can be customized using `titleClassName`.
67
+ * [NOTE] Its color and font can be customized using `titleClassName`.
54
68
  */
55
69
  title: string
56
70
  /**
@@ -58,7 +72,7 @@ const props = defineProps<{
58
72
  */
59
73
  description?: string
60
74
  /**
61
- * Icon to be displayed on the left of the the heading.
75
+ * Icon to be displayed on the left of the the heading. Overridden by the iconEl slot, if one is provided.
62
76
  */
63
77
  icon?: FunctionalComponent<SVGAttributes>
64
78
  /**
@@ -2,10 +2,53 @@
2
2
  import { mount } from 'cypress/vue'
3
3
  import assertions from '../assertions'
4
4
  import AccordionStory from './Accordion.rootstory'
5
+ import Accordion from './Accordion.vue'
6
+ import { IconActionQuestionMarkCircle } from '@cypress-design/vue-icon'
5
7
 
6
8
  describe('<Accordion/>', () => {
7
9
  function mountStory(options: Parameters<typeof AccordionStory>[0] = {}) {
8
10
  mount(() => <AccordionStory {...options} />)
9
11
  }
10
12
  assertions(mountStory)
13
+
14
+ const slots = {
15
+ default: () => 'Content',
16
+ iconEl: () => (
17
+ <IconActionQuestionMarkCircle
18
+ data-cy="icon-element"
19
+ strokeColor="red-600"
20
+ fillColor="red-50"
21
+ />
22
+ ),
23
+ }
24
+
25
+ it('can be passed an icon as a prop', () => {
26
+ mount(Accordion, {
27
+ props: {
28
+ title: 'hi',
29
+ icon: IconActionQuestionMarkCircle,
30
+ },
31
+ }).get('summary svg')
32
+ })
33
+
34
+ it('can be passed an icon as an element', () => {
35
+ mount(Accordion, {
36
+ slots,
37
+ props: {
38
+ title: 'hi',
39
+ },
40
+ }).get('[data-cy=icon-element]')
41
+ })
42
+
43
+ it('when passed both icon and iconEl, iconEl overrides icon', () => {
44
+ mount(Accordion, {
45
+ icon: IconActionQuestionMarkCircle,
46
+ slots,
47
+ props: {
48
+ title: 'hi',
49
+ },
50
+ }).get('[data-cy=icon-element]')
51
+
52
+ cy.get('summary').find('svg').should('have.length', 2)
53
+ })
11
54
  })
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @cypress-design/vue-accordion
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#133](https://github.com/cypress-io/cypress-design/pull/133) [`73250a9`](https://github.com/cypress-io/cypress-design/commit/73250a9d65a890e4be74009978214f49c64e9fce) Thanks [@elevatebart](https://github.com/elevatebart)! - remove duplicate classes on the summary
8
+
3
9
  ## 0.1.0
4
10
 
5
11
  ### Minor Changes
@@ -15,7 +15,7 @@ export declare const CssClasses: {
15
15
  export interface AccordionProps {
16
16
  /**
17
17
  * Main indigo title.
18
- * > [NOTE] It's color and font can be customized using `titleClassName`.
18
+ * > [NOTE] Its color and font can be customized using `titleClassName`.
19
19
  */
20
20
  title: string;
21
21
  /**
package/dist/index.es.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { h as g, defineComponent as v, ref as h, onMounted as b, openBlock as m, createElementBlock as d, createElementVNode as u, normalizeClass as s, unref as t, createBlock as N, createCommentVNode as y, toDisplayString as k, createVNode as w, renderSlot as x } from "vue";
1
+ import { h as g, defineComponent as b, useSlots as N, ref as h, onMounted as w, openBlock as p, createElementBlock as y, createElementVNode as m, normalizeClass as r, unref as o, renderSlot as C, createVNode as x, createCommentVNode as k, toDisplayString as v } from "vue";
2
2
  import { DetailsAnimation as D } from "@cypress-design/details-animation";
3
3
  import * as z from "@cypress-design/icon-registry";
4
- import { ICON_COLOR_PROP_NAMES as O } from "@cypress-design/icon-registry";
5
- const o = {
4
+ import { ICON_COLOR_PROP_NAMES as E } from "@cypress-design/icon-registry";
5
+ const t = {
6
6
  details: "",
7
- summary: "details-none min-h-65px py-12px card open:rounded-b-none px-24px flex items-center",
7
+ summary: "details-none min-h-65px py-12px card open:rounded-b-none px-24px flex flex-row items-center",
8
8
  summaryColor: "bg-white",
9
9
  summaryTitle: "text-18px leading-28px font-medium",
10
10
  summaryTitleColor: "text-indigo-500",
@@ -15,36 +15,37 @@ const o = {
15
15
  chevron: "flex-shrink-0 transition transform rotate-0 open:rotate-180",
16
16
  contentWrapper: "border border-gray-100 rounded-b-md border-t-0",
17
17
  content: "px-24px py-16px"
18
- }, B = ({
18
+ }, O = ({
19
19
  body: e,
20
20
  compiledClasses: n,
21
- size: r,
21
+ size: s,
22
22
  class: l,
23
- interactiveColorsOnGroup: f,
24
- ...a
23
+ interactiveColorsOnGroup: d,
24
+ ...u
25
25
  }) => {
26
- const C = Object.keys(a).reduce((c, p) => (O.includes(p) || (c[p] = a[p]), c), {}), i = {
27
- width: r,
28
- height: r,
26
+ const i = Object.keys(u).reduce((c, a) => (E.includes(a) || (c[a] = u[a]), c), {}), f = {
27
+ width: s,
28
+ height: s,
29
+ viewBox: `0 0 ${s} ${s}`,
29
30
  fill: "none",
30
31
  innerHTML: e,
31
- ...C
32
+ ...i
32
33
  };
33
- return n.length && (i.class = n.join(" ")), i;
34
- }, T = (e) => {
35
- const { sizeWithDefault: n, compiledClasses: r } = z.getComponentAttributes({ ...e, availableSizes: ["8", "16"] }), l = {
34
+ return n.length && (f.class = n.join(" ")), f;
35
+ }, $ = (e) => {
36
+ const { sizeWithDefault: n, compiledClasses: s } = z.getComponentAttributes({ ...e, availableSizes: ["8", "16"] }), l = {
36
37
  8: '<path d="m1 2.5 3 3 3-3" stroke="currentColor" class="icon-dark" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>',
37
38
  16: '<path d="m4 6 4 4 4-4" stroke="currentColor" class="icon-dark" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
38
39
  }[n];
39
40
  if (!l)
40
41
  throw Error(`Icon "chevron-down-small" is not available in size ${n}`);
41
- return g("svg", B({
42
+ return g("svg", O({
42
43
  ...e,
43
44
  size: n,
44
45
  body: l,
45
- compiledClasses: r
46
+ compiledClasses: s
46
47
  }));
47
- }, W = { class: "flex-grow pr-16px" }, S = /* @__PURE__ */ v({
48
+ }, B = { class: "flex-grow pr-16px" }, j = /* @__PURE__ */ b({
48
49
  __name: "Accordion",
49
50
  props: {
50
51
  title: null,
@@ -57,58 +58,61 @@ const o = {
57
58
  fullWidthContent: { type: Boolean }
58
59
  },
59
60
  setup(e) {
60
- const n = e, r = h(null), l = h(null);
61
- b(function() {
62
- l.value && r.value && new D(l.value, r.value);
61
+ const n = e, s = N(), l = h(null), d = h(null);
62
+ w(function() {
63
+ d.value && l.value && new D(d.value, l.value);
63
64
  });
64
- const f = n.icon;
65
- return (a, C) => {
66
- var i, c;
67
- return m(), d("details", {
65
+ const u = n.icon;
66
+ return (i, f) => {
67
+ var c, a;
68
+ return p(), y("details", {
68
69
  ref_key: "details",
69
- ref: l
70
+ ref: d
70
71
  }, [
71
- u("summary", {
72
- class: s(["flex items-center", [t(o).summary, (i = e.headingClassName) != null ? i : t(o).summaryColor]])
72
+ m("summary", {
73
+ class: r([o(t).summary, (c = e.headingClassName) != null ? c : o(t).summaryColor])
73
74
  }, [
74
- n.icon ? (m(), N(t(f), {
75
+ m("span", {
76
+ class: r(o(t).icon)
77
+ }, [
78
+ C(i.$slots, "iconEl", {}, () => [
79
+ x(o(u))
80
+ ])
81
+ ], 2),
82
+ (n.icon || o(s).iconEl) && e.separator ? (p(), y("hr", {
75
83
  key: 0,
76
- class: s(t(o).icon)
77
- }, null, 8, ["class"])) : y("", !0),
78
- n.icon && e.separator ? (m(), d("hr", {
79
- key: 1,
80
- class: s(t(o).separator)
81
- }, null, 2)) : y("", !0),
82
- u("div", W, [
83
- u("div", {
84
- class: s([
85
- e.titleClassName ? e.titleClassName : t(o).summaryTitleColor,
86
- t(o).summaryTitle
84
+ class: r(o(t).separator)
85
+ }, null, 2)) : k("", !0),
86
+ m("div", B, [
87
+ m("div", {
88
+ class: r([
89
+ e.titleClassName ? e.titleClassName : o(t).summaryTitleColor,
90
+ o(t).summaryTitle
87
91
  ])
88
- }, k(e.title), 3),
89
- e.description ? (m(), d("div", {
92
+ }, v(e.title), 3),
93
+ e.description ? (p(), y("div", {
90
94
  key: 0,
91
- class: s([
92
- t(o).summaryDescription,
93
- (c = e.descriptionClassName) != null ? c : t(o).summaryDescriptionColor
95
+ class: r([
96
+ o(t).summaryDescription,
97
+ (a = e.descriptionClassName) != null ? a : o(t).summaryDescriptionColor
94
98
  ])
95
- }, k(e.description), 3)) : y("", !0)
99
+ }, v(e.description), 3)) : k("", !0)
96
100
  ]),
97
- w(t(T), {
101
+ x(o($), {
98
102
  strokeColor: "gray-300",
99
- class: s(["open:icon-dark-gray-500", t(o).chevron])
103
+ class: r(["open:icon-dark-gray-500", o(t).chevron])
100
104
  }, null, 8, ["class"])
101
105
  ], 2),
102
- u("div", {
106
+ m("div", {
103
107
  ref_key: "content",
104
- ref: r,
105
- class: s(t(o).contentWrapper)
108
+ ref: l,
109
+ class: r(o(t).contentWrapper)
106
110
  }, [
107
- e.fullWidthContent ? x(a.$slots, "default", { key: 0 }) : (m(), d("div", {
111
+ e.fullWidthContent ? C(i.$slots, "default", { key: 0 }) : (p(), y("div", {
108
112
  key: 1,
109
- class: s(t(o).content)
113
+ class: r(o(t).content)
110
114
  }, [
111
- x(a.$slots, "default")
115
+ C(i.$slots, "default")
112
116
  ], 2))
113
117
  ], 2)
114
118
  ], 512);
@@ -116,8 +120,8 @@ const o = {
116
120
  }
117
121
  });
118
122
  export {
119
- S as default
123
+ j as default
120
124
  };
121
125
 
122
- /* <windicss-keep class="flex items-center flex-grow pr-16px open:icon-dark-gray-500 icon-dark-gray-300 details-none min-h-65px py-12px card open:rounded-b-none px-24px bg-white text-18px leading-28px font-medium text-indigo-500 text-14px leading-20px font-normal text-gray-700 mr-24px flex-shrink-0 w-1px h-40px bg-gray-100 mr-16px transition transform rotate-0 open:rotate-180 border border-gray-100 rounded-b-md border-t-0 py-16px"> */
126
+ /* <windicss-keep class="flex-grow pr-16px open:icon-dark-gray-500 icon-dark-gray-300 details-none min-h-65px py-12px card open:rounded-b-none px-24px flex flex-row items-center bg-white text-18px leading-28px font-medium text-indigo-500 text-14px leading-20px font-normal text-gray-700 mr-24px flex-shrink-0 w-1px h-40px bg-gray-100 mr-16px transition transform rotate-0 open:rotate-180 border border-gray-100 rounded-b-md border-t-0 py-16px"> */
123
127
  //# sourceMappingURL=index.es.mjs.map