Skip to content

Commit ff8e9e0

Browse files
committed
Refactor StudioDetailsPanel and StudioDetailsRow components; improve formatting and style consistency
1 parent 96b7ac1 commit ff8e9e0

File tree

2 files changed

+142
-6
lines changed

2 files changed

+142
-6
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<template>
2+
3+
<div
4+
class="studio-chip"
5+
:class="{ 'has-close-button': close }"
6+
:style="chipStyles"
7+
>
8+
<div class="content">
9+
<div class="text">
10+
<slot>
11+
{{ text }}
12+
</slot>
13+
</div>
14+
15+
<button
16+
v-if="close"
17+
class="close-button"
18+
:class="closeButtonClass"
19+
:aria-label="removeLabel"
20+
type="button"
21+
data-test="remove-chip"
22+
@click.stop="handleClose"
23+
>
24+
<HoverIcon
25+
outlineIcon="delete"
26+
filledIcon="delete"
27+
:outlineColor="$themePalette.grey.v_400"
28+
:filledColor="$themePalette.grey.v_900"
29+
class="close-icon"
30+
/>
31+
</button>
32+
</div>
33+
</div>
34+
35+
</template>
36+
37+
38+
<script>
39+
40+
import HoverIcon from './HoverIcon.vue';
41+
42+
export default {
43+
name: 'StudioChip',
44+
components: {
45+
HoverIcon,
46+
},
47+
props: {
48+
text: {
49+
type: String,
50+
default: '',
51+
},
52+
close: {
53+
type: Boolean,
54+
default: false,
55+
},
56+
},
57+
computed: {
58+
chipStyles() {
59+
const baseColor = this.$themePalette.grey.v_200;
60+
return {
61+
backgroundColor: baseColor,
62+
};
63+
},
64+
removeLabel() {
65+
return `Remove ${this.text}`;
66+
},
67+
closeButtonClass() {
68+
return this.$computedClass({
69+
':focus': {
70+
...this.$coreOutline,
71+
outlineOffset: 0,
72+
},
73+
});
74+
},
75+
},
76+
methods: {
77+
handleClose() {
78+
this.$emit('close');
79+
},
80+
},
81+
};
82+
83+
</script>
84+
85+
86+
<style lang="scss" scoped>
87+
88+
.studio-chip {
89+
display: inline-flex;
90+
align-items: center;
91+
height: 26px;
92+
min-height: 26px;
93+
padding: 2px 12px;
94+
margin: 5px;
95+
font-size: 13px;
96+
white-space: nowrap;
97+
user-select: none;
98+
border-radius: 12px;
99+
transition: all 0.2s ease;
100+
}
101+
102+
.content {
103+
display: flex;
104+
gap: 4px;
105+
align-items: center;
106+
justify-content: center;
107+
height: 100%;
108+
}
109+
110+
.text {
111+
display: flex;
112+
align-items: center;
113+
}
114+
115+
.close-button {
116+
display: flex;
117+
align-items: center;
118+
justify-content: center;
119+
cursor: pointer;
120+
border-radius: 50%;
121+
}
122+
123+
.studio-chip.has-close-button {
124+
padding: 3px 6px 2px 12px;
125+
}
126+
127+
.close-icon {
128+
width: 24px;
129+
height: 24px;
130+
font-size: 18px;
131+
}
132+
133+
</style>

contentcuration/contentcuration/frontend/shared/views/__tests__/StudioDetailsPanel.spec.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,19 @@ describe('StudioDetailsPanel', () => {
153153
// When levels array is populated, the levelsHeading row should be rendered
154154
expect(wrapper.container).toHaveTextContent('levelsHeading');
155155
// Levels are rendered through the component, verify the section exists
156-
const levelRows = Array.from(wrapper.container.querySelectorAll('*'))
157-
.filter(el => el.textContent?.includes('levelsHeading'));
156+
const levelRows = Array.from(wrapper.container.querySelectorAll('*')).filter(el =>
157+
el.textContent?.includes('levelsHeading'),
158+
);
158159
expect(levelRows.length).toBeGreaterThan(0);
159160
});
160161

161162
it('should render categories when present', () => {
162163
// When categories array is populated, the categoriesHeading row should be rendered
163164
expect(wrapper.container).toHaveTextContent('categoriesHeading');
164165
// Categories are rendered through the component, verify the section exists
165-
const categoryRows = Array.from(wrapper.container.querySelectorAll('*'))
166-
.filter(el => el.textContent?.includes('categoriesHeading'));
166+
const categoryRows = Array.from(wrapper.container.querySelectorAll('*')).filter(el =>
167+
el.textContent?.includes('categoriesHeading'),
168+
);
167169
expect(categoryRows.length).toBeGreaterThan(0);
168170
});
169171

@@ -256,8 +258,9 @@ describe('StudioDetailsPanel', () => {
256258
it('should not show primary language when not set', () => {
257259
// Language row should not appear if language is not set
258260
const container = wrapper.container;
259-
const languageRows = Array.from(container.querySelectorAll('*'))
260-
.filter(el => el.textContent?.includes('primaryLanguageHeading'));
261+
const languageRows = Array.from(container.querySelectorAll('*')).filter(el =>
262+
el.textContent?.includes('primaryLanguageHeading'),
263+
);
261264
expect(languageRows.length).toBe(0);
262265
});
263266

0 commit comments

Comments
 (0)