@semantic-ui/component
Advanced tools
Comparing version 0.1.2 to 0.1.3
@@ -15,8 +15,8 @@ { | ||
"dependencies": { | ||
"@semantic-ui/query": "^0.1.2", | ||
"@semantic-ui/reactivity": "^0.1.2", | ||
"@semantic-ui/templating": "^0.1.2", | ||
"@semantic-ui/utils": "^0.1.2" | ||
"@semantic-ui/query": "^0.1.3", | ||
"@semantic-ui/reactivity": "^0.1.3", | ||
"@semantic-ui/templating": "^0.1.3", | ||
"@semantic-ui/utils": "^0.1.3" | ||
}, | ||
"version": "0.1.2" | ||
"version": "0.1.3" | ||
} |
@@ -92,2 +92,4 @@ import { unsafeCSS } from 'lit'; | ||
static template = litTemplate; | ||
static properties = WebComponentBase.getProperties({ | ||
@@ -104,2 +106,3 @@ properties, | ||
this.css = css; | ||
this.componentSpec = componentSpec; | ||
this.settings = this.createSettingsProxy({componentSpec, properties: webComponent.properties}); | ||
@@ -152,8 +155,2 @@ this.setDefaultSettings({settings, componentSpec}); | ||
super.firstUpdated(); | ||
// shared variations are passed through to singular | ||
/*this.watchSlottedContent({ | ||
singularTag, | ||
componentSpec, | ||
properties: webComponent.properties | ||
});*/ | ||
} | ||
@@ -186,4 +183,16 @@ | ||
/******************************* | ||
Settings | ||
*******************************/ | ||
getSettings() { | ||
return this.getSettingsFromConfig({componentSpec, properties: webComponent.properties }); | ||
} | ||
setSetting(name, value) { | ||
this[name] = value; | ||
} | ||
getData() { | ||
let settings = this.getSettings({componentSpec, properties: webComponent.properties }); | ||
let settings = this.getSettings(); | ||
let data = { | ||
@@ -190,0 +199,0 @@ ...settings, |
import { html, svg } from 'lit'; | ||
import { Reaction, ReactiveVar } from '@semantic-ui/reactivity'; | ||
import { each, mapObject, wrapFunction, fatal, isArray, isFunction } from '@semantic-ui/utils'; | ||
import { each, mapObject, wrapFunction, fatal, isArray, isPlainObject, isString, isFunction } from '@semantic-ui/utils'; | ||
@@ -158,27 +158,54 @@ import { reactiveData } from './directives/reactive-data.js'; | ||
evaluateSnippet(node, data = {}) { | ||
// returns a function that returns the value in the current data context | ||
getPackedValue = (expression, data, { reactive = false } = {}) => { | ||
const getValue = (expressionString) => { | ||
return this.lookupExpressionValue(expressionString, data); | ||
const value = this.evaluateExpression(expressionString, data); // easier for breakpoints | ||
return value; | ||
}; | ||
return (reactive) | ||
? () => getValue(expression) | ||
: () => Reaction.nonreactive(() => getValue(expression)) | ||
; | ||
}; | ||
const snippetName = getValue(node.name); | ||
getPackedNodeData(node, data, { inheritParent = false } = {}) { | ||
const getPackedData = (unpackedData, options = {}) => { | ||
let packedData = {}; | ||
// this is a data object like {> someTemplate data=getData } | ||
// we need to get the data first before we can wrap it | ||
if(isString(unpackedData)) { | ||
unpackedData = this.evaluateExpression(unpackedData, data, options); | ||
} | ||
// okay now we have the data in both cases, lets pack it | ||
// this is a data object like {> someTemplate data={one: someExpr, two: someExpr } } | ||
if(isPlainObject(unpackedData)) { | ||
packedData = mapObject(unpackedData, (expression) => this.getPackedValue(expression, data, options)); | ||
} | ||
return packedData; | ||
}; | ||
const packedStaticData = getPackedData(node.data); | ||
const packedReactiveData = getPackedData(node.reactiveData, { reactive: true }); | ||
// only inherit parent data context if specified | ||
let parentData = (inheritParent) | ||
? data | ||
: {} | ||
; | ||
const packedData = { | ||
...parentData, | ||
...packedStaticData, | ||
...packedReactiveData | ||
}; | ||
return packedData; | ||
} | ||
evaluateSnippet(node, data = {}) { | ||
const snippetName = this.lookupExpressionValue(node.name, data); | ||
const snippet = this.snippets[snippetName]; | ||
if (!snippet) { | ||
fatal(`Snippet "${snippetName}" not found`); | ||
} | ||
// Prepare snippet data | ||
const staticValues = mapObject(node.data || {}, (value) => { | ||
return Reaction.nonreactive(() => getValue(value)); | ||
}); | ||
const reactiveValues = mapObject(node.reactiveData || {}, (value) => { | ||
return getValue(value); | ||
}); | ||
const snippetData = { | ||
...data, | ||
...staticValues, | ||
...reactiveValues, | ||
}; | ||
const snippetData = this.getPackedNodeData(node, data, { inheritParent: true }); | ||
return this.renderContent({ | ||
@@ -191,24 +218,6 @@ ast: snippet.content, | ||
evaluateSubTemplate(node, data = {}) { | ||
const getValue = (expressionString) => { | ||
const value = this.evaluateExpression(expressionString, data); | ||
return value; | ||
}; | ||
// template names can be dynamic | ||
const getTemplateName = () => getValue(node.name); | ||
// data can either be reactive or nonreactive | ||
const staticValues = mapObject(node.data || {}, (value) => { | ||
return () => Reaction.nonreactive(() => getValue(value)); | ||
}); | ||
const reactiveValues = mapObject(node.reactiveData || {}, (value) => { | ||
return () => getValue(value); | ||
}); | ||
const templateData = { | ||
...staticValues, | ||
...reactiveValues, | ||
}; | ||
const templateData = this.getPackedNodeData(node, data); | ||
return renderTemplate({ | ||
subTemplates: this.subTemplates, | ||
getTemplateName: getTemplateName, | ||
getTemplateName: () => this.evaluateExpression(node.name, data), // template name can be dynamic | ||
data: templateData, | ||
@@ -215,0 +224,0 @@ parentTemplate: data, |
@@ -26,5 +26,2 @@ import { LitElement } from 'lit'; | ||
super.updated(); | ||
if (this.useLight) { | ||
this.slotLightContent(); | ||
} | ||
each(this.renderCallbacks, (callback) => callback()); | ||
@@ -64,104 +61,3 @@ } | ||
storeOriginalContent() { | ||
this.originalDOM = document.createElement('template'); | ||
this.originalDOM.innerHTML = this.innerHTML; | ||
this.innerHTML = ''; | ||
} | ||
slotLightContent() { | ||
const $slots = this.$('slot'); | ||
$slots.each((slot) => { | ||
const $slot = $(slot); | ||
let html; | ||
if ($slot.attr('name')) { | ||
let slotName = $slot.attr('name'); | ||
const $slotContent = this.$$(`[slot="${slotName}"]`); | ||
if ($slotContent.length) { | ||
html = $slotContent.outerHTML(); | ||
} | ||
} | ||
else { | ||
// default slot takes all DOM content that is not slotted | ||
const $originalDOM = this.$$(this.originalDOM.content); | ||
const $defaultContent = $originalDOM.children().not('[slot]'); | ||
const defaultHTML = $defaultContent.html() || ''; | ||
const defaultText = $originalDOM.textNode() || ''; | ||
html = defaultHTML + defaultText; | ||
} | ||
if ($slot && html) { | ||
$slot.html(html); | ||
} | ||
}); | ||
} | ||
/******************************* | ||
Nested Components | ||
*******************************/ | ||
/* This is currently not being called out because | ||
it cannot ever work for SSR. | ||
including it would mean breaking parity of functionality | ||
* | ||
*/ | ||
watchSlottedContent(settings) { | ||
const $slot = this.$('slot'); | ||
// initial render | ||
$slot.each((el) => { | ||
this.onSlotChange(el, settings); | ||
}); | ||
// on change | ||
$slot.on('slotchange', (event) => { | ||
this.onSlotChange(event.target, settings); | ||
}); | ||
} | ||
onSlotChange(slotEl, {singularTag, componentSpec, properties}) { | ||
const nodes = slotEl.assignedNodes(); | ||
const name = slotEl.name || 'default'; | ||
const settings = this.getSettings({componentSpec, properties}); | ||
if(!this.slottedContent) { | ||
this.slottedContent = {}; | ||
} | ||
this.slottedContent[name] = nodes; | ||
if(singularTag) { | ||
// we use this element to track last-child | ||
let lastSingularNode; | ||
const isSingular = (node) => { | ||
return node.tagName && node.tagName.toLowerCase() == singularTag; | ||
}; | ||
const addSingularProps = (node) => { | ||
if(!isSingular(node)) { | ||
return; | ||
} | ||
if(!lastSingularNode) { | ||
node.setAttribute('first', ''); | ||
} | ||
node.setAttribute('grouped', ''); | ||
lastSingularNode = node; | ||
each(componentSpec?.inheritedPluralVariations, (variation) => { | ||
const pluralVariation = settings[variation]; | ||
if(pluralVariation && !node[variation]) { | ||
node.setAttribute(variation, pluralVariation); | ||
} | ||
}); | ||
}; | ||
/* | ||
We look a max of two levels deep | ||
this is because sometimes rendering tools like Astro | ||
will wrap a component in an arbitrary tag (island). | ||
*/ | ||
nodes.forEach(node => { | ||
addSingularProps(node); | ||
each(node.children, addSingularProps); | ||
}); | ||
if(lastSingularNode) { | ||
lastSingularNode.setAttribute('last', ''); | ||
} | ||
} | ||
} | ||
/******************************* | ||
Lit Properties | ||
@@ -271,3 +167,3 @@ *******************************/ | ||
*/ | ||
getSettings({componentSpec, properties}) { | ||
getSettingsFromConfig({componentSpec, properties}) { | ||
let settings = {}; | ||
@@ -303,8 +199,2 @@ each(properties, (propSettings, property) => { | ||
/* This may become more complex if we choose to support | ||
reverse attribute lookups like setSetting('large'); | ||
*/ | ||
setSetting(name, value) { | ||
this[name] = value; | ||
} | ||
@@ -311,0 +201,0 @@ |
46231
1365
Updated@semantic-ui/query@^0.1.3
Updated@semantic-ui/utils@^0.1.3