Skip to content

Commit 307b3ae

Browse files
committed
feat(layout): add text utility
1 parent 366fd85 commit 307b3ae

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

src/Box.tsx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,27 @@ type Alignment = typeof alignmentValues[number];
9191
const sizingValues = ['25', '50', '75', '100', 'auto'] as const;
9292
type Sizing = typeof sizingValues[number];
9393

94+
const textTransformValues = ['lowercase', 'uppercase', 'capitalize'] as const;
95+
type TextTransform = typeof textTransformValues[number];
96+
97+
const fontWeightValues = [
98+
'bold',
99+
'bolder',
100+
'normal',
101+
'light',
102+
'lighter',
103+
] as const;
104+
type FontWeight = typeof fontWeightValues[number];
105+
106+
const fontStyleValues = ['italic', 'normal'] as const;
107+
type FontStyle = typeof fontStyleValues[number];
108+
109+
const lineHeightValues = ['1', 'sm', 'base', 'lg'] as const;
110+
type LineHeight = typeof lineHeightValues[number];
111+
112+
const textDecorationValues = ['underline', 'line-through', 'none'] as const;
113+
type TextDecoration = typeof textDecorationValues[number];
114+
94115
const generateBreakpoint = (
95116
bsPrefix: string,
96117
currentBreakpoint: string | true,
@@ -278,6 +299,45 @@ const utilities: Record<string, (utilityValue: any) => string> = {
278299
minViewportHeight() {
279300
return `min-vh-100`;
280301
},
302+
textLeft(breakpoint: Breakpoint) {
303+
return generateBreakpoint('text', breakpoint, 'left');
304+
},
305+
textCenter(breakpoint: Breakpoint) {
306+
return generateBreakpoint('text', breakpoint, 'center');
307+
},
308+
textRight(breakpoint: Breakpoint) {
309+
return generateBreakpoint('text', breakpoint, 'right');
310+
},
311+
textWrap() {
312+
return `text-wrap`;
313+
},
314+
textNoWrap() {
315+
return `text-nowrap`;
316+
},
317+
textBreak() {
318+
return `text-break`;
319+
},
320+
textTransform(transform: TextTransform) {
321+
return `text-${transform}`;
322+
},
323+
fontWeight(weight: FontWeight) {
324+
return `font-weight-${weight}`;
325+
},
326+
fontStyle(style: FontStyle) {
327+
return `font-${style}`;
328+
},
329+
lineHeight(height: LineHeight) {
330+
return `lh-${height}`;
331+
},
332+
fontMonospace() {
333+
return `font-monospace`;
334+
},
335+
textReset() {
336+
return `text-reset`;
337+
},
338+
textDecoration(decoration: TextDecoration) {
339+
return `text-decoration-${decoration}`;
340+
},
281341
};
282342

283343
const propTypes = {
@@ -375,6 +435,20 @@ const propTypes = {
375435
minViewportWidth: PropTypes.bool,
376436
minViewportHeight: PropTypes.bool,
377437

438+
textLeft: PropTypes.oneOf(breakpointValues),
439+
textCenter: PropTypes.oneOf(breakpointValues),
440+
textRight: PropTypes.oneOf(breakpointValues),
441+
textWrap: PropTypes.bool,
442+
textNoWrap: PropTypes.bool,
443+
textBreak: PropTypes.bool,
444+
textTransform: PropTypes.oneOf(textTransformValues),
445+
fontWeight: PropTypes.oneOf(fontWeightValues),
446+
fontStyle: PropTypes.oneOf(fontStyleValues),
447+
lineHeight: PropTypes.oneOf(lineHeightValues),
448+
fontMonospace: PropTypes.bool,
449+
textReset: PropTypes.bool,
450+
textDecoration: PropTypes.oneOf(textDecorationValues),
451+
378452
/**
379453
*
380454
* add `d-print-{display}` className on the element
@@ -481,6 +555,20 @@ export type BoxProps = AsProp &
481555
minViewportWidth: boolean;
482556
minViewportHeight: boolean;
483557

558+
textLeft: Breakpoint;
559+
textCenter: Breakpoint;
560+
textRight: Breakpoint;
561+
textWrap: boolean;
562+
textNoWrap: boolean;
563+
textBreak: boolean;
564+
textTransform: TextTransform;
565+
fontWeight: FontWeight;
566+
fontStyle: FontStyle;
567+
lineHeight: LineHeight;
568+
fontMonospace: boolean;
569+
textReset: boolean;
570+
textDecoration: TextDecoration;
571+
484572
className: string;
485573
print: Display;
486574
visible: boolean;
@@ -560,6 +648,19 @@ const Box = (React.forwardRef(
560648
viewportHeight,
561649
minViewportWidth,
562650
minViewportHeight,
651+
textLeft,
652+
textCenter,
653+
textRight,
654+
textWrap,
655+
textNoWrap,
656+
textBreak,
657+
textTransform,
658+
fontWeight,
659+
fontStyle,
660+
lineHeight,
661+
fontMonospace,
662+
textReset,
663+
textDecoration,
563664
pe,
564665
print,
565666
visible,
@@ -638,6 +739,19 @@ const Box = (React.forwardRef(
638739
viewportHeight,
639740
minViewportWidth,
640741
minViewportHeight,
742+
textLeft,
743+
textCenter,
744+
textRight,
745+
textWrap,
746+
textNoWrap,
747+
textBreak,
748+
textTransform,
749+
fontWeight,
750+
fontStyle,
751+
lineHeight,
752+
fontMonospace,
753+
textReset,
754+
textDecoration,
641755
};
642756
const finalClassName = classNames(
643757
...Object.entries(utilityProps)

test/BoxSpec.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,47 @@ describe('<Box>', () => {
155155
component.find('div').hasClass('min-vw-100').should.equal(true);
156156
component.find('div').hasClass('h-50').should.equal(true);
157157
});
158+
it('Should have text align utilities', () => {
159+
const component = shallow(<Box textLeft="xl" textCenter="sm" textRight />);
160+
component.find('div').hasClass('text-xl-left').should.equal(true);
161+
component.find('div').hasClass('text-sm-center').should.equal(true);
162+
component.find('div').hasClass('text-right').should.equal(true);
163+
});
164+
it('Should have text wrap utilities', () => {
165+
const component = shallow(<Box textWrap textNoWrap />);
166+
component.find('div').hasClass('text-wrap').should.equal(true);
167+
component.find('div').hasClass('text-nowrap').should.equal(true);
168+
});
169+
it('Should have text break utility', () => {
170+
const component = shallow(<Box textBreak />);
171+
component.find('div').hasClass('text-break').should.equal(true);
172+
});
173+
it('Should have text transform utilities', () => {
174+
const component = shallow(<Box textTransform="uppercase" />);
175+
component.find('div').hasClass('text-uppercase').should.equal(true);
176+
});
177+
it('Should have font weight utilities', () => {
178+
const component = shallow(<Box fontWeight="lighter" />);
179+
component.find('div').hasClass('font-weight-lighter').should.equal(true);
180+
});
181+
it('Should have font style utilities', () => {
182+
const component = shallow(<Box fontStyle="italic" />);
183+
component.find('div').hasClass('font-italic').should.equal(true);
184+
});
185+
it('Should have line height utilities', () => {
186+
const component = shallow(<Box lineHeight="base" />);
187+
component.find('div').hasClass('lh-base').should.equal(true);
188+
});
189+
it('Should have monospace utility', () => {
190+
const component = shallow(<Box fontMonospace />);
191+
component.find('div').hasClass('font-monospace').should.equal(true);
192+
});
193+
it('Should have text reset utility', () => {
194+
const component = shallow(<Box textReset />);
195+
component.find('div').hasClass('text-reset').should.equal(true);
196+
});
197+
it('Should have text decoration utilities', () => {
198+
const component = shallow(<Box textDecoration="none" />);
199+
component.find('div').hasClass('text-decoration-none').should.equal(true);
200+
});
158201
});

0 commit comments

Comments
 (0)