Skip to content

Commit 454ade2

Browse files
Prevent entity data from overflowing hover card (#1115)
Closes getodk/central#854.
1 parent 6ba4ef1 commit 454ade2

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/components/dl-data.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ defineProps({
4343
.dl-data-dt { @include text-overflow-ellipsis; }
4444
4545
.dl-data-dd {
46+
// This is needed for the line-clamp mixin to work if the component is used in
47+
// .dl-horizontal. See: https://github.com/getodk/central/issues/854
48+
overflow: hidden;
49+
4650
div {
4751
@include line-clamp(3);
4852
overflow-wrap: break-word;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import DlData from '../../../src/components/dl-data.vue';
2+
import HoverCardEntity from '../../../src/components/hover-card/entity.vue';
3+
4+
import useHoverCardResources from '../../../src/request-data/hover-card';
5+
6+
import { truncatesText } from '../../../src/util/dom';
7+
8+
import testData from '../../data';
9+
import { mergeMountOptions, mount } from '../../util/lifecycle';
10+
import { testRequestData } from '../../util/request-data';
11+
12+
const mountComponent = (options = undefined) =>
13+
mount(HoverCardEntity, mergeMountOptions(options, {
14+
container: {
15+
requestData: testRequestData([useHoverCardResources], {
16+
dataset: testData.extendedDatasets.last(),
17+
entity: testData.standardEntities.last()
18+
})
19+
}
20+
}));
21+
22+
describe('HoverCardEntity', () => {
23+
describe('entity property data', () => {
24+
it('shows the first 5 properties', () => {
25+
testData.extendedEntities.createPast(1, {
26+
data: { p1: 'a', p2: 'b', p3: 'c', p4: 'd', p5: 'e', p6: 'f' }
27+
});
28+
const props = mountComponent().findAllComponents(DlData)
29+
.map(wrapper => wrapper.props());
30+
props.should.eql([
31+
{ name: 'p1', value: 'a' },
32+
{ name: 'p2', value: 'b' },
33+
{ name: 'p3', value: 'c' },
34+
{ name: 'p4', value: 'd' },
35+
{ name: 'p5', value: 'e' }
36+
]);
37+
});
38+
39+
it('renders correctly if there are fewer than 5 properties', () => {
40+
testData.extendedEntities.createPast(1, {
41+
data: { p1: 'a', p2: 'b' }
42+
});
43+
const props = mountComponent().findAllComponents(DlData)
44+
.map(wrapper => wrapper.props());
45+
props.should.eql([
46+
{ name: 'p1', value: 'a' },
47+
{ name: 'p2', value: 'b' }
48+
]);
49+
});
50+
51+
it('truncates a long property name', () => {
52+
testData.extendedEntities.createPast(1, {
53+
data: { ['x'.repeat(1000)]: 'y' }
54+
});
55+
const component = mountComponent({ attachTo: document.body });
56+
const body = component.get('.hover-card-body');
57+
body.element.clientWidth.should.equal(288);
58+
const dt = body.get('.dl-data-dt');
59+
// The <dt> should get no more than 50% of the width of .hover-card-body.
60+
dt.element.clientWidth.should.equal(144);
61+
// It's not possible to mouse over a hover card in order to view a
62+
// tooltip, so this is the best way to assert text truncation.
63+
truncatesText(dt.element).should.be.true;
64+
body.get('.dl-data-dd').element.clientWidth.should.equal(144);
65+
});
66+
67+
it('truncates a long property value', () => {
68+
testData.extendedEntities.createPast(1, {
69+
data: { x: 'y'.repeat(1000) }
70+
});
71+
const component = mountComponent({ attachTo: document.body });
72+
const body = component.get('.hover-card-body');
73+
body.element.clientWidth.should.equal(288);
74+
const dd = body.get('.dl-data-dd');
75+
// More than 50% of the width of .hover-card-body, but well short of 100%
76+
dd.element.clientWidth.should.be.within(180, 250);
77+
truncatesText(dd.get('div').element).should.be.true;
78+
});
79+
});
80+
});

0 commit comments

Comments
 (0)