@lion/core
Advanced tools
Comparing version 0.21.1 to 0.22.0
@@ -7,3 +7,3 @@ # How To >> Create a custom field ||20 | ||
import '@lion/form-core/define'; | ||
import '../../docs/systems/form/assets/h-output.js'; | ||
import '../../fundamentals/systems/form/assets/h-output.js'; | ||
@@ -77,5 +77,5 @@ // A) the custom [slot=input] or 'HTMLElementWithValue' | ||
Custom Fields can be created in just a few steps. All you need is an interaction element (like for instance a slider, a listbox or a combobox) and connect it to the [LionField](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/components/inputs/input/overview.md). | ||
Custom Fields can be created in just a few steps. All you need is an interaction element (like for instance a slider, a listbox or a combobox) and connect it to the [LionField](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/components/input/overview.md). | ||
> In case you want to extend a native element, follow [Extend a native Input](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/how-to/extend-a-native-input.md). | ||
> In case you want to extend a native element, follow [Extend a native Input](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/how-to/extend-a-native-input.md). | ||
@@ -128,4 +128,4 @@ ## A) an interaction element | ||
Now we want to integrate the slider in our form framework to enrich the user interface, get | ||
validation support and all other [benefits of LionField](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/components/inputs/input/overview.md). | ||
Now we want to integrate the slider in our form system to enrich the user interface, get | ||
validation support and all other [benefits of LionField](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/components/input/overview.md). | ||
We start by creating a component `<slider-field>` that extends from `LionField`. | ||
@@ -143,6 +143,12 @@ Then we follow the steps below: | ||
equivalent of the `input` event of the platform, but for custom built interaction elements. | ||
You now synchronized [modelValue](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/docs/systems/form/model-value.md), which can be regarded as | ||
You now synchronized [modelValue](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/fundamentals/systems/form/model-value.md), which can be regarded as | ||
the glue to integrate all other functionality like parsing/formatting/serializing, validating, | ||
tracking interaction states etc. | ||
> N.B. Make sure you never override other property getters than the one mentioned in this tutorial, | ||
> because those properties will loose their reactivity (they won't be considered anymore in the | ||
> update loop of LitElement). | ||
> Whenever a .modelValue/.formattedValue/.serializedValue needs to be computed, use | ||
> [parser/formatter/serializer](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/fundamentals/systems/form/formatting-and-parsing.md) | ||
Implement with the following code: | ||
@@ -172,2 +178,3 @@ | ||
get value() { | ||
// Remember we should always return type 'string' here | ||
return this._inputNode.value; | ||
@@ -191,4 +198,7 @@ } | ||
That was all! | ||
Now that your .modelValue is connected your component is fully compatible with our form system | ||
> Is your `.modelValue` still undefined? Please make sure you're `.value` is of type 'string'. | ||
Now you can enhance your slider by writing custom Validators for it or by | ||
writing a parser to get a custom modelValue type. |
@@ -9,3 +9,3 @@ # How To >> Extend a native Input ||20 | ||
import '@lion/input/define'; | ||
import '../../docs/systems/form/assets/h-output.js'; | ||
import '../../fundamentals/systems/form/assets/h-output.js'; | ||
@@ -15,5 +15,5 @@ loadDefaultFeedbackMessages(); | ||
Input fields can be created by extending [LionInput](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/components/inputs/input/overview.md). | ||
Input fields can be created by extending [LionInput](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/components/input/overview.md). | ||
> In case you want to wrap a custom form element, follow [Create a custom Field](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/how-to/create-a-custom-field.md). | ||
> In case you want to wrap a custom form element, follow [Create a custom Field](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/how-to/create-a-custom-field.md). | ||
@@ -20,0 +20,0 @@ For this tutorial, we create an input that wraps native `input[type=datetime-local]`. |
@@ -1,2 +0,2 @@ | ||
# Guides | ||
# Guides ||30 | ||
@@ -15,5 +15,5 @@ Lion is a set of white label Web Components that can be extended to your own styled layer of components. | ||
- [Definitions and Terms](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/principles/definitions-and-terms.md) | ||
- [Styling](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/principles/styling.md) | ||
- [Scoped Elements](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/principles/scoped-elements.md) | ||
- [Definitions and Terms](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/definitions-and-terms.md) | ||
- [Styling](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/styling.md) | ||
- [Scoped Elements](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/scoped-elements.md) | ||
@@ -26,4 +26,4 @@ ## Extending Developer | ||
- [Subclasser APIs](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/principles/subclasser-apis.md) | ||
- [Extend documentation](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/blog/extending-documentation) | ||
- [Subclasser APIs](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/subclasser-apis.md) | ||
- [Extend documentation](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/blog/extending-documentation.md) | ||
@@ -34,3 +34,4 @@ ## How To | ||
- [Get started](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/how-to/get-started.md) | ||
- [Create a custom field](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/how-to/create-a-custom-field.md) | ||
- [Get started](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/how-to/get-started.md) | ||
- [Create a custom field](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/how-to/create-a-custom-field.md) | ||
- [Extend a native input](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/how-to/extend-a-native-input.md) |
# Principles ||10 | ||
Lion is a set of white label Web Components that can be extended to your own styled layer of components. | ||
We know from experience that making high quality, accessible UI components is hard and time consuming: it takes many iterations, a lot of development time and a lot of testing to get a generic component that works in every context, supports many edge cases and is accessible in all relevant screen readers. | ||
Lion aims to do the heavy lifting for you. This means you only have to apply your own Design System: by delivering styles, configuring components and adding a minimal set of custom logic on top. | ||
## Consuming Developer | ||
Developers consuming our web components inside an application (not extending them). | ||
`Application Developers` are only allowed to interact with `public` properties and methods. | ||
Can be abbreviated as `AD`. Sometimes also called `Consuming Developer`. | ||
- [Definitions and Terms](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/definitions-and-terms.md) | ||
- [Styling](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/styling.md) | ||
- [Scoped Elements](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/scoped-elements.md) | ||
## Extending Developer | ||
Developers extending our web components, for instance: `class MaterialInput extends LionInput` are called `subclassers`. Subclassers have access to protected methods (prefixed with an underscore or marked as protected), but not to private methods. | ||
Especially for subclassers we have some extra documentation: | ||
- [Subclasser APIs](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/subclasser-apis.md) | ||
- [Extend documentation](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/blog/extending-documentation.md) |
@@ -22,5 +22,5 @@ # Principles >> Styling ||30 | ||
readable by screen readers, but invisible for end users. | ||
- When an html table is used, we allow [subclassers](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/guides/principles/subclasser-apis.md) to override the display property (`table-cell`) to `flex`. By putting the proper accessible roles (`role="cell"`) in the markup, we guarantee our markup stays accessible. | ||
- When an html table is used, we allow [subclassers](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/guides/principles/subclasser-apis.md) to override the display property (`table-cell`) to `flex`. By putting the proper accessible roles (`role="cell"`) in the markup, we guarantee our markup stays accessible. | ||
Although Lion components try to stay as unbiased as possible with regard to styling, defaults will be needed. In these cases we try to follow the platform as much as possible. If the platform doesn't provide defaults, the largest common denominator across existing UI frameworks is taken as a lead. | ||
Although Lion components try to stay as unbiased as possible with regard to styling, defaults will be needed. In these cases we try to follow the platform as much as possible. If the platform doesn't provide defaults, the largest common denominator across existing UI systems is taken as a lead. | ||
@@ -27,0 +27,0 @@ ## CSS variables |
@@ -18,3 +18,3 @@ # Systems >> Core >> Overview ||10 | ||
- [function to deduplicate mixins (dedupeMixin)](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/docs/systems/core/#deduping-of-mixins) | ||
- [function to deduplicate mixins (dedupeMixin)](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/fundamentals/systems/core/#deduping-of-mixins) | ||
- Mixin to handle disabled (DisabledMixin) | ||
@@ -21,0 +21,0 @@ - Mixin to handle disabled AND tabIndex (DisabledWithTabIndexMixin) |
{ | ||
"name": "@lion/core", | ||
"version": "0.21.1", | ||
"version": "0.22.0", | ||
"description": "Core functionality that is shared across all Lion Web Components", | ||
@@ -36,3 +36,3 @@ "license": "MIT", | ||
"@open-wc/dedupe-mixin": "^1.3.0", | ||
"@open-wc/scoped-elements": "^2.0.1", | ||
"@open-wc/scoped-elements": "^2.1.1", | ||
"lit": "^2.0.2" | ||
@@ -39,0 +39,0 @@ }, |
@@ -18,3 +18,3 @@ # Systems >> Core >> Overview ||10 | ||
- [function to deduplicate mixins (dedupeMixin)](https://github.com/ing-bank/lion/blob/7c52c12bfb025c98f93b5f0be984cedd3028a20a/docs/docs/systems/core/#deduping-of-mixins) | ||
- [function to deduplicate mixins (dedupeMixin)](https://github.com/ing-bank/lion/blob/974d0872a08182eed8be0af448d7229a7f5638fc/docs/fundamentals/systems/core/#deduping-of-mixins) | ||
- Mixin to handle disabled (DisabledMixin) | ||
@@ -21,0 +21,0 @@ - Mixin to handle disabled AND tabIndex (DisabledWithTabIndexMixin) |
@@ -38,6 +38,10 @@ import { unsafeCSS, css } from 'lit'; | ||
__setupStyleTag() { | ||
// Make it win from other elements on the page. | ||
// TODO: consider adding an id here to always win, since we are simulating shadow dom | ||
// behavior here. | ||
const highSpecifictyScope = `${this.scopedClass}.${this.scopedClass}`; | ||
this.__styleTag.textContent = /** @type {typeof ScopedStylesController} */ ( | ||
this.host.constructor | ||
) | ||
.scopedStyles(unsafeCSS(this.scopedClass)) | ||
.scopedStyles(unsafeCSS(highSpecifictyScope)) | ||
.toString(); | ||
@@ -44,0 +48,0 @@ this.host.insertBefore(this.__styleTag, this.host.childNodes[0]); |
@@ -42,3 +42,7 @@ /* eslint-disable class-methods-use-this */ | ||
__renderAsNodes(template) { | ||
const tempRenderTarget = document.createElement('div'); | ||
// @ts-expect-error wait for browser support | ||
const supportsScopedRegistry = !!ShadowRoot.prototype.createElement; | ||
const registryRoot = supportsScopedRegistry ? this.shadowRoot : document; | ||
// @ts-expect-error wait for browser support | ||
const tempRenderTarget = registryRoot.createElement('div'); | ||
render(template, tempRenderTarget, this.renderOptions); | ||
@@ -45,0 +49,0 @@ return Array.from(tempRenderTarget.childNodes); |
@@ -6,2 +6,16 @@ import sinon from 'sinon'; | ||
function mockScopedRegistry() { | ||
// @ts-expect-error wait for browser support | ||
ShadowRoot.prototype.createElement = () => {}; | ||
// @ts-expect-error wait for browser support | ||
window.CustomElementRegistry = class {}; | ||
} | ||
function unMockScopedRegistry() { | ||
// @ts-expect-error wait for browser support | ||
delete ShadowRoot.prototype.createElement; | ||
// @ts-expect-error wait for browser support | ||
delete window.CustomElementRegistry; | ||
} | ||
describe('SlotMixin', () => { | ||
@@ -192,3 +206,3 @@ it('inserts provided element into lightdom and sets slot', async () => { | ||
); | ||
const el = await fixture(`<${tag}><${tag}>`); | ||
const el = await fixture(`<${tag}></${tag}>`); | ||
const slot = /** @type HTMLSpanElement */ ( | ||
@@ -201,11 +215,7 @@ Array.from(el.children).find(elm => elm.slot === 'template') | ||
it('supports scoped elements', async () => { | ||
const scopedSpy = sinon.spy(); | ||
class ScopedEl extends LitElement { | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
scopedSpy(); | ||
} | ||
} | ||
it('supports scoped elements when polyfill loaded', async () => { | ||
mockScopedRegistry(); | ||
class ScopedEl extends LitElement {} | ||
const tag = defineCE( | ||
@@ -228,10 +238,42 @@ class extends ScopedElementsMixin(SlotMixin(LitElement)) { | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
render() { | ||
return html`<slot name="template"></slot>`; | ||
} | ||
}, | ||
); | ||
// Not rendered to shadowRoot, notScopedSpy should not be called | ||
const notScoped = document.createElement('not-scoped'); | ||
this.appendChild(notScoped); | ||
let error = ''; | ||
try { | ||
// @ts-ignore | ||
await fixture(html`<${tag}></${tag}>`, { scopedElements: true }); | ||
} catch (e) { | ||
// @ts-ignore | ||
error = e.toString(); | ||
} | ||
// it throws when it uses our temp mock (error is browser specific, so we check overlapping part) | ||
expect(error).to.include('.importNode is not a function'); | ||
unMockScopedRegistry(); | ||
}); | ||
it('does not scope elements when polyfill not loaded', async () => { | ||
class ScopedEl extends LitElement {} | ||
const tag = defineCE( | ||
class extends ScopedElementsMixin(SlotMixin(LitElement)) { | ||
static get scopedElements() { | ||
return { | ||
// @ts-expect-error | ||
...super.scopedElements, | ||
'scoped-el': ScopedEl, | ||
}; | ||
} | ||
get slots() { | ||
return { | ||
...super.slots, | ||
template: () => html`<scoped-el></scoped-el>`, | ||
}; | ||
} | ||
render() { | ||
@@ -243,5 +285,8 @@ return html`<slot name="template"></slot>`; | ||
await fixture(`<${tag}><${tag}>`); | ||
expect(scopedSpy).to.have.been.called; | ||
const docSpy = sinon.spy(document, 'createElement'); | ||
await fixture(html`<${tag}></${tag}>`); | ||
// one for the fixture, one for the scoped slot | ||
expect(docSpy).to.have.been.calledTwice; | ||
docSpy.restore(); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
111749
2011