Merge pull request #592 from lowdefy/version

Release version 3.16.0
This commit is contained in:
Gervwyk 2021-05-26 15:14:57 +02:00 committed by GitHub
commit fefb86372d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
192 changed files with 5869 additions and 1520 deletions

View File

@ -3,6 +3,102 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
## Changes
### Fixes
- Add new block locations to build.
- Fix Descriptions schema for docs generator.
## Commits
### Bug Fixes
- **build:** Add default locations for new blocks. ([544d1e1](https://github.com/lowdefy/lowdefy/commit/544d1e1d8459fb03294eb692f12116fa9f3904a5))
- **docs:** Fix Descriptions schema for docs generator. ([dbe1efe](https://github.com/lowdefy/lowdefy/commit/dbe1efec53930f5507abcebb54bc4d21e56ddc94))
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
## Changes
### BREAKING
- Rename selectGMT to selectUTC for DateTimeSelector.
### Depreciated
- Depreciate \_js.evaluate and \_js.function operators. Replaced with the new \_js operator. See [https://docs.lowdefy.com/\_js](https://docs.lowdefy.com/_js)
### Features
- Add support for custom HTML before the closing head and body tags of the app.
- Add the JsAction action, that can run custom JavaScript.
- Javascript operators are now implemented differently. See [https://docs.lowdefy.com/custom-code](https://docs.lowdefy.com/custom-code)
- Add Tooltip and Img blocks.
### Fixes
- Fix docs sitemap.
- Add new-line support to Descriptions, closes [#581](https://github.com/lowdefy/lowdefy/issues/581)
- Fix DateTimeSelector to work for local or utc time, closes [#580](https://github.com/lowdefy/lowdefy/issues/580)
- Document client and server environment operators.
- Document context initialization events for context blocks.
- SendGridMailSend to handle arrays, closes [#582](https://github.com/lowdefy/lowdefy/issues/582)
- Document Tabs block events, closes [#576](https://github.com/lowdefy/lowdefy/issues/576).
- Wait for login action on expired token refresh.
- Fixed cached scripts on app update by including contenthash in webpack output, closes [#575](https://github.com/lowdefy/lowdefy/issues/575).
## Commits
### Bug Fixes
- **docs:** Sitemap must be https. ([290b271](https://github.com/lowdefy/lowdefy/commit/290b271ec6b1cff3e89c3381ab741d913eea5688))
- fix indentation level op events in schema ([4426888](https://github.com/lowdefy/lowdefy/commit/44268886182657a95b7b1f4c1f2e7aa0ec63bcd1))
- **blocksAntd:** Add new-line support to Descriptions, closes [#581](https://github.com/lowdefy/lowdefy/issues/581) ([41bb9ee](https://github.com/lowdefy/lowdefy/commit/41bb9eee438b60d75efe00a433beb99ad98e78b8))
- **blocksAntd:** Fix DateTimeSelector to work for local or utc time, closes [#580](https://github.com/lowdefy/lowdefy/issues/580) # ([30a4764](https://github.com/lowdefy/lowdefy/commit/30a476460859f8b72198bad17ef892ef634cb24d))
- **blocksAntd:** Fix srcSet and media change width. ([4fb991a](https://github.com/lowdefy/lowdefy/commit/4fb991af415ab66dcdee59d233bf43d4c271f99c))
- **blocksAntd:** Rename selectGMT to selectUTC for DateTimeSelector. ([e817fb1](https://github.com/lowdefy/lowdefy/commit/e817fb1900a66c38487632500302040acd206a46))
- **build:** Do not throw on validate app config. ([96904a7](https://github.com/lowdefy/lowdefy/commit/96904a7783695f2b60b20be9488ffcb8dde79930))
- **docs:** Add alerts for client or server operators. ([bf5c9be](https://github.com/lowdefy/lowdefy/commit/bf5c9be5e672703c7e31f7a5a7228e492dd73e9c))
- **docs:** Add custom code concept. ([b0e63e1](https://github.com/lowdefy/lowdefy/commit/b0e63e1e2e7bcbdcec3c96692f694a8cd33e3b1d))
- **docs:** Add discord link. ([0a24af7](https://github.com/lowdefy/lowdefy/commit/0a24af75ebb682abf51556cafcab1c584e01053e))
- **docs:** Document context initialization events for context blocks. ([a59bff5](https://github.com/lowdefy/lowdefy/commit/a59bff50f25b79d0468a4a6afc836f264c3263b2)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
- **engine:** Add tests for JsAction. ([2113ae5](https://github.com/lowdefy/lowdefy/commit/2113ae5c74d1143e1305b858b555cd5ff35faa59))
- **engine:** Update tests for new action responses structure. ([73c84e6](https://github.com/lowdefy/lowdefy/commit/73c84e6fdc75f4aca072f6843fea17eee87b02eb))
- **graphql:** SendGridMailSend to handle arrays, closes [#582](https://github.com/lowdefy/lowdefy/issues/582) ([dc0ef6c](https://github.com/lowdefy/lowdefy/commit/dc0ef6c521d1b4e5b2c498e2932cc2c2d83f5eb1))
- Fix Tabs blocks events in schema. ([70a13af](https://github.com/lowdefy/lowdefy/commit/70a13af94d90c6c40276f77fefea8708e7040451)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
- webpack config so that index.html is not minified. ([d9cbf8d](https://github.com/lowdefy/lowdefy/commit/d9cbf8df56f97116832a7038f026058f1d528dc6))
- **docs:** Change to head.html. ([a7f20c4](https://github.com/lowdefy/lowdefy/commit/a7f20c4d238b520cf172934fd9df0c4f83d9157d))
- **docs:** Create modules/index and load filterDefaultValue. ([e45e5f1](https://github.com/lowdefy/lowdefy/commit/e45e5f1f80ccc256d668e92813b9e5415eccf6b7))
- **docs:** Fix custom block event actions history description. ([eb49803](https://github.com/lowdefy/lowdefy/commit/eb49803a48719c38a7d4cb0ff7d0540c0da25d75))
- **docs:** Import \_js.filterDefaultValue as operator. ([a6e2fe0](https://github.com/lowdefy/lowdefy/commit/a6e2fe036160d49b6c1994aee68326f88fc7c564))
- **docs:** Updates to custom code docs. ([a4be530](https://github.com/lowdefy/lowdefy/commit/a4be53077afd6dbcf42f41473695f77d00ccd1a5))
- **engine:** Modify action response object. ([94db71d](https://github.com/lowdefy/lowdefy/commit/94db71d2ace301c930f775de44d9908eb9c63576))
- **operators:** Update tests for \_js and \_actions. ([022893b](https://github.com/lowdefy/lowdefy/commit/022893bbca2dbfdbd8542dc3436cf5d960522f3c))
- **renderer:** Fix deprication build warning. ([18baf4a](https://github.com/lowdefy/lowdefy/commit/18baf4a421741c4c8f3034eea4fcf697a9c15023))
- **renderer:** Load and remove lowdefy.imports. ([e6fccbc](https://github.com/lowdefy/lowdefy/commit/e6fccbc4f9d7a9ec19e746b33698d86d0a2cab58))
- **renderer:** Wait for login action on expired token refresh. ([7219cdd](https://github.com/lowdefy/lowdefy/commit/7219cddb40f047e539c723aa2a19ea3c2a2bebe3))
- Rename appendHeader to appendHead. ([4e79736](https://github.com/lowdefy/lowdefy/commit/4e797363540bd0f5cfbe65928585012316b05a58))
- **servers:** Express function changed to async. ([6df571b](https://github.com/lowdefy/lowdefy/commit/6df571b0475d946e6864c2824af36450b70a7fa0))
### Features
- add Tooltip to docs ([e79a876](https://github.com/lowdefy/lowdefy/commit/e79a876a30585d90532680d7229ee921b18a4ac1))
- new Tooltip block and tests ([8717767](https://github.com/lowdefy/lowdefy/commit/871776745a3a4beb60622bb5b3e5aca0a1454a94))
- **blockBasic:** Add Img block. ([c850cb3](https://github.com/lowdefy/lowdefy/commit/c850cb32061cf2a4c361aecc024fe699cc06c7e0))
- Include contenthash in webpack output. ([dd2adbb](https://github.com/lowdefy/lowdefy/commit/dd2adbbaa195899c6986ca99934e19c4f6aeca21)), closes [#575](https://github.com/lowdefy/lowdefy/issues/575)
- **build:** Build app config. ([6575bc7](https://github.com/lowdefy/lowdefy/commit/6575bc78bc37a1b33f301364a5daee4bab324884))
- **cli:** Add appendHead, appendBody and custom js scripts. ([0f74833](https://github.com/lowdefy/lowdefy/commit/0f74833914917e7fb5d2d51177e2010b698d1019))
- **docs:** Add \_actions operator. ([d5583d2](https://github.com/lowdefy/lowdefy/commit/d5583d200a809cc451d051a7ee16455f018beff9))
- **docs:** Add JsAction. ([19fd956](https://github.com/lowdefy/lowdefy/commit/19fd9563c038a16aabebbf5c0e9b3324efa5b9d4))
- **engine:** Add JsAction. ([005155a](https://github.com/lowdefy/lowdefy/commit/005155aecf97774b37611eaa18c6aa854d6a92d3))
- **operators:** Custom \_js and \_actions operators. ([815f6a4](https://github.com/lowdefy/lowdefy/commit/815f6a452fcbe38ce21361393d2a0c9a74ff7058))
- **renderer:** Add customActions, jsOperators, registerCustomAction and registerJsOperator to lowdefy object. ([95f853d](https://github.com/lowdefy/lowdefy/commit/95f853da4b8f4308a9751a191b9519e8d69e8ace))
- **server:** Add head and body load scripts. ([ad195b4](https://github.com/lowdefy/lowdefy/commit/ad195b409b1780ac1bb3e194de5c106dbdb0b2b3))
- **servers:** Load header and body html on server. ([a5b070f](https://github.com/lowdefy/lowdefy/commit/a5b070f03b1d69991e9bfa7a4ccd571972d344df))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
## Changes

View File

@ -1,10 +1,12 @@
![Lowdefy](https://lowdefy.com/banner.png)
![Discord](https://img.shields.io/discord/729696747261263962?label=Discord%20Chat&logo=discord&logoColor=white)
[![Tweet](https://img.shields.io/twitter/url?logo=twitter&style=flat-square&url=https%3A%2F%2Flowdefy.com)](https://twitter.com/intent/tweet?text=Build%20web%20apps%2C%20admin%20panels%2C%20BI%20dashboards%2C%20and%20CRUD%20apps%20with%20ease%21%20Try%20&url=https://lowdefy.com&via=lowdefy&hashtags=lowcode,lowdefy,internaltools,developers,opensource)
[![Follow](https://img.shields.io/twitter/follow/lowdefy?logo=twitter&style=flat-square)](https://twitter.com/intent/follow?screen_name=lowdefy)
![Tests Main](https://github.com/lowdefy/lowdefy/workflows/Test%20Branches/badge.svg?branch=main)
![Tests Develop](https://github.com/lowdefy/lowdefy/workflows/Test%20Branches/badge.svg?branch=develop)
![Tests Main](https://github.com/lowdefy/lowdefy/workflows/Test%20Main/badge.svg?branch=main)
![Tests Develop](https://github.com/lowdefy/lowdefy/workflows/Test%20Develop/badge.svg?branch=develop)
[![Maintainability](https://api.codeclimate.com/v1/badges/6efe9bfa0648772cae00/maintainability)](https://codeclimate.com/github/lowdefy/lowdefy/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/6efe9bfa0648772cae00/test_coverage)](https://codeclimate.com/github/lowdefy/lowdefy/test_coverage)
[![Codecov](https://codecov.io/gh/lowdefy/lowdefy/branch/main/graph/badge.svg?token=U2AEEH9K1W)](https://codecov.io/gh/lowdefy/lowdefy)

View File

@ -1,5 +1,5 @@
{
"version": "3.15.0",
"version": "3.16.1",
"packages": [
"src/packages/*",
"src/packages/blocks/*",

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/lowdefy",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"private": true,
"description": "Lowdefy monorepo",

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/ajv
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/ajv
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/ajv

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/ajv",
"version": "3.15.0",
"version": "3.16.1",
"licence": "Apache-2.0",
"description": "",
"homepage": "https://lowdefy.com",
@ -38,7 +38,7 @@
"prepare": "yarn build"
},
"dependencies": {
"@lowdefy/nunjucks": "3.15.0",
"@lowdefy/nunjucks": "3.16.1",
"ajv": "6.12.6",
"ajv-errors": "1.0.1"
},

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/block-tools
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/block-tools
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/block-tools

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/block-tools",
"version": "3.15.0",
"version": "3.16.1",
"licence": "Apache-2.0",
"description": "Lowdefy Block Tools",
"homepage": "https://lowdefy.com",
@ -37,7 +37,7 @@
"test": "jest --coverage"
},
"dependencies": {
"@lowdefy/helpers": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"ajv": "6.12.6",
"ajv-errors": "1.0.1",
"create-emotion": "10.0.27",

View File

@ -3,6 +3,39 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
### Bug Fixes
* **docs:** Fix Descriptions schema for docs generator. ([dbe1efe](https://github.com/lowdefy/lowdefy/commit/dbe1efec53930f5507abcebb54bc4d21e56ddc94))
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
### Bug Fixes
* fix indentation level op events in schema ([4426888](https://github.com/lowdefy/lowdefy/commit/44268886182657a95b7b1f4c1f2e7aa0ec63bcd1))
* **blocksAntd:** Add new-line support to Descriptions, closes [#581](https://github.com/lowdefy/lowdefy/issues/581) ([41bb9ee](https://github.com/lowdefy/lowdefy/commit/41bb9eee438b60d75efe00a433beb99ad98e78b8))
* **blocksAntd:** Fix DateTimeSelector to work for local or utc time, closes [#580](https://github.com/lowdefy/lowdefy/issues/580) # ([30a4764](https://github.com/lowdefy/lowdefy/commit/30a476460859f8b72198bad17ef892ef634cb24d))
* **blocksAntd:** Fix srcSet and media change width. ([4fb991a](https://github.com/lowdefy/lowdefy/commit/4fb991af415ab66dcdee59d233bf43d4c271f99c))
* **docs:** Document context initialization events for context blocks. ([a59bff5](https://github.com/lowdefy/lowdefy/commit/a59bff50f25b79d0468a4a6afc836f264c3263b2)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
* Fix Tabs blocks events in schema. ([70a13af](https://github.com/lowdefy/lowdefy/commit/70a13af94d90c6c40276f77fefea8708e7040451)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
* **blocksAntd:** Rename selectGMT to selectUTC for DateTimeSelector. ([e817fb1](https://github.com/lowdefy/lowdefy/commit/e817fb1900a66c38487632500302040acd206a46))
### Features
* new Tooltip block and tests ([8717767](https://github.com/lowdefy/lowdefy/commit/871776745a3a4beb60622bb5b3e5aca0a1454a94))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)

View File

@ -4,30 +4,30 @@
type: DateTimeSelector
properties:
title: DateTimeSelector title
- id: "properties.allowClear: false"
- id: 'properties.allowClear: false'
type: DateTimeSelector
properties:
allowClear: false
- id: "properties.autoFocus: true"
- id: 'properties.autoFocus: true'
type: DateTimeSelector
properties:
autoFocus: true
- id: "properties.disabled: true"
- id: 'properties.disabled: true'
type: DateTimeSelector
properties:
disabled: true
- id: "properties.disabledDates.min"
- id: 'properties.disabledDates.min'
type: DateSelector
properties:
disabledDates:
min: 2020-10-20
- id: "properties.disabledDates.max"
- id: 'properties.disabledDates.max'
type: DateSelector
properties:
disabledDates:
max: 2020-10-15
- id: "properties.disabledDates.dates"
- id: 'properties.disabledDates.dates'
type: DateSelector
properties:
disabledDates:
@ -35,88 +35,88 @@
- _date: 2020-10-26
- 2020-10-29
- 2020-11-02
- id: "properties.disabledDates.ranges"
- id: 'properties.disabledDates.ranges'
type: DateSelector
properties:
disabledDates:
ranges:
- ["2020-10-26", "2020-10-29"]
- ['2020-10-26', '2020-10-29']
- - 2020-11-01
- 2020-11-02
- id: "properties.format: YYYY-MMM-DD HH:mm:ss (moment.js formats)"
- id: 'properties.format: YYYY-MMM-DD HH:mm:ss (moment.js formats)'
type: DateTimeSelector
properties:
format: YYYY-MMM-DD HH:mm:ss
- id: "properties.timeFormat: HH:mm:ss"
- id: 'properties.timeFormat: HH:mm:ss'
type: DateTimeSelector
properties:
format: HH:mm:ss
- id: "properties.hourStep"
- id: 'properties.hourStep'
type: DateTimeSelector
properties:
hourStep: 2
- id: "properties.minuteStep"
- id: 'properties.minuteStep'
type: DateTimeSelector
properties:
minuteStep: 15
- id: "properties.secondStep"
- id: 'properties.secondStep'
type: DateTimeSelector
properties:
secondStep: 30
- id: "properties.selectGMT: true"
- id: 'properties.selectUTC: true'
type: DateTimeSelector
properties:
selectGMT: true
- id: "properties.placeholder: - Select this Date and Time"
selectUTC: true
- id: 'properties.placeholder: - Select this Date and Time'
type: DateTimeSelector
properties:
placeholder: Select this Date and Time
- id: "properties.showNow: false"
- id: 'properties.showNow: false'
type: DateTimeSelector
properties:
showNow: false
- id: "properties.size: small"
- id: 'properties.size: small'
type: DateTimeSelector
properties:
size: small
- id: "properties.suffixIcon: CalendarTwoTone"
- id: 'properties.suffixIcon: CalendarTwoTone'
type: DateTimeSelector
properties:
suffixIcon: CalendarTwoTone
- id: "properties.inputStyle: CSS style applied"
- id: 'properties.inputStyle: CSS style applied'
type: DateTimeSelector
properties:
inputStyle:
border: 1px solid red
- id: "properties.label span: 5"
- id: 'properties.label span: 5'
type: DateTimeSelector
properties:
label:
span: 5
- id: "properties.label align: right"
- id: 'properties.label align: right'
type: DateTimeSelector
properties:
label:
align: right
- id: "properties.label inline: true"
- id: 'properties.label inline: true'
type: DateTimeSelector
properties:
label:
inline: true
- id: "properties.label disabled: true"
- id: 'properties.label disabled: true'
type: DateTimeSelector
properties:
label:
disabled: true
- id: "properties.label colon: true"
- id: 'properties.label colon: true'
type: DateTimeSelector
properties:
label:
colon: true
- id: "properties.label extra: extra text added"
- id: 'properties.label extra: extra text added'
type: DateTimeSelector
properties:
label:

View File

@ -1,6 +1,6 @@
- id: default
type: Descriptions
- id: default
- id: default title
type: Descriptions
properties:
title: Descriptions title
@ -19,37 +19,49 @@
column: 2
items:
- label: field_one
value: "1"
value: '1'
span: 1
- label: field_two
value: "2"
value: '2'
span: 1
- label: field_three
value: "3"
value: '3'
span: 2
- id: properties.items-list-primitive
- id: properties.items-list with new lines
type: Descriptions
properties:
title: Title
column: 2
items:
- 1
- 2
- 3
- 4
- label: field_one
value: "description field with \nnew line \t helps\n make better content."
span: 1
- label: 'one \n two;'
value: "description field with \nnew line \t helps\n make better content."
span: 1
# - id: properties.items-list-primitive
# type: Descriptions
# properties:
# title: Title
# items:
# - 1
# - 2
# - 3
# - 4
- id: properties.items-object-object
type: Descriptions
properties:
title: Title
items:
one:
one:
two: 3
four:
five: six
seven:
seven:
eight:
- 9
- 9
- ten
- id: "properties.bordered: true"
- id: 'properties.bordered: true'
type: Descriptions
properties:
bordered: true
@ -57,7 +69,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.colon: false"
- id: 'properties.colon: false'
type: Descriptions
properties:
colon: false
@ -65,7 +77,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.column: 2"
- id: 'properties.column: 2'
type: Descriptions
properties:
column: 2
@ -73,7 +85,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.layout: vertical"
- id: 'properties.layout: vertical'
type: Descriptions
properties:
layout: vertical
@ -81,7 +93,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.size: small"
- id: 'properties.size: small'
type: Descriptions
properties:
size: small
@ -89,7 +101,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.size: default"
- id: 'properties.size: default'
type: Descriptions
properties:
size: default
@ -97,7 +109,7 @@
field_one: value one
field_two: 2
field_three: value three
- id: "properties.size: small, properties.bordered: true"
- id: 'properties.size: small, properties.bordered: true'
type: Descriptions
properties:
size: small
@ -109,3 +121,11 @@
field_4: value 4
field_5: 5
field_6: value 6
- id: properties.items-object with new lines
type: Descriptions
properties:
title: Title
column: 2
items:
field_one: "description one field with \n new line \t helps\n make better content."
'one \n two;': "description two field with \n new line \t helps\n make better content."

View File

@ -61,11 +61,11 @@
logo:
style:
border: 5px solid blue
- id: 'properties.logo.srcset'
- id: 'properties.logo.srcSet'
type: PageHeaderMenu
properties:
logo:
srcset: 'https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w'
srcSet: 'https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w'
menu:
links:
- id: Introduction
@ -84,7 +84,7 @@
type: PageHeaderMenu
properties:
logo:
srcset: '(max-width: 767px) 40px, 768px'
srcSet: '(max-width: 767px) 40px, 768px'
menu:
links:
- id: Introduction

View File

@ -61,11 +61,11 @@
logo:
style:
border: 5px solid blue
- id: 'properties.logo.srcset'
- id: 'properties.logo.srcSet'
type: PageHeaderMenu
properties:
logo:
srcset: 'https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w'
srcSet: 'https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w'
menu:
links:
- id: Introduction
@ -84,7 +84,7 @@
type: PageHeaderMenu
properties:
logo:
srcset: '(max-width: 767px) 40px, 768px'
srcSet: '(max-width: 767px) 40px, 768px'
menu:
links:
- id: Introduction

View File

@ -0,0 +1,74 @@
- id: default
type: Tooltip
- id: "properties.title"
type: Tooltip
properties:
title: Tooltip block
- id: "properties.autoAdjustOverflow: false"
type: Tooltip
properties:
title: autoAdjustOverflow false
autoAdjustOverflow: false
placement: right
- id: "properties.autoAdjustOverflow: true"
type: Tooltip
properties:
title: autoAdjustOverflow true
autoAdjustOverflow: true
placement: right
- id: "properties.color: blue"
type: Tooltip
properties:
title: color blue
color: blue
- id: "properties.defaultVisible: true"
type: Tooltip
properties:
title: defaultVisible true
defaultVisible: true
- id: "properties.mouseEnterDelay: 1"
type: Tooltip
properties:
title: mouseEnterDelay 1
mouseEnterDelay: 1
- id: "properties.mouseLeaveDelay: 1"
type: Tooltip
properties:
title: mouseLeaveDelay 1
mouseLeaveDelay: 1
- id: "properties.placement"
type: Tooltip
properties:
title: placement topLeft
placement: topLeft
- id: "properties.arrowPointAtCenter: true"
type: Tooltip
properties:
title: arrowPointAtCenter true
arrowPointAtCenter: true
placement: topLeft
- id: "properties.trigger: click"
type: Tooltip
properties:
title: trigger click
trigger: click
- id: "properties.zIndex: 100"
type: Tooltip
properties:
title: zIndex 1000
zIndex: 1000
- id: "properties.overlayStyle: border: 5px solid blue"
type: Tooltip
properties:
title: Tooltip block
overlayStyle:
border: 5px solid blue
- id: "areas.content:"
type: Tooltip
properties:
title: Tooltip block
areas:
content:
blocks:
- id: test
type: Test

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/blocks-antd",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "Lowdefy Ant Design Blocks",
"homepage": "https://lowdefy.com",
@ -45,9 +45,9 @@
},
"dependencies": {
"@ant-design/icons": "4.5.0",
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/color": "3.15.0",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"@lowdefy/color": "3.16.1",
"@lowdefy/helpers": "3.16.1",
"antd": "4.4.2",
"classnames": "2.2.6",
"moment": "2.29.1",

View File

@ -86,7 +86,7 @@ const DateTimeSelector = ({
!newVal
? null
: moment
.utc(newVal.add(properties.selectGMT ? newVal.utcOffset() : 0, 'minutes'))
.utc(newVal.add(properties.selectUTC ? newVal.utcOffset() : 0, 'minutes'))
.startOf(timeUnit)
.toDate()
);
@ -95,7 +95,7 @@ const DateTimeSelector = ({
value={
!type.isDate(value)
? null
: properties.selectGMT
: properties.selectUTC
? moment.utc(value)
: moment(value)
}

View File

@ -167,10 +167,10 @@
"minimum": 1,
"description": "Minute intervals to show in the time selector."
},
"selectGMT": {
"selectUTC": {
"type": "boolean",
"default": false,
"description": "Shows the user's selection as GMT time, not time-zone based."
"description": "Shows the user's selection as UTC time, not time-zone based."
},
"showToday": {
"type": "boolean",

View File

@ -19,7 +19,7 @@ import { type } from '@lowdefy/helpers';
import { blockDefaultProps } from '@lowdefy/block-tools';
import { Descriptions } from 'antd';
const DescriptionsBlock = ({ blockId, properties }) => (
const DescriptionsBlock = ({ blockId, properties, methods }) => (
<Descriptions
id={blockId}
title={properties.title}
@ -36,17 +36,26 @@ const DescriptionsBlock = ({ blockId, properties }) => (
{item}
</Descriptions.Item>
) : (
<Descriptions.Item key={i} label={item.label} span={item.span}>
<Descriptions.Item
key={i}
label={item.label}
span={item.span}
className={`${methods.makeCssClass([{ whiteSpace: 'pre-wrap' }, item.style])}`}
>
{item.value}
</Descriptions.Item>
)
)
: type.isObject(properties.items) &&
Object.keys(properties.items).map((key, i) => (
<Descriptions.Item key={i} label={key}>
<Descriptions.Item
key={i}
label={key}
className={`${methods.makeCssClass({ whiteSpace: 'pre-wrap' })}`}
>
{type.isPrimitive(properties.items[key])
? `${properties.items[key]}`
: `${JSON.stringify(properties.items[key])}`}
? properties.items[key]
: JSON.stringify(properties.items[key])}
</Descriptions.Item>
))}
</Descriptions>

View File

@ -75,6 +75,13 @@
"span": {
"type": "integer",
"description": "Number of columns for this item to span."
},
"style": {
"type": "object",
"description": "Css style object to applied to item.",
"docs": {
"displayType": "yaml"
}
}
}
}

View File

@ -74,6 +74,28 @@
}
}
}
},
"events": {
"type": "object",
"additionalProperties": false,
"properties": {
"onEnter": {
"type": "array",
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
}
}
}
}
}

View File

@ -166,6 +166,26 @@
"type": "object",
"additionalProperties": false,
"properties": {
"onBreakpoint": {
"type": "array",
"description": "Trigger actions when sider breakpoint id crossed."
},
"onEnter": {
"type": "array",
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
},
"onSiderClose": {
"type": "array",
"description": "Trigger actions when sider is closed."
@ -173,10 +193,6 @@
"onSiderOpen": {
"type": "array",
"description": "Trigger actions when sider is opened."
},
"onBreakpoint": {
"type": "array",
"description": "Trigger actions when sider breakpoint id crossed."
}
}
}

View File

@ -166,6 +166,25 @@
"type": "object",
"additionalProperties": false,
"properties": {
"onBreakpoint": {
"type": "array"
},
"onEnter": {
"type": "array",
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
},
"onSiderClose": {
"type": "array",
"description": "Trigger actions when sider is closed."
@ -173,9 +192,6 @@
"onSiderOpen": {
"type": "array",
"description": "Trigger actions when sider is opened."
},
"onBreakpoint": {
"type": "array"
}
}
}

View File

@ -122,15 +122,15 @@ const PageHeaderMenu = ({
? '/public/logo-light-theme.png'
: '/public/logo-dark-theme.png')
}
srcset={
(properties.logo && (properties.logo.srcset || properties.logo.src)) ||
srcSet={
(properties.logo && (properties.logo.srcSet || properties.logo.src)) ||
(get(properties, 'header.theme') === 'light'
? '/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 768w'
: '/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w')
? '/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 577w'
: '/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w')
}
sizes={
(properties.logo && properties.logo.sizes) ||
'(max-width: 767px) 40px, 768px'
'(max-width: 576px) 40px, 577px'
}
alt={(properties.logo && properties.logo.alt) || 'Lowdefy'}
className={methods.makeCssClass([
@ -138,7 +138,7 @@ const PageHeaderMenu = ({
width: 130,
sm: {
width:
properties.logo && properties.logo.src && !properties.logo.srcset
properties.logo && properties.logo.src && !properties.logo.srcSet
? 130
: 40,
},

View File

@ -34,9 +34,9 @@
"type": "string",
"description": "Header logo source url."
},
"srcset": {
"srcSet": {
"type": "string",
"description": "Header logo srcset for logo img element."
"description": "Header logo srcSet for logo img element."
},
"size": {
"type": "string",
@ -210,33 +210,49 @@
"type": "object",
"additionalProperties": false,
"properties": {
"onToggleDrawer": {
"onBreadcrumbClick": {
"type": "array",
"description": "Trigger action when mobile menu drawer is toggled."
"description": "Trigger action when a breadcrumb item is clicked."
},
"onClose": {
"type": "array",
"description": "Trigger action when mobile menu is closed."
},
"onOpen": {
"onEnter": {
"type": "array",
"description": "Trigger action when mobile menu is open."
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onMenuItemSelect": {
"onEnterAsync": {
"type": "array",
"description": "Trigger action when menu item is selected."
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
},
"onMenuItemClick": {
"type": "array",
"description": "Trigger action when menu item is clicked."
},
"onMenuItemSelect": {
"type": "array",
"description": "Trigger action when menu item is selected."
},
"onOpen": {
"type": "array",
"description": "Trigger action when mobile menu is open."
},
"onToggleDrawer": {
"type": "array",
"description": "Trigger action when mobile menu drawer is toggled."
},
"onToggleMenuGroup": {
"type": "array",
"description": "Trigger action when mobile menu group is opened."
},
"onBreadcrumbClick": {
"type": "array",
"description": "Trigger action when a breadcrumb item is clicked."
}
}
}

View File

@ -166,6 +166,26 @@
"type": "object",
"additionalProperties": false,
"properties": {
"onBreakpoint": {
"type": "array",
"description": "Trigger actions when sider breakpoint id crossed."
},
"onEnter": {
"type": "array",
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
},
"onSiderClose": {
"type": "array",
"description": "Trigger actions when sider is closed."
@ -173,10 +193,6 @@
"onSiderOpen": {
"type": "array",
"description": "Trigger actions when sider is opened."
},
"onBreakpoint": {
"type": "array",
"description": "Trigger actions when sider breakpoint id crossed."
}
}
}

View File

@ -168,15 +168,15 @@ const PageSiderMenu = ({
? '/public/logo-light-theme.png'
: '/public/logo-dark-theme.png')
}
srcset={
(properties.logo && (properties.logo.srcset || properties.logo.src)) ||
srcSet={
(properties.logo && (properties.logo.srcSet || properties.logo.src)) ||
(get(properties, 'header.theme') === 'light'
? '/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 768w'
: '/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w')
? '/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 577w'
: '/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w')
}
sizes={
(properties.logo && properties.logo.sizes) ||
'(max-width: 767px) 40px, 768px'
'(max-width: 576px) 40px, 577px'
}
alt={(properties.logo && properties.logo.alt) || 'Lowdefy'}
className={methods.makeCssClass([
@ -184,7 +184,7 @@ const PageSiderMenu = ({
width: 130,
sm: {
width:
properties.logo && properties.logo.src && !properties.logo.srcset
properties.logo && properties.logo.src && !properties.logo.srcSet
? 130
: 40,
},

View File

@ -44,9 +44,9 @@
"type": "string",
"description": "Header logo source url."
},
"srcset": {
"srcSet": {
"type": "string",
"description": "Header logo srcset for logo img element."
"description": "Header logo srcSet for logo img element."
},
"size": {
"type": "string",
@ -291,17 +291,33 @@
"type": "object",
"additionalProperties": false,
"properties": {
"onToggleDrawer": {
"onBreadcrumbClick": {
"type": "array",
"description": "Trigger action when mobile menu drawer is toggled."
"description": "Trigger action when a breadcrumb item is clicked."
},
"onChangeToggleSiderAffix": {
"type": "array",
"description": "Trigger action when sider collapse button affix triggers a onChange event."
},
"onClose": {
"type": "array",
"description": "Trigger action when menu is closed."
},
"onOpen": {
"onEnter": {
"type": "array",
"description": "Trigger action when menu is open."
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
},
"onMenuItemSelect": {
"type": "array",
@ -311,17 +327,17 @@
"type": "array",
"description": "Trigger action when menu item is clicked."
},
"onOpen": {
"type": "array",
"description": "Trigger action when menu is open."
},
"onToggleDrawer": {
"type": "array",
"description": "Trigger action when mobile menu drawer is toggled."
},
"onToggleMenuGroup": {
"type": "array",
"description": "Trigger action when mobile menu group is opened."
},
"onBreadcrumbClick": {
"type": "array",
"description": "Trigger action when a breadcrumb item is clicked."
},
"onChangeToggleSiderAffix": {
"type": "array",
"description": "Trigger action when sider collapse button affix triggers a onChange event."
}
}
}

View File

@ -83,22 +83,22 @@
"description": "Area key for the extra area blocks."
}
}
}
},
"events": {
"type": "object",
"properties": {
"onChange": {
"type": "array",
"description": "Trigger action on tab change."
},
"onTabScroll": {
"type": "array",
"description": "Trigger action on tab scroll."
},
"onTabClick": {
"type": "array",
"description": "Trigger action on tab click."
},
"events": {
"type": "object",
"properties": {
"onChange": {
"type": "array",
"description": "Trigger action on tab change."
},
"onTabScroll": {
"type": "array",
"description": "Trigger action on tab scroll."
},
"onTabClick": {
"type": "array",
"description": "Trigger action on tab click."
}
}
}
}

View File

@ -0,0 +1,47 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { Tooltip } from 'antd';
import { blockDefaultProps } from '@lowdefy/block-tools';
const TooltipBlock = ({ blockId, content, properties, methods }) => (
<Tooltip
id={blockId}
title={properties.title}
overlayStyle={methods.makeCssClass(properties.overlayStyle, { styleObjectOnly: true })}
arrowPointAtCenter={properties.arrowPointAtCenter}
autoAdjustOverflow={properties.autoAdjustOverflow}
color={properties.color}
defaultVisible={properties.defaultVisible}
destroyTooltipOnHide={properties.destroyTooltipOnHide}
mouseEnterDelay={properties.mouseEnterDelay}
mouseLeaveDelay={properties.mouseLeaveDelay}
placement={properties.placement}
trigger={properties.trigger || 'hover'}
zIndex={properties.zIndex}
onVisibleChange={() => methods.triggerEvent({ name: 'onVisibleChange' })}
>
{content.content && content.content()}
{
'' // required by antd to wrap element in span tag.
}
</Tooltip>
);
TooltipBlock.defaultProps = blockDefaultProps;
export default TooltipBlock;

View File

@ -0,0 +1,86 @@
{
"category": "container",
"loading": {
"type": "Skeleton",
"properties": {
"height": 80
}
},
"schema": {
"properties": {
"type": "object",
"additionalProperties": false,
"properties": {
"arrowPointAtCenter": {
"type": "boolean",
"default": false,
"description": "Whether the arrow is pointed at the center of target."
},
"autoAdjustOverflow": {
"type": "boolean",
"default": true,
"description": "Whether to adjust popup placement automatically when popup is off screen."
},
"overlayStyle": {
"type": "object",
"description": "Style of the tooltip card.",
"docs": {
"displayType": "yaml"
}
},
"color": {
"type": "string",
"description": "The background color.",
"docs": {
"displayType": "color"
}
},
"defaultVisible": {
"type": "boolean",
"default": false,
"description": "Whether the floating tooltip card is visible by default."
},
"mouseEnterDelay": {
"type": "number",
"default": 0.1,
"description": "Delay in seconds, before tooltip is shown on mouse enter."
},
"mouseLeaveDelay": {
"type": "number",
"default": 0.1,
"description": "Delay in seconds, before tooltip is shown on mouse enter."
},
"placement": {
"type": "string",
"enum": ["top", "left", "right", "bottom", "topLeft", "topRight", "bottomLeft", "bottomRight", "leftTop", "leftBottom", "rightTop", "rightBottom"],
"default": "top",
"description": "The position of the tooltip relative to the target."
},
"trigger": {
"type": "string",
"enum": ["hover", "focus", "click"],
"default": "hover",
"description": "Tooltip trigger mode."
},
"title": {
"type": "string",
"description": "Title to show in the title area. Overwritten by blocks in the title content area."
},
"zIndex": {
"type": "integer",
"description": "The z-index of the Tooltip."
}
}
},
"events": {
"type": "object",
"additionalProperties": false,
"properties": {
"onVisibleChange": {
"type": "array",
"description": "Trigger action when visibility of the tooltip card is changed."
}
}
}
}
}

View File

@ -35,7 +35,7 @@ const disabledDate = (disabledDates = {}) => {
.filter((range) => range !== null);
return (currentDate) => {
const utcCurrentData = currentDate.utc();
const utcCurrentData = currentDate.clone().utc();
if (min && utcCurrentData.isBefore(min)) return true;
if (max && utcCurrentData.isAfter(max)) return true;
let match = dates.find((date) => date.isSame(utcCurrentData.startOf('day')));

View File

@ -75,6 +75,7 @@ import TextArea from './blocks/TextArea/TextArea';
import TextInput from './blocks/TextInput/TextInput';
import Title from './blocks/Title/Title';
import TitleInput from './blocks/TitleInput/TitleInput';
import Tooltip from './blocks/Tooltip/Tooltip';
import WeekSelector from './blocks/WeekSelector/WeekSelector';
export {
@ -139,6 +140,7 @@ export {
TextInput,
Title,
TitleInput,
Tooltip,
WeekSelector,
};
export default {
@ -203,5 +205,6 @@ export default {
TextInput,
Title,
TitleInput,
Tooltip,
WeekSelector,
};

View File

@ -0,0 +1,38 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { runMockRenderTests } from '@lowdefy/block-tools';
import Enzyme, { mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { Tooltip } from 'antd';
Enzyme.configure({ adapter: new Adapter() });
import TooltipBlock from '../src/blocks/Tooltip/Tooltip';
import examples from '../demo/examples/Tooltip.yaml';
import meta from '../src/blocks/Tooltip/Tooltip.json';
jest.mock('antd/lib/tooltip', () => {
return jest.fn(() => 'mocked');
});
const mocks = [
{
name: 'default',
fn: Tooltip,
},
];
runMockRenderTests({ examples, Block: TooltipBlock, meta, mocks, enzyme: { mount } });

View File

@ -0,0 +1,39 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { runBlockSchemaTests, runRenderTests } from '@lowdefy/block-tools';
import Tooltip from '../src/blocks/Tooltip/Tooltip';
import examples from '../demo/examples/Tooltip.yaml';
import meta from '../src/blocks/Tooltip/Tooltip.json';
jest.mock('@lowdefy/block-tools', () => {
const originalModule = jest.requireActual('@lowdefy/block-tools');
return {
...originalModule,
blockDefaultProps: {
...originalModule.blockDefaultProps,
methods: {
...originalModule.blockDefaultProps.methods,
makeCssClass: jest.fn((style, op) => JSON.stringify({ style, options: op })),
},
},
};
});
// FIX Jest: Error: Uncaught [TypeError: parentInstance.children.indexOf is not a function]
// runRenderTests({ examples, Block: Tooltip, meta });
runBlockSchemaTests({ examples, meta });

View File

@ -620,7 +620,7 @@ Array [
]
`;
exports[`Mock render - properties.selectGMT: true - value[0] - default 1`] = `
exports[`Mock render - properties.selectUTC: true - value[0] - default 1`] = `
Array [
Array [
Object {
@ -631,7 +631,7 @@ Array [
"disabledDate": [Function],
"format": "YYYY-MM-DD HH:mm",
"getPopupContainer": [Function],
"id": "properties.selectGMT: true_input",
"id": "properties.selectUTC: true_input",
"onChange": [Function],
"placeholder": "Select Date & Time",
"showNow": undefined,

View File

@ -1283,10 +1283,10 @@ exports[`Render properties.secondStep - value[0] 1`] = `
</div>
`;
exports[`Render properties.selectGMT: true - value[0] 1`] = `
exports[`Render properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -1295,10 +1295,10 @@ exports[`Render properties.selectGMT: true - value[0] 1`] = `
>
<label
className="{\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -1315,7 +1315,7 @@ exports[`Render properties.selectGMT: true - value[0] 1`] = `
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -1326,7 +1326,7 @@ exports[`Render properties.selectGMT: true - value[0] 1`] = `
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -2975,10 +2975,10 @@ exports[`Render required = true properties.secondStep - value[0] 1`] = `
</div>
`;
exports[`Render required = true properties.selectGMT: true - value[0] 1`] = `
exports[`Render required = true properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -2987,10 +2987,10 @@ exports[`Render required = true properties.selectGMT: true - value[0] 1`] = `
>
<label
className="ant-form-item-required {\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -3007,7 +3007,7 @@ exports[`Render required = true properties.selectGMT: true - value[0] 1`] = `
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -3018,7 +3018,7 @@ exports[`Render required = true properties.selectGMT: true - value[0] 1`] = `
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -5222,10 +5222,10 @@ exports[`Render validation.status = error properties.secondStep - value[0] 1`] =
</div>
`;
exports[`Render validation.status = error properties.selectGMT: true - value[0] 1`] = `
exports[`Render validation.status = error properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item ant-form-item-has-feedback ant-form-item-has-error {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -5234,10 +5234,10 @@ exports[`Render validation.status = error properties.selectGMT: true - value[0]
>
<label
className="{\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -5254,7 +5254,7 @@ exports[`Render validation.status = error properties.selectGMT: true - value[0]
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -5265,7 +5265,7 @@ exports[`Render validation.status = error properties.selectGMT: true - value[0]
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -7082,10 +7082,10 @@ exports[`Render validation.status = null properties.secondStep - value[0] 1`] =
</div>
`;
exports[`Render validation.status = null properties.selectGMT: true - value[0] 1`] = `
exports[`Render validation.status = null properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -7094,10 +7094,10 @@ exports[`Render validation.status = null properties.selectGMT: true - value[0] 1
>
<label
className="{\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -7114,7 +7114,7 @@ exports[`Render validation.status = null properties.selectGMT: true - value[0] 1
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -7125,7 +7125,7 @@ exports[`Render validation.status = null properties.selectGMT: true - value[0] 1
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -9234,10 +9234,10 @@ exports[`Render validation.status = success properties.secondStep - value[0] 1`]
</div>
`;
exports[`Render validation.status = success properties.selectGMT: true - value[0] 1`] = `
exports[`Render validation.status = success properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item ant-form-item-has-feedback ant-form-item-has-success {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -9246,10 +9246,10 @@ exports[`Render validation.status = success properties.selectGMT: true - value[0
>
<label
className="{\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -9266,7 +9266,7 @@ exports[`Render validation.status = success properties.selectGMT: true - value[0
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -9277,7 +9277,7 @@ exports[`Render validation.status = success properties.selectGMT: true - value[0
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -11619,10 +11619,10 @@ exports[`Render validation.status = warning properties.secondStep - value[0] 1`]
</div>
`;
exports[`Render validation.status = warning properties.selectGMT: true - value[0] 1`] = `
exports[`Render validation.status = warning properties.selectUTC: true - value[0] 1`] = `
<div
className="ant-row ant-form-item ant-form-item-has-feedback ant-form-item-has-warning {\\"style\\":{\\"marginBottom\\":0}}"
id="properties.selectGMT: true"
id="properties.selectUTC: true"
style={Object {}}
>
<div
@ -11631,10 +11631,10 @@ exports[`Render validation.status = warning properties.selectGMT: true - value[0
>
<label
className="{\\"style\\":[{\\"height\\":\\"fit-content !important\\",\\"minHeight\\":32},null]}"
htmlFor="properties.selectGMT: true_input"
title="properties.selectGMT: true"
htmlFor="properties.selectUTC: true_input"
title="properties.selectUTC: true"
>
properties.selectGMT: true
properties.selectUTC: true
</label>
</div>
<div
@ -11651,7 +11651,7 @@ exports[`Render validation.status = warning properties.selectGMT: true - value[0
className="{\\"style\\":{\\"width\\":\\"100%\\"}}"
>
<div
id="properties.selectGMT: true_popup"
id="properties.selectUTC: true_popup"
/>
<div
className="ant-picker {\\"style\\":[{\\"width\\":\\"100%\\"},null]}"
@ -11662,7 +11662,7 @@ exports[`Render validation.status = warning properties.selectGMT: true - value[0
>
<input
autoComplete="off"
id="properties.selectGMT: true_input"
id="properties.selectUTC: true_input"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
@ -12276,9 +12276,9 @@ exports[`Test Schema properties.secondStep 1`] = `true`;
exports[`Test Schema properties.secondStep 2`] = `null`;
exports[`Test Schema properties.selectGMT: true 1`] = `true`;
exports[`Test Schema properties.selectUTC: true 1`] = `true`;
exports[`Test Schema properties.selectGMT: true 2`] = `null`;
exports[`Test Schema properties.selectUTC: true 2`] = `null`;
exports[`Test Schema properties.showNow: false 1`] = `true`;

View File

@ -18,7 +18,7 @@ Array [
]
`;
exports[`Mock render - default - value[0] - default 2`] = `
exports[`Mock render - default title - value[0] - default 1`] = `
Array [
Array [
Object {
@ -26,7 +26,7 @@ Array [
"children": false,
"colon": undefined,
"column": undefined,
"id": "default",
"id": "default title",
"layout": undefined,
"size": undefined,
"title": "Descriptions title",
@ -43,16 +43,19 @@ Array [
"bordered": true,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -77,16 +80,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -111,16 +117,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -145,18 +154,21 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
label="field_one"
span={1}
>
1
</mockConstructor>,
<mockConstructor
className="{\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
label="field_two"
span={1}
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
label="field_three"
span={2}
>
@ -175,40 +187,34 @@ Array [
]
`;
exports[`Mock render - properties.items-list-primitive - value[0] - default 1`] = `
exports[`Mock render - properties.items-list with new lines - value[0] - default 1`] = `
Array [
Array [
Object {
"bordered": undefined,
"children": Array [
<mockConstructor
label={1}
className="{\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
label="field_one"
span={1}
>
1
description field with
new line helps
make better content.
</mockConstructor>,
<mockConstructor
label={2}
span={2}
className="{\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
label="one \\\\n two;"
span={1}
>
2
</mockConstructor>,
<mockConstructor
label={3}
span={3}
>
3
</mockConstructor>,
<mockConstructor
label={4}
span={4}
>
4
description field with
new line helps
make better content.
</mockConstructor>,
],
"colon": undefined,
"column": undefined,
"id": "properties.items-list-primitive",
"column": 2,
"id": "properties.items-list with new lines",
"layout": undefined,
"size": undefined,
"title": "Title",
@ -225,16 +231,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -252,6 +261,41 @@ Array [
]
`;
exports[`Mock render - properties.items-object with new lines - value[0] - default 1`] = `
Array [
Array [
Object {
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
description one field with
new line helps
make better content.
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="one \\\\n two;"
>
description two field with
new line helps
make better content.
</mockConstructor>,
],
"colon": undefined,
"column": 2,
"id": "properties.items-object with new lines",
"layout": undefined,
"size": undefined,
"title": "Title",
},
Object {},
],
]
`;
exports[`Mock render - properties.items-object-object - value[0] - default 1`] = `
Array [
Array [
@ -259,16 +303,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="one"
>
{"two":3}
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="four"
>
{"five":"six"}
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="seven"
>
{"eight":[9,"ten"]}
@ -293,16 +340,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -327,16 +377,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -361,16 +414,19 @@ Array [
"bordered": undefined,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
@ -395,31 +451,37 @@ Array [
"bordered": true,
"children": Array [
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_one"
>
value one
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_two"
>
2
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_three"
>
value three
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_4"
>
value 4
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_5"
>
5
</mockConstructor>,
<mockConstructor
className="{\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
label="field_6"
>
value 6

View File

@ -14,7 +14,7 @@ exports[`Render default - value[0] 1`] = `
</div>
`;
exports[`Render default - value[0] 2`] = `
exports[`Render default title - value[0] 1`] = `
<div
className="ant-descriptions"
>
@ -46,37 +46,37 @@ exports[`Render properties.bordered: true - value[0] 1`] = `
className="ant-descriptions-row"
>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_one
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value one
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_two
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
2
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_three
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value three
@ -101,7 +101,7 @@ exports[`Render properties.colon: false - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -116,7 +116,7 @@ exports[`Render properties.colon: false - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -131,7 +131,7 @@ exports[`Render properties.colon: false - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -165,7 +165,7 @@ exports[`Render properties.column: 2 - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -180,7 +180,7 @@ exports[`Render properties.column: 2 - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -199,7 +199,7 @@ exports[`Render properties.column: 2 - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={2}
>
<span
@ -238,7 +238,7 @@ exports[`Render properties.items-list - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
colSpan={1}
>
<span
@ -253,7 +253,7 @@ exports[`Render properties.items-list - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
colSpan={1}
>
<span
@ -272,7 +272,7 @@ exports[`Render properties.items-list - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
colSpan={2}
>
<span
@ -293,7 +293,7 @@ exports[`Render properties.items-list - value[0] 1`] = `
</div>
`;
exports[`Render properties.items-list-primitive - value[0] 1`] = `
exports[`Render properties.items-list with new lines - value[0] 1`] = `
<div
className="ant-descriptions"
>
@ -311,71 +311,37 @@ exports[`Render properties.items-list-primitive - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
>
1
field_one
</span>
<span
className="ant-descriptions-item-content"
>
1
description field with
new line helps
make better content.
</span>
</td>
<td
className="ant-descriptions-item"
colSpan={2}
className="ant-descriptions-item {\\"style\\":[{\\"whiteSpace\\":\\"pre-wrap\\"},null]}"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
>
2
one \\n two;
</span>
<span
className="ant-descriptions-item-content"
>
2
</span>
</td>
</tr>
<tr
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
colSpan={3}
>
<span
className="ant-descriptions-item-label"
>
3
</span>
<span
className="ant-descriptions-item-content"
>
3
</span>
</td>
</tr>
<tr
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
colSpan={3}
>
<span
className="ant-descriptions-item-label"
>
4
</span>
<span
className="ant-descriptions-item-content"
>
4
description field with
new line helps
make better content.
</span>
</td>
</tr>
@ -403,7 +369,7 @@ exports[`Render properties.items-object - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -418,7 +384,7 @@ exports[`Render properties.items-object - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -433,7 +399,7 @@ exports[`Render properties.items-object - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -454,6 +420,64 @@ exports[`Render properties.items-object - value[0] 1`] = `
</div>
`;
exports[`Render properties.items-object with new lines - value[0] 1`] = `
<div
className="ant-descriptions"
>
<div
className="ant-descriptions-title"
>
Title
</div>
<div
className="ant-descriptions-view"
>
<table>
<tbody>
<tr
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
>
field_one
</span>
<span
className="ant-descriptions-item-content"
>
description one field with
new line helps
make better content.
</span>
</td>
<td
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
>
one \\n two;
</span>
<span
className="ant-descriptions-item-content"
>
description two field with
new line helps
make better content.
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`Render properties.items-object-object - value[0] 1`] = `
<div
className="ant-descriptions"
@ -472,7 +496,7 @@ exports[`Render properties.items-object-object - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -487,7 +511,7 @@ exports[`Render properties.items-object-object - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -502,7 +526,7 @@ exports[`Render properties.items-object-object - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -536,7 +560,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
className="ant-descriptions-row"
>
<th
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -546,7 +570,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
</span>
</th>
<th
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -556,7 +580,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
</span>
</th>
<th
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -570,7 +594,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -580,7 +604,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -590,7 +614,7 @@ exports[`Render properties.layout: vertical - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -619,7 +643,7 @@ exports[`Render properties.size: default - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -634,7 +658,7 @@ exports[`Render properties.size: default - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -649,7 +673,7 @@ exports[`Render properties.size: default - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -683,7 +707,7 @@ exports[`Render properties.size: small - value[0] 1`] = `
className="ant-descriptions-row"
>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -698,7 +722,7 @@ exports[`Render properties.size: small - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -713,7 +737,7 @@ exports[`Render properties.size: small - value[0] 1`] = `
</span>
</td>
<td
className="ant-descriptions-item"
className="ant-descriptions-item {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
<span
@ -747,37 +771,37 @@ exports[`Render properties.size: small, properties.bordered: true - value[0] 1`]
className="ant-descriptions-row"
>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_one
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value one
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_two
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
2
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_three
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value three
@ -787,37 +811,37 @@ exports[`Render properties.size: small, properties.bordered: true - value[0] 1`]
className="ant-descriptions-row"
>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_4
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value 4
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_5
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
5
</td>
<th
className="ant-descriptions-item-label"
className="ant-descriptions-item-label {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
field_6
</th>
<td
className="ant-descriptions-item-content"
className="ant-descriptions-item-content {\\"style\\":{\\"whiteSpace\\":\\"pre-wrap\\"}}"
colSpan={1}
>
value 6
@ -833,9 +857,9 @@ exports[`Test Schema default 1`] = `true`;
exports[`Test Schema default 2`] = `null`;
exports[`Test Schema default 3`] = `true`;
exports[`Test Schema default title 1`] = `true`;
exports[`Test Schema default 4`] = `null`;
exports[`Test Schema default title 2`] = `null`;
exports[`Test Schema properties.bordered: true 1`] = `true`;
@ -853,71 +877,18 @@ exports[`Test Schema properties.items-list 1`] = `true`;
exports[`Test Schema properties.items-list 2`] = `null`;
exports[`Test Schema properties.items-list-primitive 1`] = `false`;
exports[`Test Schema properties.items-list with new lines 1`] = `true`;
exports[`Test Schema properties.items-list-primitive 2`] = `
Array [
Object {
"dataPath": "/properties/items/0",
"keyword": "type",
"message": "should be object",
"params": Object {
"type": "object",
},
"schemaPath": "#/properties/properties/properties/items/oneOf/0/items/type",
},
Object {
"dataPath": "/properties/items/1",
"keyword": "type",
"message": "should be object",
"params": Object {
"type": "object",
},
"schemaPath": "#/properties/properties/properties/items/oneOf/0/items/type",
},
Object {
"dataPath": "/properties/items/2",
"keyword": "type",
"message": "should be object",
"params": Object {
"type": "object",
},
"schemaPath": "#/properties/properties/properties/items/oneOf/0/items/type",
},
Object {
"dataPath": "/properties/items/3",
"keyword": "type",
"message": "should be object",
"params": Object {
"type": "object",
},
"schemaPath": "#/properties/properties/properties/items/oneOf/0/items/type",
},
Object {
"dataPath": "/properties/items",
"keyword": "type",
"message": "should be object",
"params": Object {
"type": "object",
},
"schemaPath": "#/properties/properties/properties/items/oneOf/1/type",
},
Object {
"dataPath": "/properties/items",
"keyword": "oneOf",
"message": "should match exactly one schema in oneOf",
"params": Object {
"passingSchemas": null,
},
"schemaPath": "#/properties/properties/properties/items/oneOf",
},
]
`;
exports[`Test Schema properties.items-list with new lines 2`] = `null`;
exports[`Test Schema properties.items-object 1`] = `true`;
exports[`Test Schema properties.items-object 2`] = `null`;
exports[`Test Schema properties.items-object with new lines 1`] = `true`;
exports[`Test Schema properties.items-object with new lines 2`] = `null`;
exports[`Test Schema properties.items-object-object 1`] = `true`;
exports[`Test Schema properties.items-object-object 2`] = `null`;

View File

@ -1079,13 +1079,13 @@ Array [
]
`;
exports[`Mock render - properties.logo.srcset - value[0] - default 1`] = `
exports[`Mock render - properties.logo.srcSet - value[0] - default 1`] = `
Array [
Array [
Object {
"children": <React.Fragment>
<HeaderBlock
blockId="properties.logo.srcset_header"
blockId="properties.logo.srcSet_header"
content={
Object {
"content": [Function],
@ -1131,7 +1131,7 @@ Array [
}
/>
<ContentBlock
blockId="properties.logo.srcset_content"
blockId="properties.logo.srcSet_content"
content={
Object {
"content": [Function],
@ -1176,7 +1176,7 @@ Array [
/>
</React.Fragment>,
"className": "css-vooagt",
"id": "properties.logo.srcset",
"id": "properties.logo.srcSet",
},
Object {},
],

View File

@ -40,9 +40,9 @@ exports[`Test Schema properties.logo.src 1`] = `true`;
exports[`Test Schema properties.logo.src 2`] = `null`;
exports[`Test Schema properties.logo.srcset 1`] = `true`;
exports[`Test Schema properties.logo.srcSet 1`] = `true`;
exports[`Test Schema properties.logo.srcset 2`] = `null`;
exports[`Test Schema properties.logo.srcSet 2`] = `null`;
exports[`Test Schema properties.logo.style 1`] = `true`;

View File

@ -903,13 +903,13 @@ Array [
]
`;
exports[`Mock render - properties.logo.srcset - value[0] - default 1`] = `
exports[`Mock render - properties.logo.srcSet - value[0] - default 1`] = `
Array [
Array [
Object {
"children": <React.Fragment>
<HeaderBlock
blockId="properties.logo.srcset_header"
blockId="properties.logo.srcSet_header"
content={
Object {
"content": [Function],
@ -956,7 +956,7 @@ Array [
}
/>
<LayoutBlock
blockId="properties.logo.srcset_layout"
blockId="properties.logo.srcSet_layout"
content={
Object {
"content": [Function],
@ -986,7 +986,7 @@ Array [
/>
</React.Fragment>,
"className": "css-vooagt",
"id": "properties.logo.srcset",
"id": "properties.logo.srcSet",
},
Object {},
],

View File

@ -56,9 +56,9 @@ exports[`Render default - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -231,9 +231,9 @@ exports[`Render properties.breadcrumb.list - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -440,9 +440,9 @@ exports[`Render properties.content.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -615,9 +615,9 @@ exports[`Render properties.footer.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -805,9 +805,9 @@ exports[`Render properties.header.color - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -1077,9 +1077,9 @@ exports[`Render properties.header.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -1252,9 +1252,9 @@ exports[`Render properties.header.theme: light - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-light-theme.png"
srcset="/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 768w"
srcSet="/public/logo-square-light-theme.png 40w, /public/logo-light-theme.png 577w"
/>
</a>
</header>
@ -1514,9 +1514,9 @@ exports[`Render properties.logo.alt - value[0] 1`] = `
<img
alt="Header logo alt text"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -1776,9 +1776,9 @@ exports[`Render properties.logo.size - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="(max-width: 767px) 40px, 768px"
srcSet="(max-width: 767px) 40px, 768px"
/>
</a>
</header>
@ -2038,9 +2038,9 @@ exports[`Render properties.logo.src - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":130},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="https://lowdefy.com/logos/name_250.png"
srcset="https://lowdefy.com/logos/name_250.png"
srcSet="https://lowdefy.com/logos/name_250.png"
/>
</a>
</header>
@ -2244,14 +2244,14 @@ exports[`Render properties.logo.src - value[0] 1`] = `
</section>
`;
exports[`Render properties.logo.srcset - value[0] 1`] = `
exports[`Render properties.logo.srcSet - value[0] 1`] = `
<section
className="ant-layout {\\"style\\":{\\"minHeight\\":\\"100vh\\"}}"
id="properties.logo.srcset"
id="properties.logo.srcSet"
>
<header
className="ant-layout-header {\\"style\\":[{\\"backgroundColor\\":false},null,{\\"display\\":\\"flex\\",\\"alignItems\\":\\"center\\",\\"padding\\":\\"0 46px\\",\\"sm\\":{\\"padding\\":\\"0 15px\\"},\\"md\\":{\\"padding\\":\\"0 30px\\"},\\"lg\\":{\\"padding\\":\\"0 46px\\"},\\"flexDirection\\":\\"row-reverse\\"}]} hide-on-print"
id="properties.logo.srcset_header"
id="properties.logo.srcSet_header"
>
<div
className="{\\"style\\":{\\"alignItems\\":\\"center\\",\\"flex\\":\\"1 1 auto\\",\\"display\\":\\"flex\\",\\"justifyContent\\":\\"flex-end\\"}}"
@ -2260,18 +2260,18 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
className="{\\"style\\":[{\\"display\\":\\"block\\",\\"lg\\":{\\"display\\":\\"none\\"}},{\\"paddingLeft\\":\\"1rem\\"}]}"
>
<div
id="properties.logo.srcset_mobile_menu"
id="properties.logo.srcSet_mobile_menu"
>
<button
className="ant-btn {\\"style\\":[{},null]} ant-btn-primary ant-btn-icon-only"
id="properties.logo.srcset_mobile_menu_button"
id="properties.logo.srcSet_mobile_menu_button"
onClick={[Function]}
type="button"
>
<span
aria-label="loading-3-quarters"
className="anticon anticon-loading-3-quarters anticon-spin {\\"style\\":[{},null]}"
id="properties.logo.srcset_mobile_menu_button_icon"
id="properties.logo.srcSet_mobile_menu_button_icon"
required={false}
role="img"
>
@ -2300,19 +2300,19 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w"
srcSet="https://lowdefy.com/logos/name_250.png 250w, https://lowdefy.com/logos/name_450.png 450w"
/>
</a>
</header>
<section
className="ant-layout ant-layout-has-sider {}"
id="properties.logo.srcset_layout"
id="properties.logo.srcSet_layout"
>
<aside
className="{\\"style\\":[{\\"overflow\\":\\"auto\\"},{\\"display\\":\\"none\\",\\"lg\\":{\\"display\\":\\"block\\"}}]} hide-on-print ant-layout-sider ant-layout-sider-light"
id="properties.logo.srcset_sider"
id="properties.logo.srcSet_sider"
style={
Object {
"flex": "0 0 200px",
@ -2336,7 +2336,7 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
>
<ul
className="ant-menu {\\"style\\":[{\\"lineHeight\\":\\"64px\\",\\"display\\":false},null,null,null,{\\"display\\":\\"none\\",\\"lg\\":{\\"display\\":\\"block\\"}}]} ant-menu-light ant-menu-root ant-menu-inline"
id="properties.logo.srcset_menu"
id="properties.logo.srcSet_menu"
onMouseEnter={[Function]}
onTransitionEnd={[Function]}
role="menu"
@ -2438,7 +2438,7 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
/>
<div
className="{}"
id="properties.logo.srcset_toggle_sider_affix"
id="properties.logo.srcSet_toggle_sider_affix"
>
<div
className=""
@ -2452,14 +2452,14 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
>
<button
className="ant-btn {\\"style\\":[{},null]} ant-btn-link ant-btn-icon-only ant-btn-block"
id="properties.logo.srcset_toggle_sider"
id="properties.logo.srcSet_toggle_sider"
onClick={[Function]}
type="button"
>
<span
aria-label="loading-3-quarters"
className="anticon anticon-loading-3-quarters anticon-spin {\\"style\\":[{},null]}"
id="properties.logo.srcset_toggle_sider_icon"
id="properties.logo.srcSet_toggle_sider_icon"
required={false}
role="img"
>
@ -2486,7 +2486,7 @@ exports[`Render properties.logo.srcset - value[0] 1`] = `
</aside>
<main
className="ant-layout-content {\\"style\\":{\\"padding\\":\\"0 40px 40px 40px\\",\\"sm\\":{\\"padding\\":\\"0 10px 10px 10px\\"},\\"md\\":{\\"padding\\":\\"0 20px 20px 20px\\"},\\"lg\\":{\\"padding\\":\\"0 40px 40px 40px\\"}}}"
id="properties.logo.srcset_content"
id="properties.logo.srcSet_content"
>
<div
className="{\\"style\\":{\\"padding\\":\\"20px 0\\",\\"sm\\":{\\"padding\\":\\"5px 0\\"},\\"md\\":{\\"padding\\":\\"10px 0\\"}}}"
@ -2562,9 +2562,9 @@ exports[`Render properties.logo.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},{\\"border\\":\\"5px solid blue\\"}]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -2737,9 +2737,9 @@ exports[`Render properties.menu - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -2999,9 +2999,9 @@ exports[`Render properties.menu.selectedColor - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -3261,9 +3261,9 @@ exports[`Render properties.sider.color - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -3523,9 +3523,9 @@ exports[`Render properties.sider.initialCollapsed - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -3709,9 +3709,9 @@ exports[`Render properties.sider.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -3895,9 +3895,9 @@ exports[`Render properties.sider.theme: dark - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -4070,9 +4070,9 @@ exports[`Render properties.style - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -4245,9 +4245,9 @@ exports[`Render properties.toggleSiderButton.hide - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -4431,9 +4431,9 @@ exports[`Render properties.toggleSiderButton.type - value[0] 1`] = `
<img
alt="Lowdefy"
className="{\\"style\\":[{\\"width\\":130,\\"sm\\":{\\"width\\":40},\\"md\\":{\\"width\\":130}},{\\"margin\\":\\"0 30px 0 0\\",\\"flex\\":\\"0 1 auto\\",\\"sm\\":{\\"margin\\":\\"0 10px 0 0\\"},\\"md\\":{\\"margin\\":\\"0 15px 0 0\\"}},null]}"
sizes="(max-width: 767px) 40px, 768px"
sizes="(max-width: 576px) 40px, 577px"
src="/public/logo-dark-theme.png"
srcset="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 768w"
srcSet="/public/logo-square-dark-theme.png 40w, /public/logo-dark-theme.png 577w"
/>
</a>
</header>
@ -4601,9 +4601,9 @@ exports[`Test Schema properties.logo.src 1`] = `true`;
exports[`Test Schema properties.logo.src 2`] = `null`;
exports[`Test Schema properties.logo.srcset 1`] = `true`;
exports[`Test Schema properties.logo.srcSet 1`] = `true`;
exports[`Test Schema properties.logo.srcset 2`] = `null`;
exports[`Test Schema properties.logo.srcSet 2`] = `null`;
exports[`Test Schema properties.logo.style 1`] = `true`;

View File

@ -0,0 +1,519 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Mock render - areas.content: - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "areas.content:",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "Tooltip block",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - default - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "default",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": undefined,
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.arrowPointAtCenter: true - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": true,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.arrowPointAtCenter: true",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": "topLeft",
"title": "arrowPointAtCenter true",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.autoAdjustOverflow: false - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": false,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.autoAdjustOverflow: false",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": "right",
"title": "autoAdjustOverflow false",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.autoAdjustOverflow: true - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": true,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.autoAdjustOverflow: true",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": "right",
"title": "autoAdjustOverflow true",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.color: blue - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": "blue",
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.color: blue",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "color blue",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.defaultVisible: true - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": true,
"destroyTooltipOnHide": undefined,
"id": "properties.defaultVisible: true",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "defaultVisible true",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.mouseEnterDelay: 1 - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.mouseEnterDelay: 1",
"mouseEnterDelay": 1,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "mouseEnterDelay 1",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.mouseLeaveDelay: 1 - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.mouseLeaveDelay: 1",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": 1,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "mouseLeaveDelay 1",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.overlayStyle: border: 5px solid blue - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.overlayStyle: border: 5px solid blue",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"style\\":{\\"border\\":\\"5px solid blue\\"},\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "Tooltip block",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.placement - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.placement",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": "topLeft",
"title": "placement topLeft",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.title - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.title",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "Tooltip block",
"trigger": "hover",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.trigger: click - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.trigger: click",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "trigger click",
"trigger": "click",
"zIndex": undefined,
},
Object {},
],
]
`;
exports[`Mock render - properties.zIndex: 100 - value[0] - default 1`] = `
Array [
Array [
Object {
"arrowPointAtCenter": undefined,
"autoAdjustOverflow": undefined,
"children": Array [
<div
style={
Object {
"border": "1px solid red",
"padding": 10,
}
}
>
content
</div>,
"",
],
"color": undefined,
"defaultVisible": undefined,
"destroyTooltipOnHide": undefined,
"id": "properties.zIndex: 100",
"mouseEnterDelay": undefined,
"mouseLeaveDelay": undefined,
"onVisibleChange": [Function],
"overlayStyle": "{\\"options\\":{\\"styleObjectOnly\\":true}}",
"placement": undefined,
"title": "zIndex 1000",
"trigger": "hover",
"zIndex": 1000,
},
Object {},
],
]
`;

View File

@ -0,0 +1,57 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Test Schema areas.content: 1`] = `true`;
exports[`Test Schema areas.content: 2`] = `null`;
exports[`Test Schema default 1`] = `true`;
exports[`Test Schema default 2`] = `null`;
exports[`Test Schema properties.arrowPointAtCenter: true 1`] = `true`;
exports[`Test Schema properties.arrowPointAtCenter: true 2`] = `null`;
exports[`Test Schema properties.autoAdjustOverflow: false 1`] = `true`;
exports[`Test Schema properties.autoAdjustOverflow: false 2`] = `null`;
exports[`Test Schema properties.autoAdjustOverflow: true 1`] = `true`;
exports[`Test Schema properties.autoAdjustOverflow: true 2`] = `null`;
exports[`Test Schema properties.color: blue 1`] = `true`;
exports[`Test Schema properties.color: blue 2`] = `null`;
exports[`Test Schema properties.defaultVisible: true 1`] = `true`;
exports[`Test Schema properties.defaultVisible: true 2`] = `null`;
exports[`Test Schema properties.mouseEnterDelay: 1 1`] = `true`;
exports[`Test Schema properties.mouseEnterDelay: 1 2`] = `null`;
exports[`Test Schema properties.mouseLeaveDelay: 1 1`] = `true`;
exports[`Test Schema properties.mouseLeaveDelay: 1 2`] = `null`;
exports[`Test Schema properties.overlayStyle: border: 5px solid blue 1`] = `true`;
exports[`Test Schema properties.overlayStyle: border: 5px solid blue 2`] = `null`;
exports[`Test Schema properties.placement 1`] = `true`;
exports[`Test Schema properties.placement 2`] = `null`;
exports[`Test Schema properties.title 1`] = `true`;
exports[`Test Schema properties.title 2`] = `null`;
exports[`Test Schema properties.trigger: click 1`] = `true`;
exports[`Test Schema properties.trigger: click 2`] = `null`;
exports[`Test Schema properties.zIndex: 100 1`] = `true`;
exports[`Test Schema properties.zIndex: 100 2`] = `null`;

View File

@ -1,6 +1,7 @@
const { ModuleFederationPlugin } = require('webpack').container;
const path = require('path');
const fs = require('fs');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const packageJson = require('./package.json');
@ -94,6 +95,7 @@ module.exports = {
],
},
plugins: [
new CleanWebpackPlugin(),
new ModuleFederationPlugin({
name: sanitizeName(packageJson.name),
library: { type: 'var', name: sanitizeName(packageJson.name) },

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-basic
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
### Bug Fixes
* **docs:** Document context initialization events for context blocks. ([a59bff5](https://github.com/lowdefy/lowdefy/commit/a59bff50f25b79d0468a4a6afc836f264c3263b2)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
### Features
* **blockBasic:** Add Img block. ([c850cb3](https://github.com/lowdefy/lowdefy/commit/c850cb32061cf2a4c361aecc024fe699cc06c7e0))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/blocks-basic

View File

@ -8,7 +8,7 @@
- id: properties.style
type: Html
properties:
style:
style:
background: yellow
padding: 10
html: |
@ -16,7 +16,7 @@
- id: properties.html-styled
type: Html
properties:
style:
style:
background: yellow
padding: 10
html: |
@ -49,4 +49,4 @@
</div>
<script>
alert('script tag');
</script>
</script>

View File

@ -0,0 +1,60 @@
- id: default
type: Img
- id: src
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
- id: srcset
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
srcset: https://docs.lowdefy.com/public/logo-dark-theme.png
- id: alt
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
alt: This is the alt
- id: alt
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
crossorigin: anonymous
- id: decoding
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
decoding: sync
- id: height
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
height: 30
- id: loading
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
loading: lazy
- id: sizes
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
sizes: 20px
- id: style
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
style:
border: 1px solid red
- id: width
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
height: 10
- id: onClick
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
events:
onClick:
- id: testAction
type: Text

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/blocks-basic",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "Basic html Lowdefy blocks.",
"homepage": "https://lowdefy.com",
@ -38,7 +38,7 @@
"test": "jest --coverage --config jest.config.js --no-cache"
},
"dependencies": {
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"dompurify": "2.2.6",
"react": "17.0.2",
"react-dom": "17.0.2"
@ -48,7 +48,7 @@
"@babel/core": "7.12.16",
"@babel/preset-env": "7.12.16",
"@babel/preset-react": "7.12.13",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"@wojtekmaj/enzyme-adapter-react-17": "0.6.0",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",

View File

@ -26,6 +26,22 @@
"onClick": {
"type": "array",
"description": "Trigger actions when the Context is clicked."
},
"onEnter": {
"type": "array",
"description": "Trigger actions every time a context is mounted and keep the page in loading until all actions have finished."
},
"onEnterAsync": {
"type": "array",
"description": "Trigger actions every time a context is mounted and do not keep the page in loading."
},
"onInit": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and keep the page in loading until all actions have finished."
},
"onInitAsync": {
"type": "array",
"description": "Trigger actions the first time a context is mounted and do not keep the page in loading."
}
}
}

View File

@ -0,0 +1,38 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { blockDefaultProps } from '@lowdefy/block-tools';
const ImgBlock = ({ blockId, events, properties, methods }) => {
const { style, ...allProps } = properties;
return (
<img
{...allProps}
id={blockId}
data-testid={blockId}
onClick={() => methods.triggerEvent({ name: 'onClick' })}
className={methods.makeCssClass([
{ outline: 'none', cursor: events.onClick && 'pointer' },
properties.style,
])}
/>
);
};
ImgBlock.defaultProps = blockDefaultProps;
export default ImgBlock;

View File

@ -0,0 +1,62 @@
{
"category": "display",
"loading": false,
"schema": {
"properties": {
"type": "object",
"additionalProperties": false,
"required": ["src"],
"properties": {
"src": {
"type": "string",
"description": "The image URL."
},
"alt": {
"type": "string",
"description": "Alternative text description of the image."
},
"crossorigin": {
"type": "string",
"enum": ["anonymous", "use-credentials"],
"description": "Indicates if the fetching of the image must be done using a CORS request."
},
"decoding": {
"type": "string",
"enum": ["sync", "async", "auto"],
"description": "An image decoding hint to the browser. Sync for atomic presentation with other content, async, to reduce delay in presenting other content and auto leave to browser to decide."
},
"height": {
"type": "number",
"description": "Height of the image."
},
"loading": {
"type": "string",
"enum": ["eager", "lazy"],
"description": "How the browser should load the image. Eager loads the image immediately, lazy, defers loading until the image it reaches a calculated distance from the viewport, as defined by the browser."
},
"sizes": {
"type": "string",
"description": "Indicating a set of source sizes of strings separated by commas."
},
"srcset": {
"type": "string",
"description": "Possible image sources for the user agent to use, strings separated by commas.",
"docs": {
"displayType": "text-area"
}
},
"style": {
"type": "object",
"description": "Css style object to applied to the image.",
"docs": {
"displayType": "yaml"
}
},
"width": {
"type": "number",
"description": "Width of the image."
}
}
}
}
}

View File

@ -18,8 +18,9 @@ import Box from './blocks/Box/Box';
import Context from './blocks/Context/Context';
import DangerousHtml from './blocks/DangerousHtml/DangerousHtml';
import Html from './blocks/Html/Html';
import Img from './blocks/Img/Img';
import List from './blocks/List/List';
import Span from './blocks/Span/Span';
export { Box, Context, DangerousHtml, Html, Span, List };
export default { Box, Context, DangerousHtml, Html, Span, List };
export { Box, Context, DangerousHtml, Html, Img, List, Span };
export default { Box, Context, DangerousHtml, Html, Img, List, Span };

View File

@ -0,0 +1,56 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import { mockBlock, runBlockSchemaTests, runRenderTests } from '@lowdefy/block-tools';
import { configure, mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
configure({ adapter: new Adapter() });
import { Img } from '../src';
import examples from '../demo/examples/Img.yaml';
import meta from '../src/blocks/Img/Img.json';
jest.mock('@lowdefy/block-tools', () => {
const originalModule = jest.requireActual('@lowdefy/block-tools');
return {
...originalModule,
blockDefaultProps: {
...originalModule.blockDefaultProps,
methods: {
...originalModule.blockDefaultProps.methods,
makeCssClass: jest.fn((style, op) => JSON.stringify({ style, options: op })),
},
},
};
});
runRenderTests({ examples, Block: Img, meta });
runBlockSchemaTests({ examples, meta });
const { before, methods, getProps } = mockBlock({ meta });
beforeEach(before);
test('triggerEvent onClick', () => {
const block = {
id: 'one',
type: 'Img',
};
const Shell = () => <Img {...getProps(block)} methods={methods} />;
const wrapper = mount(<Shell />);
wrapper.find('[data-testid="one"]').simulate('click');
expect(methods.triggerEvent).toHaveBeenCalledWith({ name: 'onClick' });
});

View File

@ -0,0 +1,176 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render alt - value[0] 1`] = `
<img
alt="This is the alt"
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="alt"
id="alt"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render alt - value[0] 2`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
crossorigin="anonymous"
data-testid="alt"
id="alt"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render decoding - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="decoding"
decoding="sync"
id="decoding"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render default - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="default"
id="default"
onClick={[Function]}
/>
`;
exports[`Render height - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="height"
height={30}
id="height"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render loading - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="loading"
id="loading"
loading="lazy"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render onClick - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\",\\"cursor\\":\\"pointer\\"},null]}"
data-testid="onClick"
id="onClick"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render sizes - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="sizes"
id="sizes"
onClick={[Function]}
sizes="20px"
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render src - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="src"
id="src"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render srcset - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="srcset"
id="srcset"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
srcset="https://docs.lowdefy.com/public/logo-dark-theme.png"
/>
`;
exports[`Render style - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},{\\"border\\":\\"1px solid red\\"}]}"
data-testid="style"
id="style"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Render width - value[0] 1`] = `
<img
className="{\\"style\\":[{\\"outline\\":\\"none\\"},null]}"
data-testid="width"
height={10}
id="width"
onClick={[Function]}
src="https://docs.lowdefy.com/public/logo-light-theme.png"
/>
`;
exports[`Test Schema alt 1`] = `true`;
exports[`Test Schema alt 2`] = `null`;
exports[`Test Schema alt 3`] = `true`;
exports[`Test Schema alt 4`] = `null`;
exports[`Test Schema decoding 1`] = `true`;
exports[`Test Schema decoding 2`] = `null`;
exports[`Test Schema default 1`] = `true`;
exports[`Test Schema default 2`] = `null`;
exports[`Test Schema height 1`] = `true`;
exports[`Test Schema height 2`] = `null`;
exports[`Test Schema loading 1`] = `true`;
exports[`Test Schema loading 2`] = `null`;
exports[`Test Schema onClick 1`] = `true`;
exports[`Test Schema onClick 2`] = `null`;
exports[`Test Schema sizes 1`] = `true`;
exports[`Test Schema sizes 2`] = `null`;
exports[`Test Schema src 1`] = `true`;
exports[`Test Schema src 2`] = `null`;
exports[`Test Schema srcset 1`] = `true`;
exports[`Test Schema srcset 2`] = `null`;
exports[`Test Schema style 1`] = `true`;
exports[`Test Schema style 2`] = `null`;
exports[`Test Schema width 1`] = `true`;
exports[`Test Schema width 2`] = `null`;

View File

@ -1,6 +1,7 @@
const { ModuleFederationPlugin } = require('webpack').container;
const path = require('path');
const fs = require('fs');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const packageJson = require('./package.json');
@ -68,6 +69,7 @@ module.exports = {
],
},
plugins: [
new CleanWebpackPlugin(),
new ModuleFederationPlugin({
name: sanitizeName(packageJson.name),
library: { type: 'var', name: sanitizeName(packageJson.name) },

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-color-selectors
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-color-selectors
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/blocks-color-selectors

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/blocks-color-selectors",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "A Lowdefy color selector blocks based on react-color.",
"homepage": "https://lowdefy.com",
@ -40,8 +40,8 @@
"test": "jest --coverage --config jest.config.js --no-cache"
},
"dependencies": {
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/blocks-antd": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"@lowdefy/blocks-antd": "3.16.1",
"react": "17.0.2",
"react-color": "2.19.3",
"react-dom": "17.0.2"
@ -51,7 +51,7 @@
"@babel/core": "7.12.16",
"@babel/preset-env": "7.12.16",
"@babel/preset-react": "7.12.13",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"@wojtekmaj/enzyme-adapter-react-17": "0.6.0",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",

View File

@ -1,6 +1,7 @@
const { ModuleFederationPlugin } = require('webpack').container;
const path = require('path');
const fs = require('fs');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const packageJson = require('./package.json');
@ -94,6 +95,7 @@ module.exports = {
],
},
plugins: [
new CleanWebpackPlugin(),
new ModuleFederationPlugin({
name: sanitizeName(packageJson.name),
library: { type: 'var', name: sanitizeName(packageJson.name) },

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-echarts
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-echarts
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/blocks-echarts

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/blocks-echarts",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "ECharts Blocks for Lowdefy.",
"homepage": "https://lowdefy.com",
@ -40,7 +40,7 @@
"test": "jest --coverage --config jest.config.js --no-cache"
},
"dependencies": {
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"echarts": "5.0.2",
"echarts-for-react": "3.0.1",
"react": "17.0.2",
@ -52,7 +52,7 @@
"@babel/core": "7.12.16",
"@babel/preset-env": "7.12.16",
"@babel/preset-react": "7.12.13",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",
"buffer": "6.0.3",

View File

@ -1,6 +1,7 @@
const { ModuleFederationPlugin } = require('webpack').container;
const path = require('path');
const fs = require('fs');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const packageJson = require('./package.json');
@ -68,6 +69,7 @@ module.exports = {
],
},
plugins: [
new CleanWebpackPlugin(),
new ModuleFederationPlugin({
name: sanitizeName(packageJson.name),
library: { type: 'var', name: sanitizeName(packageJson.name) },

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-markdown
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/blocks-markdown
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/blocks-markdown

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/blocks-markdown",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "Lowdefy markdown blocks.",
"homepage": "https://lowdefy.com",
@ -40,7 +40,7 @@
"test": "jest --coverage --config jest.config.js --no-cache"
},
"dependencies": {
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"dompurify": "2.2.6",
"react": "17.0.2",
"react-dom": "17.0.2",
@ -53,7 +53,7 @@
"@babel/core": "7.12.16",
"@babel/preset-env": "7.12.16",
"@babel/preset-react": "7.12.13",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"@wojtekmaj/enzyme-adapter-react-17": "0.6.0",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",

View File

@ -1,6 +1,7 @@
const { ModuleFederationPlugin } = require('webpack').container;
const fs = require('fs');
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const packageJson = require('./package.json');
@ -87,6 +88,7 @@ module.exports = {
],
},
plugins: [
new CleanWebpackPlugin(),
new ModuleFederationPlugin({
name: sanitizeName(packageJson.name),
library: { type: 'var', name: sanitizeName(packageJson.name) },

View File

@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
### Bug Fixes
* **build:** Add default locations for new blocks. ([544d1e1](https://github.com/lowdefy/lowdefy/commit/544d1e1d8459fb03294eb692f12116fa9f3904a5))
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
### Bug Fixes
* **build:** Do not throw on validate app config. ([96904a7](https://github.com/lowdefy/lowdefy/commit/96904a7783695f2b60b20be9488ffcb8dde79930))
* Rename appendHeader to appendHead. ([4e79736](https://github.com/lowdefy/lowdefy/commit/4e797363540bd0f5cfbe65928585012316b05a58))
### Features
* **build:** Build app config. ([6575bc7](https://github.com/lowdefy/lowdefy/commit/6575bc78bc37a1b33f301364a5daee4bab324884))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/build",
"version": "3.15.0",
"version": "3.16.1",
"licence": "Apache-2.0",
"description": "",
"homepage": "https://lowdefy.com",
@ -36,10 +36,10 @@
"webpack": "webpack --config webpack.config.js"
},
"dependencies": {
"@lowdefy/ajv": "3.15.0",
"@lowdefy/helpers": "3.15.0",
"@lowdefy/node-utils": "3.15.0",
"@lowdefy/nunjucks": "3.15.0",
"@lowdefy/ajv": "3.16.1",
"@lowdefy/helpers": "3.16.1",
"@lowdefy/node-utils": "3.16.1",
"@lowdefy/nunjucks": "3.16.1",
"ajv": "6.12.6",
"axios": "0.21.1",
"dataloader": "2.0.0",

View File

@ -24,6 +24,7 @@ async function run() {
logger: console,
cacheDirectory: path.resolve(process.cwd(), '../servers/serverDev/.lowdefy/.cache'),
configDirectory: path.resolve(process.cwd(), '../docs'),
// configDirectory: path.resolve(process.cwd(), '../servers/serverDev'),
outputDirectory: path.resolve(process.cwd(), '../servers/serverDev/.lowdefy/build'),
});
}

View File

@ -27,7 +27,9 @@ import buildPages from './build/buildPages/buildPages';
import buildRefs from './build/buildRefs';
import cleanOutputDirectory from './build/cleanOutputDirectory';
import testSchema from './build/testSchema';
import validateApp from './build/validateApp';
import validateConfig from './build/validateConfig';
import writeApp from './build/writeApp';
import writeConfig from './build/writeConfig';
import writeConnections from './build/writeConnections';
import writeGlobal from './build/writeGlobal';
@ -54,12 +56,14 @@ async function build(options) {
let components = await buildRefs({ context });
await testSchema({ components, context });
context.metaLoader = createMetaLoader({ components, context });
await validateApp({ components, context });
await validateConfig({ components, context });
await buildAuth({ components, context });
await buildConnections({ components, context });
await buildPages({ components, context });
await buildMenu({ components, context });
await cleanOutputDirectory({ context });
await writeApp({ components, context });
await writeConnections({ components, context });
await writeRequests({ components, context });
await writePages({ components, context });

View File

@ -0,0 +1,40 @@
/* eslint-disable no-param-reassign */
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { type } from '@lowdefy/helpers';
async function validateApp({ components }) {
if (type.isNone(components.app)) {
components.app = {};
}
if (!type.isObject(components.app)) {
throw new Error('lowdefy.app is not an object.');
}
if (type.isNone(components.app.html)) {
components.app.html = {};
}
if (type.isNone(components.app.html.appendBody)) {
components.app.html.appendBody = '';
}
if (type.isNone(components.app.html.appendHead)) {
components.app.html.appendHead = '';
}
return components;
}
export default validateApp;

View File

@ -0,0 +1,57 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import validateApp from './validateApp';
import testContext from '../test/testContext';
const context = testContext();
test('validateApp success', async () => {
let components = {
app: {
html: {
appendBody: 'abc',
appendHead: 'abc',
},
},
};
let result = await validateApp({ components, context });
expect(result).toEqual({ app: { html: { appendBody: 'abc', appendHead: 'abc' } } });
components = {};
result = await validateApp({ components, context });
expect(result).toEqual({ app: { html: { appendBody: '', appendHead: '' } } });
components = {
app: {},
};
result = await validateApp({ components, context });
expect(result).toEqual({ app: { html: { appendBody: '', appendHead: '' } } });
components = {
app: {
html: {},
},
};
result = await validateApp({ components, context });
expect(result).toEqual({ app: { html: { appendBody: '', appendHead: '' } } });
});
test('validateApp app not an object', async () => {
const components = {
app: 'app',
};
await expect(validateApp({ components, context })).rejects.toThrow(
'lowdefy.app is not an object.'
);
});

View File

@ -25,7 +25,7 @@ async function validateConfig({ components }) {
components.config = {};
}
if (!type.isObject(components.config)) {
throw new Error('Config is not an object.');
throw new Error('lowdefy.config is not an object.');
}
if (type.isNone(components.config.auth)) {
components.config.auth = {};

View File

@ -23,7 +23,9 @@ test('validateConfig config not an object', async () => {
const components = {
config: 'config',
};
await expect(validateConfig({ components, context })).rejects.toThrow('Config is not an object.');
await expect(validateConfig({ components, context })).rejects.toThrow(
'lowdefy.config is not an object.'
);
});
test('validateConfig config invalid auth config', async () => {

View File

@ -0,0 +1,24 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
async function writeApp({ components, context }) {
await context.artifactSetter.set({
filePath: 'app.json',
content: JSON.stringify(components.app || {}, null, 2),
});
}
export default writeApp;

View File

@ -0,0 +1,77 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import writeApp from './writeApp';
import testContext from '../test/testContext';
const mockSet = jest.fn();
const artifactSetter = {
set: mockSet,
};
const context = testContext({ artifactSetter });
beforeEach(() => {
mockSet.mockReset();
});
test('writeApp', async () => {
const components = {
app: {
key: 'value',
},
};
await writeApp({ components, context });
expect(mockSet.mock.calls).toEqual([
[
{
filePath: 'app.json',
content: `{
"key": "value"
}`,
},
],
]);
});
test('writeApp empty config', async () => {
const components = {
app: {},
};
await writeApp({ components, context });
expect(mockSet.mock.calls).toEqual([
[
{
filePath: 'app.json',
content: `{}`,
},
],
]);
});
test('writeApp config undefined', async () => {
const components = {};
await writeApp({ components, context });
expect(mockSet.mock.calls).toEqual([
[
{
filePath: 'app.json',
content: `{}`,
},
],
]);
});

View File

@ -33,6 +33,32 @@
}
}
},
"app": {
"type": "object",
"additionalProperties": false,
"properties": {
"html": {
"type": "object",
"errorMessage": {
"type": "App \"app.html\" should be an object."
},
"properties": {
"appendBody": {
"type": "string",
"errorMessage": {
"type": "App \"app.html.appendBody\" should be a string."
}
},
"appendHead": {
"type": "string",
"errorMessage": {
"type": "App \"app.html.appendHead\" should be a string."
}
}
}
}
}
},
"authConfig": {
"type": "object",
"additionalProperties": false,
@ -466,7 +492,6 @@
}
}
}
},
"additionalProperties": false,
"required": ["lowdefy"],
@ -489,6 +514,9 @@
"type": "App \"licence\" should be a string."
}
},
"app": {
"$ref": "#/definitions/app"
},
"cli": {
"type": "object",
"errorMessage": {

View File

@ -32,6 +32,9 @@ const defaultMetaLocations = {
Html: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-basic/meta/Html.json`,
},
Img: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-basic/meta/Img.json`,
},
List: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-basic/meta/List.json`,
},
@ -223,6 +226,9 @@ const defaultMetaLocations = {
TitleInput: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-antd/meta/TitleInput.json`,
},
Tooltip: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-antd/meta/Tooltip.json`,
},
UserAvatar: {
url: `https://blocks-cdn.lowdefy.com/v${version}/blocks-antd/meta/UserAvatar.json`,
},

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package lowdefy
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
### Bug Fixes
* Rename appendHeader to appendHead. ([4e79736](https://github.com/lowdefy/lowdefy/commit/4e797363540bd0f5cfbe65928585012316b05a58))
* webpack config so that index.html is not minified. ([d9cbf8d](https://github.com/lowdefy/lowdefy/commit/d9cbf8df56f97116832a7038f026058f1d528dc6))
* **servers:** Express function changed to async. ([6df571b](https://github.com/lowdefy/lowdefy/commit/6df571b0475d946e6864c2824af36450b70a7fa0))
### Features
* Include contenthash in webpack output. ([dd2adbb](https://github.com/lowdefy/lowdefy/commit/dd2adbbaa195899c6986ca99934e19c4f6aeca21)), closes [#575](https://github.com/lowdefy/lowdefy/issues/575)
* **cli:** Add appendHead, appendBody and custom js scripts. ([0f74833](https://github.com/lowdefy/lowdefy/commit/0f74833914917e7fb5d2d51177e2010b698d1019))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)

View File

@ -1,6 +1,6 @@
{
"name": "lowdefy",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "Lowdefy CLI",
"homepage": "https://lowdefy.com",
@ -40,8 +40,8 @@
"webpack": "webpack --config webpack.config.js"
},
"dependencies": {
"@lowdefy/helpers": "3.15.0",
"@lowdefy/node-utils": "3.15.0",
"@lowdefy/helpers": "3.16.1",
"@lowdefy/node-utils": "3.16.1",
"apollo-server-express": "2.21.0",
"axios": "0.21.1",
"chalk": "4.1.0",
@ -70,7 +70,7 @@
"@babel/core": "7.12.16",
"@babel/preset-env": "7.12.16",
"@babel/preset-react": "7.12.13",
"@lowdefy/block-tools": "3.15.0",
"@lowdefy/block-tools": "3.16.1",
"babel-jest": "26.6.3",
"babel-loader": "8.2.2",
"clean-webpack-plugin": "3.0.0",

View File

@ -17,6 +17,7 @@
import path from 'path';
import { spawnSync } from 'child_process';
import fse from 'fs-extra';
import { readFile, writeFile } from '@lowdefy/node-utils';
import checkChildProcessError from '../../utils/checkChildProcessError';
import startUp from '../../utils/startUp';
@ -24,7 +25,7 @@ import getFederatedModule from '../../utils/getFederatedModule';
import fetchNpmTarball from '../../utils/fetchNpmTarball';
async function fetchNetlifyServer({ context, netlifyDir }) {
context.print.spin('Fetching Lowdefy Netlify server.');
context.print.log('Fetching Lowdefy Netlify server.');
await fetchNpmTarball({
packageName: '@lowdefy/server-netlify',
version: context.lowdefyVersion,
@ -39,7 +40,7 @@ async function npmInstall({ context, netlifyDir }) {
await fse.remove(path.resolve('./package-lock.json'));
await fse.emptyDir(path.resolve('./node_modules'));
context.print.spin('npm install production.');
context.print.log('npm install production.');
let processOutput = spawnSync('npm', ['install', '--production', '--legacy-peer-deps']);
checkChildProcessError({
context,
@ -51,7 +52,7 @@ async function npmInstall({ context, netlifyDir }) {
}
async function fetchBuildScript({ context }) {
context.print.spin('Fetching Lowdefy build script.');
context.print.log('Fetching Lowdefy build script.');
const { default: buildScript } = await getFederatedModule({
module: 'build',
packageName: '@lowdefy/build',
@ -63,7 +64,7 @@ async function fetchBuildScript({ context }) {
}
async function build({ context, buildScript, netlifyDir }) {
context.print.spin('Starting Lowdefy build.');
context.print.log('Starting Lowdefy build.');
const outputDirectory = path.resolve(netlifyDir, './package/dist/functions/graphql/build');
await buildScript({
logger: context.print,
@ -74,6 +75,21 @@ async function build({ context, buildScript, netlifyDir }) {
context.print.log(`Build artifacts saved at ${outputDirectory}.`);
}
async function buildIndexHtml({ context }) {
context.print.log('Starting Lowdefy index.html build.');
let appConfig = await readFile(path.resolve('./.lowdefy/functions/graphql/build/app.json'));
appConfig = JSON.parse(appConfig);
const indexHtmlPath = path.resolve('./.lowdefy/publish/index.html');
let indexHtml = await readFile(indexHtmlPath);
indexHtml = indexHtml.replace('<!-- __LOWDEFY_APP_HEAD_HTML__ -->', appConfig.html.appendHead);
indexHtml = indexHtml.replace('<!-- __LOWDEFY_APP_BODY_HTML__ -->', appConfig.html.appendBody);
await writeFile({
filePath: indexHtmlPath,
content: indexHtml,
});
context.print.log('Lowdefy index.html build complete.');
}
async function moveBuildArtifacts({ context, netlifyDir }) {
await fse.copy(
path.resolve(netlifyDir, 'package/dist/shell'),
@ -117,6 +133,9 @@ async function buildNetlify({ context, options }) {
await moveFunctions({ context, netlifyDir });
await movePublicAssets({ context });
context.print.log(`Build artifacts.`);
await buildIndexHtml({ context });
await context.sendTelemetry({
data: {
netlify: process.env.NETLIFY === 'true',

View File

@ -26,13 +26,20 @@ async function getExpress({ context, gqlServer, options }) {
const reloadPort = await findOpenPort();
const reloadReturned = await reload(app, { route: '/api/dev/reload.js', port: reloadPort });
app.use(express.static(path.join(__dirname, 'shell')));
app.use('/public', express.static(path.resolve(process.cwd(), 'public')));
app.use(express.static(path.resolve(__dirname, 'shell')));
app.use('/api/dev/version', (req, res) => {
res.json(context.lowdefyVersion);
});
app.use((req, res) => {
res.sendFile(path.resolve(__dirname, 'shell/index.html'));
app.use(async (req, res) => {
let indexHtml = await readFile(path.resolve(__dirname, 'shell/index.html'));
let appConfig = await readFile(path.resolve(context.outputDirectory, 'app.json'));
appConfig = JSON.parse(appConfig);
indexHtml = indexHtml.replace('<!-- __LOWDEFY_APP_HEAD_HTML__ -->', appConfig.html.appendHead);
indexHtml = indexHtml.replace('<!-- __LOWDEFY_APP_BODY_HTML__ -->', appConfig.html.appendBody);
res.send(indexHtml);
});
return { expressApp: app, reloadFn: reloadReturned.reload };
}

View File

@ -13,22 +13,46 @@
See the License for the specific language governing permissions and
limitations under the License. -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lowdefy App</title>
<link rel="manifest" href="/public/manifest.webmanifest">
<link rel="icon" type="image/svg+xml" href="/public/icon.svg">
<link rel="icon" type="image/png" href="/public/icon-32.png">
<link rel="apple-touch-icon" href="/public/apple-touch-icon.png">
<script src="/api/dev/reload.js"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="emotion"></div>
<div id="root"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lowdefy App</title>
<link rel="manifest" href="/public/manifest.webmanifest">
<link rel="icon" type="image/svg+xml" href="/public/icon.svg">
<link rel="icon" type="image/png" href="/public/icon-32.png">
<link rel="apple-touch-icon" href="/public/apple-touch-icon.png">
<script type="text/javascript">
const jsActions = {}
const jsOperators = {}
const getMethodLoader = (scope, reference) =>
(name, method) => {
if (typeof name !== 'string') {
throw new Error(`${scope} requires a string for the first argument.`)
}
if (typeof method !== 'function') {
throw new Error(`${scope} requires a function for the second argument.`)
}
reference[name] = method;
}
window.lowdefy = {
imports: {
jsActions,
jsOperators,
},
registerJsAction: getMethodLoader('registerJsAction', jsActions),
registerJsOperator: getMethodLoader('registerJsOperator', jsOperators)
}
</script>
<!-- __LOWDEFY_APP_HEAD_HTML__ -->
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="emotion"></div>
<div id="root"></div>
<!-- __LOWDEFY_APP_BODY_HTML__ -->
</body>
</html>

View File

@ -1,8 +1,10 @@
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;
const { dependencies, devDependencies } = require('./package.json');
module.exports = [
@ -42,7 +44,9 @@ module.exports = [
],
},
plugins: [
// new CleanWebpackPlugin(),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*', '!shell/**'],
}),
new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true }),
new ModuleFederationPlugin({
name: 'cli',
@ -57,7 +61,7 @@ module.exports = [
{
entry: './src/commands/dev/shell/index.js',
output: {
filename: 'index.js',
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist/shell'),
},
mode: 'production',
@ -84,8 +88,14 @@ module.exports = [
},
],
},
optimization: {
moduleIds: 'deterministic',
runtimeChunk: 'single',
},
plugins: [
// new CleanWebpackPlugin(),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*', '!index.js'],
}),
new ModuleFederationPlugin({
name: 'lowdefy_web_shell',
shared: {
@ -103,8 +113,9 @@ module.exports = [
},
}),
new HtmlWebpackPlugin({
template: './src/commands/dev/shell/index.html',
minify: false,
publicPath: '/',
template: './src/commands/dev/shell/index.html',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),

View File

@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
**Note:** Version bump only for package @lowdefy/color
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
**Note:** Version bump only for package @lowdefy/color
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)
**Note:** Version bump only for package @lowdefy/color

View File

@ -1,6 +1,6 @@
{
"name": "@lowdefy/color",
"version": "3.15.0",
"version": "3.16.1",
"license": "Apache-2.0",
"description": "",
"homepage": "https://lowdefy.com",

View File

@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.16.1](https://github.com/lowdefy/lowdefy/compare/v3.16.0...v3.16.1) (2021-05-26)
### Bug Fixes
* **build:** Add default locations for new blocks. ([544d1e1](https://github.com/lowdefy/lowdefy/commit/544d1e1d8459fb03294eb692f12116fa9f3904a5))
# [3.16.0](https://github.com/lowdefy/lowdefy/compare/v3.15.0...v3.16.0) (2021-05-26)
### Bug Fixes
* **docs:** Add alerts for client or server operators. ([bf5c9be](https://github.com/lowdefy/lowdefy/commit/bf5c9be5e672703c7e31f7a5a7228e492dd73e9c))
* **docs:** Add custom code concept. ([b0e63e1](https://github.com/lowdefy/lowdefy/commit/b0e63e1e2e7bcbdcec3c96692f694a8cd33e3b1d))
* **docs:** Add discord link. ([0a24af7](https://github.com/lowdefy/lowdefy/commit/0a24af75ebb682abf51556cafcab1c584e01053e))
* **docs:** Change to head.html. ([a7f20c4](https://github.com/lowdefy/lowdefy/commit/a7f20c4d238b520cf172934fd9df0c4f83d9157d))
* **docs:** Create modules/index and load filterDefaultValue. ([e45e5f1](https://github.com/lowdefy/lowdefy/commit/e45e5f1f80ccc256d668e92813b9e5415eccf6b7))
* **docs:** Document context initialization events for context blocks. ([a59bff5](https://github.com/lowdefy/lowdefy/commit/a59bff50f25b79d0468a4a6afc836f264c3263b2)), closes [#576](https://github.com/lowdefy/lowdefy/issues/576)
* **docs:** Fix custom block event actions history description. ([eb49803](https://github.com/lowdefy/lowdefy/commit/eb49803a48719c38a7d4cb0ff7d0540c0da25d75))
* **docs:** Import _js.filterDefaultValue as operator. ([a6e2fe0](https://github.com/lowdefy/lowdefy/commit/a6e2fe036160d49b6c1994aee68326f88fc7c564))
* **docs:** Sitemap must be https. ([290b271](https://github.com/lowdefy/lowdefy/commit/290b271ec6b1cff3e89c3381ab741d913eea5688))
* **docs:** Updates to custom code docs. ([a4be530](https://github.com/lowdefy/lowdefy/commit/a4be53077afd6dbcf42f41473695f77d00ccd1a5))
* Rename appendHeader to appendHead. ([4e79736](https://github.com/lowdefy/lowdefy/commit/4e797363540bd0f5cfbe65928585012316b05a58))
### Features
* add Tooltip to docs ([e79a876](https://github.com/lowdefy/lowdefy/commit/e79a876a30585d90532680d7229ee921b18a4ac1))
* **blockBasic:** Add Img block. ([c850cb3](https://github.com/lowdefy/lowdefy/commit/c850cb32061cf2a4c361aecc024fe699cc06c7e0))
* **docs:** Add _actions operator. ([d5583d2](https://github.com/lowdefy/lowdefy/commit/d5583d200a809cc451d051a7ee16455f018beff9))
* **docs:** Add JsAction. ([19fd956](https://github.com/lowdefy/lowdefy/commit/19fd9563c038a16aabebbf5c0e9b3324efa5b9d4))
# [3.15.0](https://github.com/lowdefy/lowdefy/compare/v3.14.1...v3.15.0) (2021-05-11)

View File

@ -0,0 +1,234 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/actions.yaml.njk
vars:
pageId: JsAction
pageTitle: JsAction
filePath: actions/JsAction.yaml
warning: |
SECURITY WARNING: The JsAction executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your JavaScript, make sure that you only load trusted code.
types: |
```
(params: {
name: string,
args?: any[]
}): void
```
description: |
The `JsAction` action is used to call a custom JavaScript function which was loaded onto the page using the `window.lowdefy.registerJsAction()` method. This JavaScript function can be asynchronous. See [Custom Code](/custom-code) for more details on how to register a new JavaScript action.
The returned result of the JavaScript function is accessible through the [`_actions`](/_actions) operator for subsequent action in the event action list.
A `JsAction` is called with a context object which includes all [`context` data objects](/context-and-state) as well as the list of `args` passed to the action.
```text
(context: {
user: object,
global: object,
state: object,
urlQuery: object,
input: object,
},
...args?: any[]): any
```
params: |
###### object
- `name: string`: __Required__ - The registered name of the JavaScript function to call when the action is triggered.
- `args: any[]`: The array of positional arguments with which the JavaScript function should be called.
examples: |
##### Set a [Intercom](https://www.intercom.com/) user when a page is initialized:
```yaml
# lowdefy.yaml
name: intercom-example
lowdefy: '3.16.1'
app:
html:
appendBody: |
<script>
function setIntercomUser(context) {
window.intercomSettings = {
app_id: "{{ your_intercom_app_id }}",
name: context.user.name,
email: context.user.email,
};
}
window.lowdefy.registerJsAction('setIntercomUser', setIntercomUser);
</script>
<script>
(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');
ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];
i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');
s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/{{ your_intercom_app_id }}';
var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};
if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
</script>
pages:
- id: home
type: PageHeaderMenu
events:
onInitAsync:
- id: set_intercom_user
type: JsAction
params:
name: setIntercomUser
blocks:
# ...
```
##### Highlight search term returned by [MongoDB Search Highlight](https://docs.atlas.mongodb.com/reference/atlas-search/highlighting/):
Add a JavaScript file to highlight the search text by wapping the highlighted text with `<span style="background: yellow;">{{ value }}</span>`:
```js
// file: /public/highlightText.js
function highlightText(context, data) {
return data.map((item) => {
item.highlights.forEach((light) => {
const paths = light.path.split('.');
const key = paths[paths.length - 1];
paths.pop();
let res = item;
paths.forEach((key) => {
res = res[key];
});
res[key] = light.texts.reduce((acc, obj) => {
if (obj.type === 'hit') {
return acc.concat('<span style="background: yellow;">', obj.value, '</span>');
}
return acc.concat(obj.value);
}, '');
});
return item;
});
}
export default highlightText;
```
Import custom JavaScript modules:
```js
// file: /public/modules.js
import highlightText from './highlightText.js';
window.lowdefy.registerJsAction('highlightText', highlightText);
````
Lowdefy setup:
```yaml
# file: lowdefy.yaml
name: text-highlight-example
lowdefy: '3.16.1'
app:
html:
# Load the custom modules into the index.html head tag.
appendHead: |
<script type="module" src="/public/modules.js"></script>
connections:
- id: products
type: MongoDBCollection
properties:
collection: products
databaseUri:
_secret: MDB_URI
pages:
- id: home
type: PageHeaderMenu
requests:
- id: search_products
type: MongoDBAggregation
connectionId: products
properties:
pipeline:
_array.concat:
- - $search:
compound:
should:
- text:
query:
_string.concat:
- '*'
- _state: search.input
- '*'
path:
- title
- description
- wildcard:
query:
_string.concat:
- '*'
- _state: search.input
- '*'
path:
- title
- description
allowAnalyzedField: true
highlight:
path:
- title
- description
- $addFields:
score:
$meta: searchScore
highlights:
$meta: searchHighlights
blocks:
- id: search.input
type: TextInput
properties:
title: Type to search products
prefix: SearchOutlined
events:
onChange:
- id: get_search # get search_products query for search.input
type: Request
params: search_products
- id: apply_highlight # apply the highlight transformation to the request data.
type: JsAction
params:
name: highlightText
args:
- _request: search_products
- id: set_state # set the response of the apply_highlight action to state
type: SetState
params:
found_products:
_actions: apply_highlight.response
- id: product_results
type: Html
properties:
html:
_nunjucks:
template: |
<ul>
{% for item in found_products %}
<li>{{ item.title | safe }} - {{ item.description | safe}}</li>
{% endfor %}
</ul>
on:
found_products:
_state: found_products
```
NOTE: For this example to work, you will need a `products` collection in your MongoDB database, populated with `{title: '...', description: '...'}` data objects including the following search index on the `products` collection:
```json
{
"mappings": {
"dynamic": true,
"fields": {
"title": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
}
```

View File

@ -0,0 +1,38 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/blocks/template.yaml.njk
vars:
block_type: Tooltip
category: container
schema: ../blocks/blocksAntd/src/blocks/Tooltip/Tooltip.json
description_content: |
A simple text popup tip. Can be used to display extra information about its children blocks.
init_state_values:
block.properties.title: Tooltip title
areas:
- content
examples:
- title: Button tooltip
block:
id: button_ex
type: Tooltip
properties:
title: Explains what happens when this button is clicked.
blocks:
- id: btn
type: Button
properties:
title: Button

View File

@ -23,7 +23,7 @@ _ref:
html: <a href="https://lowdefy.com">Lowdefy Website</a>
description_content: |
A block to render HTML.
> The Html block sanitizes HTML using [DOMPurify's](https://github.com/cure53/DOMPurify) default configuration. This comes with some security considerations, please consider [DOMPurify's Security Goals and Threat Model](https://github.com/cure53/DOMPurify/wiki/Security-Goals-&-Threat-Model) for more details regarding the security impact of using the Html block. In short, it is strongly advised to never render any user input Html content, only render hardcoded or trusted HTML content.
examples:
@ -31,21 +31,20 @@ _ref:
block:
id: basic_example
type: Html
properties:
properties:
html: |
<div style="background: #123456; padding: 10px;"><h1 style="color: white;">A simple white title box</h1></div>
- title: DangerousHtml with iframes sanitized
block:
id: sanitized_iframes_example
type: Html
properties:
properties:
html: |
The iframe was removed: <iframe style="max-width: 512px;" width="100%" src="https://www.youtube.com/embed/7N7GWdlQJlU" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> - title: DangerousHtml with iframes enabled
- title: DangerousHtml basic sanitization
block:
id: sanitized_example
type: Html
properties:
properties:
html: |
<div style="color: red; border: 2px dashed blue; padding: 10px;"><script>alert("hello world")</script><img src=x onerror=alert("img") />A little bit of bad html sanitized.</div>

View File

@ -0,0 +1,40 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/blocks/template.yaml.njk
vars:
block_type: Img
category: display
schema: ../blocks/blocksBasic/src/blocks/Img/Img.json
filePath: blocks/display/Img.yaml
init_property_values:
src: 'https://docs.lowdefy.com/public/logo-light-theme.png'
description_content: |
A block to render a HTML [`<img/>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) element.
examples:
- title: Basic Img
block:
id: basic_example
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
- title: srcset Img
block:
id: srcset_example
type: Img
properties:
src: https://docs.lowdefy.com/public/logo-light-theme.png
srcset: https://docs.lowdefy.com/public/logo-square-light-theme.png 40w, https://docs.lowdefy.com/public/logo-light-theme.png 577w
sizes: '(max-width: 576px) 40px, 577px'

View File

@ -20,20 +20,24 @@ _ref:
section: Concepts
filePath: concepts/custom-blocks.yaml
content:
- id: warning
type: Alert
properties:
message: |
SECURITY WARNING: Blocks execute JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Make sure that you only load blocks from a trusted source.
type: warning
- id: md1
type: MarkdownWithCode
properties:
content: |
> __NOTE__: Blocks run javascript on your site - this can lead to potential security vulnerabilities. __Make sure you trust the block publisher or even better, host your own blocks.__
Blocks in Lowdefy are simple, most often state-less, [React components](https://reactjs.org/docs/components-and-props.html). Lowdefy uses [webpack module federation](https://webpack.js.org/concepts/module-federation/) to implement a micro front-end strategy. This means blocks are imported at load time, and not part of the Lowdefy app build.
The decoupling of blocks provides the considerable advantages:
- Block developers can extend the UI capabilities of Lowdefy by building blocks for the community to utilize.
- Lowdefy app developers can use community blocks to experiment and extend their apps.
- Lowdefy blocks are simple, most often stateless React components, thus blocks can be developed fast and can be used inside Lowdefy apps with ease.
- Lowdefy blocks are simple, most often stateless React components, thus blocks can be developed quickly and can be used inside Lowdefy apps with ease.
- The build process is simple and fast since you only build the code for your block, and not the entire application.
- The Lowdefy engine takes care off the application state, the the block only has to concern itself which a easy application interface.
- The Lowdefy engine takes care off the application state, the the block only has to concern itself with a easy application interface.
## Using Custom Blocks
@ -41,7 +45,7 @@ _ref:
```yaml
name: dashboard-app
lowdefy: 3.10.0
lowdefy: 3.16.1
types:
AmChartsXY:
url: https://blocks-cdn.lowdefy.com/v3.10.1/blocks-amcharts/meta/AmChartsXY.json
@ -89,9 +93,9 @@ _ref:
In your `lowdefy.yaml` file, add your custom block type to the `types` object with the local path.
```yaml
```yaml
name: dashboard-app
lowdefy: 3.10.0
lowdefy: 3.16.1
types:
MyCustomBlock:
url: http://localhost:3002/meta/MyCustomBlock.json
@ -125,16 +129,18 @@ _ref:
- `actions: actionObjects[]`: The list of [Lowdefy action objects](https://docs.lowdefy.com/events-and-actions) which will be evaluated by the Lowdefy engine.
- `history: object[]`: A list of objects logging the event calls and responses.
- `blockId: string`: The block id from which the event was called.
- `endTimestamp: datetime`: Timestamp for when the event was completed.
- `event: object`: The event object passed to the event.
- `eventName: string`: The event name which which triggerEvent was called.
- `success: boolean`: True if all actions for the event executed without throwing any errors.
- `timestamp: datetime`: Timestamp for when the event was completed.
- `responses: object[]`: The list of action responses.
- `actionId: string`: The id of the triggered action.
- `actionType: string`: The type of action called.
- `error: Error: If the action throw an error.
- `response: any`: The returned result of the action.
- `skipped: boolean`: True if the action was skipped.
- `startTimestamp: datetime`: Timestamp for when the event was started.
- `responses: object`: The list of action responses, where the object key is equal to the action id.
- `{{ key }}: string`:
- `type: string`: The type of action called.
- `error: Error`: If the action throw an error.
- `index: number`: Index of the action in the event array.
- `response: any`: The returned result of the action.
- `skipped: boolean`: True if the action was skipped.
- `methods: object`: All application methods built into Lowdefy, available for the block.
- `makeCssClass(cssObject | cssObject[]): string`: This methods creates a css class for the block to apply to DOM elements. Css classes are created using [Emotion](https://emotion.sh/docs/introduction). If a list of cssObject are given the cssObjects are shallow merged with the preceding objects properties being overwritten by the latter. Any valid css style object can be passed, including media queries. Default media queries are built in:
- `xs?: object`: Css object applied for screen media with max width of 576px.
@ -155,7 +161,7 @@ _ref:
## Deploying Custom Blocks
Both the block metadata and block React component need to be built by webpack and hosted on a publicly accessible static file server. Any Lowdefy app can then load and use the block. You also need to set the `remoteEntryUrl` in `webpack.prod.js` in order to build the correct block meta data, make sure URL is pointing to where your block is hosted.
Both the block metadata and block React component need to be built by webpack and hosted on a publicly accessible static file server. Any Lowdefy app can then load and use the block. You also need to set the `remoteEntryUrl` in `webpack.prod.js` in order to build the correct block meta data, make sure the URL is pointing to where your block is hosted.
The easiest way to host your custom block is the deploy the custom block to [npm](https://www.npmjs.com/) and [Unpkg](https://unpkg.com/) will automatically host your block for you on their CDN. Although this option is easy, the cache settings for Unpkg can result in longer load times in some cases which can result in a unreliable user experience. It is thus best to deploy you blocks to your own static file servers.
@ -163,7 +169,7 @@ _ref:
- _ref:
path: templates/navigation_buttons.yaml
vars:
previous_page_title: Lists
previous_page_id: lists
previous_page_title: Custom Code
previous_page_id: custom-code
next_page_title: User authentication
next_page_id: users-introduction

View File

@ -0,0 +1,217 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/general.yaml.njk
vars:
pageId: custom-code
pageTitle: Custom Code
section: Concepts
filePath: concepts/custom-code.yaml
content:
- id: warning
type: Alert
properties:
message: |
SECURITY WARNING: Custom code executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your custom code, make sure that you only load trusted code.
type: warning
- id: md1
type: MarkdownWithCode
properties:
content: |
Lowdefy runs as a single page web app (SPA). It is possible to extend the functionality of a Lowdefy app by loading custom code (HTML, CSS and JavaScript) into the HTML `head` and `body` to of the default `index.html` page.
The content loaded into the `head` and `body` tag can be any valid HTML, most often `script` tags are loaded to register a new [`JsAction`](/JsAction) or [`_js`](/_js) operator. However, third party code can also be imported, for example Google Analytics, Intercom, etc. Be sure to only load trusted code into your app, as this code will be able to execute JavaScript on all pages of your Lowdefy app, which could expose you app or data to security vulnerabilities.
> __Warning__: Lowdefy implements the [Ant design](https://ant.design/) UI component framework for app layout and most blocks, thus the default Ant Design CSS is loaded for all Lowdefy apps. Take caution not to unintentionally overwrite existing style settings and classes which can result in a degraded user experience.
## Schema to load custom code
- `app.html.appendHead: string`: Any valid HTML content can be loaded just before the `</head>` tag of the Lowdefy app `index.html` file.
- `app.html.appendBody: string`: Any valid HTML content can be loaded just before the `</body>` tag of the Lowdefy app `index.html` file.
Most often it is convenient to abstract this HTML out to a separate file using the [`_ref`](/_ref) operator.
> __Warning__: Code imported using `appendHead` or `appendBody` will be loaded, and can execute JavaScript on every page of your Lowdefy app.
###### Loading third party code snippet like Google Analytics:
To add [Google Analytics](/https://developers.google.com/analytics/devguides/collection/analyticsjs) to a Lowdefy app, the `lowdefy.yaml` can be setup with:
```yaml
name: google-analytics-example
lowdefy: 3.16.1
# ...
app:
html:
appendHead: |
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
# ...
```
## Hosting static files
A Lowdefy app provides a convenient method to host __public__ files under the `/public/*` app route. Add content to be hosted publicly by creating a folder named `public` in the root of a Lowdefy project folder, next to the `lowdefy.yaml` file. Place the public content in this folder to host this content with your app.
All content in this folder will be publicly accessible at `{{ APP_URL }}/public/{{ FILE_PATH_NAME }}`. For example, the logo at the top of this page is hosted at [`https://docs.lowdefy.com/public/logo-light-theme.png`](http://localhost:3000/public/logo-light-theme.png). Sub-folders inside the public folder are supported.
By default, the `public` folder of a Lowdefy app will serve some files which most apps need:
- `apple-touch-icon.png`: A 180x180px png image file to be used as the apple PWA icon.
- `icon-32.png`: A 32x32px png image file to be used as fallback favicon for some browsers.
- `icon-512.png`: A 512x512px png image icon.
- `icon.svg`: A svg image file which will be used as favicon if supported by browser.
- `logo-dark-theme.png`: A ~250x72px png image used as the header image for [`PageHeaderMenu`](/PageHeaderMenu) and [`PageSiderMenu`](/PageSiderMenu) blocks on desktop when the block theme is set to `dark`.
- `logo-light-theme.png`: A ~250x72px png image used as the header image for `PageHeaderMenu` and `PageSiderMenu` blocks on desktop when the block theme is set to `light`.
- `logo-square-dark-theme.png`: A ~125x125px png image used as the header image for `PageHeaderMenu` and `PageSiderMenu` blocks on mobile when the block theme is set to `dark`.
- `logo-square-light-theme.png`: A ~125x125px png image used as the header image for `PageHeaderMenu` and `PageSiderMenu` blocks on mobile when the block theme is set to `light`.
- `manifest.webmanifest`: The app [web manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest).
Any of these files can be overwritten by replacing the file with a modified version. For example, to replace the logo inside the header of `PageSiderMenu` on all pages, add a ~250x72px logo inside the project folder at `/public/logo-light-theme.png`.
## Loading and registering a [`JsAction`](/JsAction)
In order for the Lowdefy app engine to execute a custom JavaScript [action](/events-and-actions), the JavaScript code for the action must be loaded onto the page and registered using the `registerJsAction` method available on the browser [`window`](https://developer.mozilla.org/en-US/docs/Web/API/window) object by calling `window.lowdefy.registerJsAction(name: string, action: function)`.
The `JsAction` allows the use of async functions.
###### Load, register and trigger a custom `JsAction` from code in the app `public` folder:
This example fetches a list of Todos from [{JSON}placeholder](https://jsonplaceholder.typicode.com/), and updates [state](/context-and-state).
1) First, add the JavaScript code to the `public` folder and resister the `JsAction`:
```js
// /public/fetchTodos.js
function async fetchTodos(context, numItems, skip) {
const data = await fetch('https://jsonplaceholder.typicode.com/todos');
const todos = await data.json();
return todos.slice(skip, skip + numItems);
}
// Register the JsAction for the Lowdefy app to use.
window.lowdefy.registerJsAction('fetchTodos', fetchTodos);
```
2) Import the JavaScript as a module into the page:
```html
<!-- /header_modules.html -->
<script type="module" src="/public/fetchTodos.js"></script>
```
3) Set load the custom code into the app header and trigger the action on page load:
```yaml
# /lowdefy.yaml
name: json-todos
lowdefy: 3.16.1
app:
html:
appendHead:
_ref: header_modules.html # Load the custom HTML into the header.
pages:
- id: todos
type: PageHeaderMenu
events:
onEnter:
- id: get_todos
type: JsAction
params:
name: fetchTodos # Trigger the custom JavaScript action.
args:
- 10 # numItems
- 0 # skip
- id: set_todos
type: SetState
params:
todos:
# Set the response of the get_todos action to state.
_actions: get_todos.response
# ...
```
## Loading and registering a [`_js`](/_js) operator
Similar to the loading custom JavaScript actions, custom JavaScript operators can also be loaded. In order for the Lowdefy app engine to execute a custom JavaScript [operator](/operators), the JavaScript code for the operator must be loaded onto the page and registered using the `registerJsOperator` method available on the browser [`window`](https://developer.mozilla.org/en-US/docs/Web/API/window) object by calling `window.lowdefy.registerJsOperator(name: string, action: function)`.
All `_js` functions must be synchronous.
###### Load, register and use a custom `_js` operator from code in the app `public` folder:
This example uses a `_js` operator to remove all duplicates from a list of names.
1) First, add the JavaScript code to the `public` folder and resister the `_js` operator:
```js
// /public/foo_operators.js
function removeDuplicates(items) {
return [ ...new Set(items) ];
}
// Register the removeDuplicates function as a _js.deduplicate operator.
window.lowdefy.registerJsOperator('deduplicate', removeDuplicates);
```
2) Import the JavaScript as a module into the page:
```html
<!-- /header.html -->
<script type="module" src="/public/foo_operators.js"></script>
```
3) Set load the custom code into the app header and use the new operator on the page:
```yaml
# /lowdefy.yaml
name: operator-example
lowdefy: 3.16.1
app:
html:
appendHead:
_ref: header.html # Load the custom HTML into the header.
pages:
- id: some_names
type: PageHeaderMenu
blocks:
- id: names
type: ButtonSelector
properties:
title: Select your new friend
options:
# use the removeDuplicates function and pass a list of names as a function argument
_js.deduplicate:
- - Anne
- Sam
- Joe
- Micheal
- Sam
- Steven
- Anne
- Pepper
# ...
```
------
Custom code provides an easy way to extent the logic functionality of Lowdefy apps. However, to extend the UI capabilities beyond the existing features provided by the default Lowdefy blocks, custom blocks can be loaded onto apps.
- _ref:
path: templates/navigation_buttons.yaml
vars:
previous_page_title: Lists
previous_page_id: lists
next_page_title: Custom Blocks
next_page_id: custom-blocks

View File

@ -21,7 +21,7 @@ _ref:
filePath: concepts/events-and-actions.yaml
content:
- id: md1
type: Markdown
type: MarkdownWithCode
properties:
content: |
### TLDR
@ -83,6 +83,9 @@ _ref:
params:
# ...
```
# The actions object
When an event is triggered each completed action writes its response to the actions object under the action id object key. Thus all following actions in a event action list has access to the response of all preceding actions in the same event list through the [`_actions`](/_actions) operator.
# The event object
@ -90,17 +93,17 @@ _ref:
# Context initialisation events
Four events are always defined for [`context`](/context) type blocks:
Four events are always defined for [`context`](/context) type blocks, called in the following order:
- `onInit`
- `onEnter`
- `onInitAsync`
- `onEnterAsync`
These events can be used to initialise the context or page.
These events can be used to initialize the context or page.
The `onInit` event is triggered the first time a context is mounted, for example if a page is loaded for the first time. This event blocks page render, in other words, the page __will__ remain in a loading state until all the actions have completed execution. It can be used to set up a context. Actions that take a long time to execute, like `Request`, should be used sparingly here.
The `onEnter` event is triggered every time a context is mounted to a page, for example if a user left a page, and returns to it. This event also blocks page render. It can be used to execute actions that should be run each time a page is loaded, like checking if an id is present in the [url query parameters](/_url_query), and initialising the [`state`](/context-and-state).
The `onEnter` event is triggered every time a context is mounted to a page, for example if a user left a page, and returns to it. This event also blocks page render. It can be used to execute actions that should be run each time a page is loaded, like checking if an id is present in the [url query parameters](/_url_query), and initializing the [`state`](/context-and-state).
The `onInitAsync` event is triggered the first time a context is mounted, but does not block page render. In other words, the page __will not__ remain in a loading state until all the actions have completed execution. This is a good place to execute non-blocking tasks or requests that might take longer to execute.
@ -111,6 +114,7 @@ _ref:
The following actions can be used:
- [`CallMethod`](/CallMethod) - Call a method defined by another block.
- [`JsAction`](/JsAction) - Call a custom JavaScript function as an action.
- [`Link`](/Link) - Link to another page.
- [`Message`](/Message) - Show a message to the user.
- [`Notification`](/Notification) - Show a notification to the user.

View File

@ -152,11 +152,11 @@ _ref:
### Lists and state
List blocks create a content area for each item in `state`. If `state` is updated, the list block will also update, creating or destroying content areas as necessary. Thus list blocks can also be manipulated by setting `state` directly using the [`SetState`](/SetState) operator.
- _ref:
path: templates/navigation_buttons.yaml
vars:
previous_page_title: Deployment
previous_page_id: deployment
next_page_title: Custom Blocks
next_page_id: custom-blocks
next_page_title: Custom Code
next_page_id: custom-code

View File

@ -30,7 +30,31 @@ _ref:
If an operator errors while evaluating, it returns a `null` value, and logs the error to the console.
# Build time operators
## Client or server operators
Some operators are only available on either the client or the server. For example, the [`_menu`](/_menu) operator is only useful on the client and is thus not included in server requests. Likewise, the [`_secret`](/_secret) operator is only available on the server for security reasons.
If a operator has special environment considerations, it is indicated on the individual operator documentation page. If no indication is made, the operator can be used under both environments.
##### Client only operators:
- [_actions](/_actions)
- [_format](/_format)
- [_js](/_js)
- [_list_contexts](/_list_contexts)
- [_media](/_media)
- [_menu](/_menu)
- [_request](/_request)
##### Server only operators:
- [_diff](/_diff)
- [_secret](/_secret)
- [_uuid](/_uuid)
Operators that are client side only cannot be used in `Requests` and `Connections`, and operators which are server side only cannot be used in `Blocks` and `Actions`.
## Build time operators
Besides the client and server environment, app build time is considered a third environment where special operator logic applies.
The `_ref` and `_var` operators do not work like other operators. They are evaluated while an app is being built, and can thus be used anywhere in the app configuration. They are used to split a app into multiple files, and to reuse configuration. See [`_ref`](/_ref) for more details.
- _ref:

1
packages/docs/head.html Normal file
View File

@ -0,0 +1 @@
<script type="module" src="/public/modules/index.js" ></script>

View File

@ -13,7 +13,7 @@
# limitations under the License.
name: '@lowdefy/docs'
lowdefy: '3.15.0'
lowdefy: '3.16.1'
licence: Apache-2.0
global:
@ -24,6 +24,11 @@ global:
sm:
span: 23
app:
html:
appendHead:
_ref: head.html
connections:
- id: discord_channel
type: AxiosHttp

View File

@ -113,6 +113,11 @@
pageId: lists
properties:
title: Lists
- id: custom-code
type: MenuLink
pageId: custom-code
properties:
title: Custom Code
- id: custom-blocks
type: MenuLink
pageId: custom-blocks
@ -288,6 +293,9 @@
- id: Icon
type: MenuLink
pageId: Icon
- id: Img
type: MenuLink
pageId: Img
- id: Markdown
type: MenuLink
pageId: Markdown
@ -370,6 +378,9 @@
- id: Tabs
type: MenuLink
pageId: Tabs
- id: Tooltip
type: MenuLink
pageId: Tooltip
- id: blocks_context
type: MenuGroup
@ -383,9 +394,6 @@
- id: PageHCF
type: MenuLink
pageId: PageHCF
- id: PageHCF
type: MenuLink
pageId: PageHCF
- id: PageHCSF
type: MenuLink
pageId: PageHCSF
@ -481,6 +489,9 @@
- id: CallMethod
type: MenuLink
pageId: CallMethod
- id: JsAction
type: MenuLink
pageId: JsAction
- id: Link
type: MenuLink
pageId: Link
@ -524,6 +535,9 @@
title: Operators
icon: ToolOutlined
links:
- id: _actions
type: MenuLink
pageId: _actions
- id: _and
type: MenuLink
pageId: _and

View File

@ -0,0 +1,123 @@
# Copyright 2020-2021 Lowdefy, Inc
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
_ref:
path: templates/operators.yaml.njk
transformer: templates/operatorsMethodTransformer.js
vars:
pageId: _actions
pageTitle: _actions
filePath: operators/_actions.yaml
env: Client Only
types: |
```
(key: string): any
(all: boolean): any
(arguments: {
all?: boolean,
key?: string,
default?: any,
}): any
```
description: |
The `_actions` operator returns the response value for a preceding action in the same event list.
The action response object has the following structure:
```yaml
error: Error,
index: number,
response: any,
skipped: boolean,
type: string,
```
arguments: |
###### string
If the `_actions` operator is called with a string equal to a preceding action id in the same event list, the action response object returned. If a string is passed which does not match preceding action id in the same event list, `null` is returned. Dot notation is supported.
###### boolean
If the `_actions` operator is called with boolean argument `true`, an object with all the preceding action id responses in the same event list is returned.
examples: |
##### Using a action response:
```yaml
_actions: my_action.response
```
Returns: The response returned by the action.
##### Setting a action response to `state`:
```yaml
id: refresh
type: Button
events:
onClick:
- id: get_fresh_data
type: Request
skip:
_state: should_not_fetch
params: get_data
- id: set_data
type: SetState
params:
did_not_fetch_data:
_actions: get_fresh_data.skipped
```
##### Setting a returned [`JsAction`](/JsAction) response to `state`:
First register a custom JavaScript action: `getNormalizedEigenvector`
```yaml
# file: lowdefy.yaml
lowdefy: '3.16.1'
app:
html:
appendHead: |
<script type="text/javascript">
const getNormalizedEigenvector = (context, ...args) => {
const vectorLength = Math.sqrt(args.reduce((acc, curVal) => Math.pow(curVal, 2) + acc), 0);
return args.map(val => val / vectorLength );
}
window.lowdefy.registerJsAction('getNormalizedEigenvector', getNormalizedEigenvector);
</script>
```
Then, calculate the vector and update state.
```yaml
# onClick event on a block.
id: calculate
type: Button
events:
onClick:
- id: get_normalized_eigenvector
type: JsAction
params:
name: getNormalizedEigenvector
args:
- 1
- 5
- -12
- 7
- 4
- id: update_state
type: SetState
params:
normal_eigenvector:
_actions: get_normalized_eigenvector.response
```
In this example, state will now be equal to:
```yaml
normal_eigenvector:
- 0.06523280730534423
- 0.3261640365267211
- -0.7827936876641306
- 0.45662965113740955
- 0.2609312292213769
```

View File

@ -19,8 +19,7 @@ _ref:
pageId: _diff
pageTitle: _diff
filePath: operators/_diff.yaml
description: |
> The `_diff` operator is only useable on the Lowdefy server, and not on the web client. Therefore it can only be used in requests and connections.
env: Server Only
methods:
- name: deep
types: |

Some files were not shown because too many files have changed in this diff Show More