Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ocx-content-container - improve padding + allow specifying breakpoint #63

Merged
merged 2 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div ocxContentContainer [layout]="layout">
<div ocxContentContainer [layout]="layout" [breakpoint]="breakpoint">
<ng-content></ng-content>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { Component } from '@angular/core'
// Using this mock host allows us to simulate Angular @Input mechanisms
@Component({
template: `
<ocx-content-container [layout]="layout"></ocx-content-container>
<ocx-content-container [layout]="layout" [breakpoint]="breakpoint"></ocx-content-container>
`,
})
class TestHostComponent {
layout: 'horizontal' | 'vertical' = 'horizontal';
breakpoint: 'sm' | 'md' | 'lg' | 'xl' = 'md'
}

describe('OcxContentContainerComponent', () => {
Expand All @@ -35,13 +36,35 @@ describe('OcxContentContainerComponent', () => {
it('should render a horizontal layout container with all expected css classes', () => {
// Check that layout is horizontal by default
expect(component.layout).toEqual('horizontal')
// Check that breakpoint is md by default
expect(component.breakpoint).toEqual('md')
fixture.detectChanges()

// Check that the classList of the rendered element contains all expected classes
const expectedClasses = ['flex', 'p-3', 'gap-3', 'flex-column', 'sm:flex-row']
const expectedClasses = ['flex', 'py-3', 'gap-3', 'flex-column', 'md:flex-row']
expect(Object.keys(fixture.debugElement.children[0].classes)).toEqual(expectedClasses)
})

it('should render a horizontal layout container with all expected css classes and a specified breakpoint', () => {
// Check that layout is horizontal by default
expect(component.layout).toEqual('horizontal')
// Check that breakpoint is md by default
expect(component.breakpoint).toEqual('md')
fixture.detectChanges()

// Check that the classList of the rendered element contains all expected classes
const expectedClassesMD = ['flex', 'py-3', 'gap-3', 'flex-column', 'md:flex-row']
expect(Object.keys(fixture.debugElement.children[0].classes)).toEqual(expectedClassesMD)

component.breakpoint = "lg"
fixture.detectChanges()

// Check that breakpoint is now lg and that classes have been updated accordingly
expect(component.breakpoint).toEqual('lg')
const expectedClassesLG = ['flex', 'py-3', 'gap-3', 'flex-column', 'lg:flex-row']
expect(Object.keys(fixture.debugElement.children[0].classes)).toEqual(expectedClassesLG)
})

it('should render a vertical layout container with all expected css classes', () => {
// Replace default component with custom host component to simulate input behavior
fixture = TestBed.createComponent(TestHostComponent)
Expand All @@ -59,7 +82,7 @@ describe('OcxContentContainerComponent', () => {
expect(component.layout).toEqual('vertical')

// Check that the classList of the rendered element contains all expected classes
const expectedClasses = ["flex", "p-3", "gap-3", "flex-column"]
const expectedClasses = ["flex", "py-3", "gap-3", "flex-column"]
expect(Object.keys(fixture.debugElement.children[0].children[0].classes)).toEqual(expectedClasses)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export default {
options: ['horizontal', 'vertical'],
control: { type: 'select' },
},
breakpoint: {
options: ['sm', 'md', 'lg', 'xl'],
control: { type: 'select' },
}
},
decorators: [
moduleMetadata({
Expand All @@ -26,14 +30,15 @@ export const Basic = {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<ocx-content-container layout="${args.layout}" breakpoint="${args.breakpoint}">
<p>Content 1 nested in ocx-content-container</p>
<p>Content 2 nested in ocx-content-container</p>
</ocx-content-container>
`,
}),
args: {
layout: 'horizontal',
breakpoint: 'md'
},
}

Expand All @@ -43,7 +48,7 @@ export const WithNestedOCXContent = {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<ocx-content-container layout="${args.layout}" breakpoint="${args.breakpoint}">
<ocx-content class="w-full sm:w-8">
<p>Content inside of ocx-content without title</p>
</ocx-content>
Expand All @@ -55,6 +60,7 @@ export const WithNestedOCXContent = {
}),
args: {
layout: 'horizontal',
breakpoint: 'md'
},
}

Expand All @@ -64,7 +70,7 @@ export const WithNestedOCXContentContainer = {
...args,
},
template: `
<ocx-content-container layout="${args.layout}">
<ocx-content-container layout="${args.layout}" breakpoint="${args.breakpoint}">
<ocx-content-container>
<p>Horizontal content in nested ocx-content-container 1</p>
<p>Horizontal content in nested ocx-content-container 1</p>
Expand All @@ -78,6 +84,7 @@ export const WithNestedOCXContentContainer = {
}),
args: {
layout: 'horizontal',
breakpoint: 'md'
},
}

Expand All @@ -87,13 +94,14 @@ export const DirectiveOnly = {
...args,
},
template: `
<div ocxContentContainer layout="${args.layout}">
<div ocxContentContainer layout="${args.layout}" breakpoint="${args.breakpoint}">
<p>Content 1 nested inside of a div with the ocxContentContainer directive applied to it.</p>
<p>Content 2 nested inside of a div with the ocxContentContainer directive applied to it.</p>
</div>
`,
}),
args: {
layout: 'horizontal',
breakpoint: 'md'
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ export class OcxContentContainerComponent {
* Allows specifying the layout direction of the container
*/
@Input() layout: 'vertical' | 'horizontal' = 'horizontal';

/**
* Allows specifying the breakpoint below which a horizontal layout switches to a vertical layout.
* Only necessary if horizontal layout is used
* Default: md
*/
@Input() breakpoint: 'sm' | 'md' | 'lg' | 'xl' = 'md'
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ export class OcxContentContainerDirective implements OnInit, OnChanges {
*/
@Input() layout: 'horizontal' | 'vertical' = 'horizontal'

/**
* Used for passing in the breakpoint below which a horizontal layout should switch to a vertical layout.
* Only necessary if horizontal layout is used
* Default: md
*/
@Input() breakpoint: 'sm' | 'md' | 'lg' | 'xl' = 'md'

constructor(private el: ElementRef) {}

ngOnInit() {
Expand All @@ -23,11 +30,24 @@ export class OcxContentContainerDirective implements OnInit, OnChanges {
private addContainerStyles() {
const addClasses = (classes: string[]) => this.el.nativeElement.classList.add(...classes)
const removeClasses = (classes: string[]) => this.el.nativeElement.classList.remove(...classes)
const sharedClasses = ['flex', 'p-3', 'gap-3', 'flex-column']
removeClasses(['sm:flex-row'])
// We need to ensure that all breakpoint dependent flex-row classes are removed from the element
// This way we can avoid multiple contradictory layout classes and unexpected effects
const removeResponsiveLayoutClasses = () => {
const classesToRemove: string[] = []
const regexPattern = /\w+:flex-row$/
this.el.nativeElement.classList.forEach((className: string) => {
if (regexPattern.test(className)) {
classesToRemove.push(className)
}
})
removeClasses(classesToRemove)
}
const sharedClasses = ['flex', 'py-3', 'gap-3', 'flex-column']
removeResponsiveLayoutClasses()
addClasses(sharedClasses)
if (this.layout != 'vertical') {
addClasses(['sm:flex-row'])
const responsiveLayoutClass = `${this.breakpoint || 'md'}:flex-row`
addClasses([responsiveLayoutClass])
}
}
}