diff --git a/src/parser/parser.test.ts b/src/parser/parser.test.ts
index 7b76039..ca02078 100644
--- a/src/parser/parser.test.ts
+++ b/src/parser/parser.test.ts
@@ -205,6 +205,12 @@ describe('Parser', () => {
expect(template).toEqual(`
${num}
`);
});
+ it('renders 0 for { value: 0 } expressions', () => {
+ const expr = { value: 0 };
+ const template = rml`${expr}
`;
+ expect(template).toEqual('0
');
+ });
+
it('handles -0 as "0"', () => {
// Don't ask why, it's a JavaScript quirk
const num = -0;
@@ -558,29 +564,36 @@ describe('Parser', () => {
describe('Any sink', () => {
describe('When a BehaviorSubject (.value) is passed', () => {
-
describe('When an implicit sink is used', () => {
-
it('sets the value inline', () => {
const bs = new BehaviorSubject(123)
const template = rml`${bs}
`;
-
expect(template).toMatch(/123<\/div>/);
});
-
});
-
describe('When an explicit sink is used', () => {
-
it('sets the value inline', () => {
const bs = new BehaviorSubject(123)
const template = rml`${InnerText(bs)}
`;
-
expect(template).toMatch(/123<\/div>/);
});
+ });
+ describe('Content', () => {
+ it('renders 0 when an object has a .value of 0', () => {
+ const zeroValueObject = { value: 0 };
+ const template = rml`${zeroValueObject}
`;
+ expect(template).toEqual('0
');
+ });
});
+ describe('Attributes', () => {
+ it('renders 0 in an attribute when an object has a .value of 0', () => {
+ const zeroValueObject = { value: 0 };
+ const template = rml``;
+ expect(template).toEqual(``);
+ });
+ });
});
});
diff --git a/src/parser/parser.ts b/src/parser/parser.ts
index d6b33af..05e7bb7 100644
--- a/src/parser/parser.ts
+++ b/src/parser/parser.ts
@@ -68,14 +68,20 @@ const getEventName = (eventAttributeString: RMLEventAttributeName): [RMLEventNam
*
* `;
* };
- * ```
- *
- * ## Example
- *
- * ```ts
- * import { rml } from 'rimmel';
- *
- * const Component = () => {
+ if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
+ acc = accPlusString +(expression ?? '');
+ } else if (
+ expression && typeof expression === 'object' &&
+ 'value' in expression &&
+ (typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
+ ) {
+ // Render the value property of objects, including 0
+ acc = accPlusString + (expression.value ?? '');
+ } else {
+ //other existing logic for different expression types
+ }
+ }
+
* const data = fetch('/api').then(res => res.text());
*
* return rml`
@@ -127,8 +133,13 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
const printableExpressionType = typeof (expression ?? '');
if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
- // Static expressions, no data binding. Just concatenate and move on
acc = accPlusString +(expression ?? '');
+ } else if (
+ expression && typeof expression === 'object' &&
+ 'value' in expression &&
+ (typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
+ ) {
+ acc = accPlusString + (expression.value ?? '');
} else if(eventName) {
// Event Source
// so feed it to an Rx Subject | Observer | Handler Function | POJO | Array
@@ -268,7 +279,7 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
addRef(ref, isSinkBindingConfiguration(_source) ? _source : InnerHTML(_source));
acc = acc
+(existingRef ? string : string.replace(/\s*>\s*$/, ` ${RESOLVE_ATTRIBUTE}="${ref}">`))
- +(initialValue || '')
+ +(initialValue ?? '')
;
} else if(/>?\s*[^<]*$/m.test(string) && /^\s*[^<]*\s*/m.test(nextString)) {