@kitconcept/volto-light-theme 1.0.0-rc.1 → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/deploy.yml +99 -0
- package/.prettierrc +12 -0
- package/CHANGELOG.md +23 -0
- package/Makefile +24 -17
- package/devops/stacks/light-theme.kitconcept.io.yml +66 -0
- package/dockerfiles/Dockerfile +12 -4
- package/dockerfiles/Dockerfile.dev +4 -0
- package/dockerfiles/docker-compose.yml +19 -5
- package/dockerfiles/helper.py +120 -0
- package/package.json +12 -2
- package/src/components/Blocks/Button/schema.js +4 -4
- package/src/components/Blocks/Teaser/schema.js +5 -0
- package/src/customizations/volto/components/theme/View/NewsItemView.jsx +57 -0
- package/src/index.js +6 -2
- package/src/theme/_bgcolor-blocks-layout.scss +3 -1
- package/src/theme/_content.scss +25 -0
- package/src/theme/_layout.scss +48 -9
- package/src/theme/_variables.scss +1 -1
- package/src/theme/blocks/_button.scss +6 -0
- package/src/theme/blocks/_listing.scss +150 -77
- package/src/theme/collections/grid.variables +6 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
name: Release and deploy
|
|
2
|
+
on:
|
|
3
|
+
- push
|
|
4
|
+
|
|
5
|
+
env:
|
|
6
|
+
ENVIRONMENT: "light-theme.kitconcept.io"
|
|
7
|
+
IMAGE_NAME: "ghcr.io/kitconcept/voltolighttheme-frontend"
|
|
8
|
+
VOLTO_VERSION: "17.0.0-alpha.16"
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
meta:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
outputs:
|
|
14
|
+
ENVIRONMENT: ${{ steps.vars.outputs.ENVIRONMENT }}
|
|
15
|
+
STACK_NAME: ${{ steps.vars.outputs.STACK_NAME }}
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout
|
|
18
|
+
uses: actions/checkout@v3
|
|
19
|
+
|
|
20
|
+
- name: Set Env Vars
|
|
21
|
+
id: vars
|
|
22
|
+
run: |
|
|
23
|
+
ENVIRONMENT=${{ env.ENVIRONMENT }}
|
|
24
|
+
echo "ENVIRONMENT=${ENVIRONMENT}" >> $GITHUB_OUTPUT
|
|
25
|
+
echo "STACK_NAME=${ENVIRONMENT//./-}" >> $GITHUB_OUTPUT
|
|
26
|
+
|
|
27
|
+
release:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
needs:
|
|
30
|
+
- meta
|
|
31
|
+
steps:
|
|
32
|
+
|
|
33
|
+
- name: Checkout
|
|
34
|
+
uses: actions/checkout@v3
|
|
35
|
+
|
|
36
|
+
- name: Docker meta
|
|
37
|
+
id: meta
|
|
38
|
+
uses: docker/metadata-action@v4
|
|
39
|
+
with:
|
|
40
|
+
images: |
|
|
41
|
+
${{ env.IMAGE_NAME }}
|
|
42
|
+
labels: |
|
|
43
|
+
org.label-schema.docker.cmd=docker run -d -p 3000:3000 ${{ env.IMAGE_NAME }}
|
|
44
|
+
flavor: |
|
|
45
|
+
latest=false
|
|
46
|
+
tags: |
|
|
47
|
+
type=ref,event=branch
|
|
48
|
+
type=sha
|
|
49
|
+
type=raw,value=latest,enable={{is_default_branch}}
|
|
50
|
+
|
|
51
|
+
- name: Set up Docker Buildx
|
|
52
|
+
uses: docker/setup-buildx-action@v2
|
|
53
|
+
|
|
54
|
+
- name: Login to GitHub Container Registry
|
|
55
|
+
uses: docker/login-action@v2
|
|
56
|
+
with:
|
|
57
|
+
registry: ghcr.io
|
|
58
|
+
username: ${{ github.actor }}
|
|
59
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
60
|
+
|
|
61
|
+
- name: Build and push
|
|
62
|
+
uses: docker/build-push-action@v3
|
|
63
|
+
with:
|
|
64
|
+
platforms: linux/amd64
|
|
65
|
+
context: ./
|
|
66
|
+
file: dockerfiles/Dockerfile
|
|
67
|
+
build-args: |
|
|
68
|
+
ADDON_NAME=@kitconcept/volto-light-theme
|
|
69
|
+
ADDON_PATH=volto-light-theme
|
|
70
|
+
VOLTO_VERSION=${{ env.VOLTO_VERSION }}
|
|
71
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
72
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
73
|
+
labels: $${{ steps.meta.outputs.labels }}
|
|
74
|
+
deploy:
|
|
75
|
+
if: ${{ github.ref == 'refs/heads/main' }}
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
needs:
|
|
78
|
+
- meta
|
|
79
|
+
- release
|
|
80
|
+
environment: ${{ needs.meta.outputs.ENVIRONMENT }}
|
|
81
|
+
steps:
|
|
82
|
+
- name: Checkout
|
|
83
|
+
uses: actions/checkout@v3
|
|
84
|
+
|
|
85
|
+
- name: Deploy to cluster
|
|
86
|
+
uses: kitconcept/docker-stack-deploy@v1.2.0
|
|
87
|
+
with:
|
|
88
|
+
registry: "ghcr.io"
|
|
89
|
+
username: ${{ github.actor }}
|
|
90
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
91
|
+
remote_host: ${{ secrets.DEPLOY_HOST }}
|
|
92
|
+
remote_port: ${{ secrets.DEPLOY_PORT }}
|
|
93
|
+
remote_user: ${{ secrets.DEPLOY_USER }}
|
|
94
|
+
remote_private_key: ${{ secrets.DEPLOY_SSH }}
|
|
95
|
+
stack_file: devops/stacks/${{ needs.meta.outputs.ENVIRONMENT }}.yml
|
|
96
|
+
stack_name: ${{ needs.meta.outputs.STACK_NAME }}
|
|
97
|
+
stack_param: ${{ github.ref_name }}
|
|
98
|
+
env_file: ${{ secrets.ENV_FILE }}
|
|
99
|
+
deploy_timeout: 480
|
package/.prettierrc
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,29 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 1.0.0-rc.3 (2023-07-10)
|
|
12
|
+
|
|
13
|
+
### Breaking
|
|
14
|
+
|
|
15
|
+
- Remove `@kitconcept/volto-blocks-grid` dependency @sneridagh [#131](https://github.com/kitconcept/volto-light-theme/pull/131)
|
|
16
|
+
|
|
17
|
+
### Bugfix
|
|
18
|
+
|
|
19
|
+
- Fix minor style bugs for Listing block @danalvrz [#130](https://github.com/kitconcept/volto-light-theme/pull/130)
|
|
20
|
+
|
|
21
|
+
### Internal
|
|
22
|
+
|
|
23
|
+
- Create deploy to https://light-theme.kitconcept.io [@ericof] [#72](https://github.com/kitconcept/volto-light-theme/pull/72)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## 1.0.0-rc.2 (2023-07-07)
|
|
27
|
+
|
|
28
|
+
### Bugfix
|
|
29
|
+
|
|
30
|
+
- Add NewsItemView @iFlamieng [#127](https://github.com/kitconcept/volto-light-theme/pull/127)
|
|
31
|
+
- Add support for margins in responsive. Improve the spacing in grids. @sneridagh [#129](https://github.com/kitconcept/volto-light-theme/pull/129)
|
|
32
|
+
|
|
33
|
+
|
|
11
34
|
## 1.0.0-rc.1 (2023-07-05)
|
|
12
35
|
|
|
13
36
|
### Bugfix
|
package/Makefile
CHANGED
|
@@ -26,36 +26,43 @@ VOLTO_VERSION=17.0.0-alpha.16
|
|
|
26
26
|
|
|
27
27
|
ADDON_NAME='@kitconcept/volto-light-theme'
|
|
28
28
|
ADDON_PATH='volto-light-theme'
|
|
29
|
-
|
|
29
|
+
COMPOSE_FILE=dockerfiles/docker-compose.yml
|
|
30
30
|
ACCEPTANCE_COMPOSE=acceptance/docker-compose.yml
|
|
31
31
|
CMD=CURRENT_DIR=${CURRENT_DIR} ADDON_NAME=${ADDON_NAME} ADDON_PATH=${ADDON_PATH} VOLTO_VERSION=${VOLTO_VERSION} PLONE_VERSION=${PLONE_VERSION} docker compose
|
|
32
|
-
DOCKER_COMPOSE=${CMD} -p ${ADDON_PATH} -f ${
|
|
32
|
+
DOCKER_COMPOSE=${CMD} -p ${ADDON_PATH} -f ${COMPOSE_FILE}
|
|
33
|
+
DEV_COMPOSE=COMPOSE_PROFILES=dev ${DOCKER_COMPOSE}
|
|
34
|
+
LIVE_COMPOSE=COMPOSE_PROFILES=dev ${DOCKER_COMPOSE}
|
|
33
35
|
ACCEPTANCE=${CMD} -p ${ADDON_PATH}-acceptance -f ${ACCEPTANCE_COMPOSE}
|
|
34
36
|
|
|
35
37
|
.PHONY: build-backend
|
|
36
38
|
build-backend: ## Build
|
|
37
39
|
@echo "$(GREEN)==> Build Backend Container $(RESET)"
|
|
38
|
-
${
|
|
40
|
+
${DEV_COMPOSE} build backend
|
|
39
41
|
|
|
40
42
|
.PHONY: start-backend
|
|
41
43
|
start-backend: ## Starts Docker backend
|
|
42
44
|
@echo "$(GREEN)==> Start Docker-based Plone Backend $(RESET)"
|
|
43
|
-
${
|
|
45
|
+
${DEV_COMPOSE} up backend -d
|
|
44
46
|
|
|
45
47
|
.PHONY: stop-backend
|
|
46
48
|
stop-backend: ## Stop Docker backend
|
|
47
49
|
@echo "$(GREEN)==> Stop Docker-based Plone Backend $(RESET)"
|
|
48
|
-
${
|
|
50
|
+
${DEV_COMPOSE} stop backend
|
|
51
|
+
|
|
52
|
+
.PHONY: build-live
|
|
53
|
+
build-live: ## Build Addon live
|
|
54
|
+
@echo "$(GREEN)==> Build Addon development container $(RESET)"
|
|
55
|
+
${LIVE_COMPOSE} build addon-live
|
|
49
56
|
|
|
50
57
|
.PHONY: build-addon
|
|
51
58
|
build-addon: ## Build Addon dev
|
|
52
59
|
@echo "$(GREEN)==> Build Addon development container $(RESET)"
|
|
53
|
-
${
|
|
60
|
+
${DEV_COMPOSE} build addon-dev
|
|
54
61
|
|
|
55
62
|
.PHONY: start-dev
|
|
56
63
|
start-dev: ## Starts Dev container
|
|
57
64
|
@echo "$(GREEN)==> Start Addon Development container $(RESET)"
|
|
58
|
-
${
|
|
65
|
+
${DEV_COMPOSE} up addon-dev
|
|
59
66
|
|
|
60
67
|
.PHONY: dev
|
|
61
68
|
dev: ## Develop the addon
|
|
@@ -72,27 +79,27 @@ help: ## Show this help.
|
|
|
72
79
|
# Dev Helpers
|
|
73
80
|
.PHONY: i18n
|
|
74
81
|
i18n: ## Sync i18n
|
|
75
|
-
${
|
|
82
|
+
${DEV_COMPOSE} run addon-dev i18n
|
|
76
83
|
|
|
77
84
|
.PHONY: format
|
|
78
85
|
format: ## Format codebase
|
|
79
|
-
${
|
|
80
|
-
${
|
|
81
|
-
${
|
|
86
|
+
${DEV_COMPOSE} run addon-dev lint:fix
|
|
87
|
+
${DEV_COMPOSE} run addon-dev prettier:fix
|
|
88
|
+
${DEV_COMPOSE} run addon-dev stylelint:fix
|
|
82
89
|
|
|
83
90
|
.PHONY: lint
|
|
84
91
|
lint: ## Lint Codebase
|
|
85
|
-
${
|
|
86
|
-
${
|
|
87
|
-
${
|
|
92
|
+
${DEV_COMPOSE} run addon-dev lint
|
|
93
|
+
${DEV_COMPOSE} run addon-dev prettier
|
|
94
|
+
${DEV_COMPOSE} run addon-dev stylelint --allow-empty-input
|
|
88
95
|
|
|
89
96
|
.PHONY: test
|
|
90
97
|
test: ## Run unit tests
|
|
91
|
-
${
|
|
98
|
+
${DEV_COMPOSE} run addon-dev test --watchAll
|
|
92
99
|
|
|
93
100
|
.PHONY: test-ci
|
|
94
101
|
test-ci: ## Run unit tests in CI
|
|
95
|
-
${
|
|
102
|
+
${DEV_COMPOSE} run -e CI=1 addon-dev test
|
|
96
103
|
|
|
97
104
|
## Acceptance
|
|
98
105
|
.PHONY: install-acceptance
|
|
@@ -126,4 +133,4 @@ status-test-acceptance-server: ## Status of Acceptance Server
|
|
|
126
133
|
|
|
127
134
|
.PHONY: debug-frontend
|
|
128
135
|
debug-frontend: ## Run bash in the Frontend container
|
|
129
|
-
${
|
|
136
|
+
${DEV_COMPOSE} run --entrypoint bash addon-dev
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
version: '3.3'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
|
|
5
|
+
frontend:
|
|
6
|
+
image: ghcr.io/kitconcept/voltolighttheme-frontend:${STACK_PARAM:-latest}
|
|
7
|
+
environment:
|
|
8
|
+
RAZZLE_INTERNAL_API_PATH: http://light-theme-kitconcept-io_backend:8080/Plone
|
|
9
|
+
depends_on:
|
|
10
|
+
- backend
|
|
11
|
+
networks:
|
|
12
|
+
- public
|
|
13
|
+
healthcheck:
|
|
14
|
+
disable: true
|
|
15
|
+
deploy:
|
|
16
|
+
replicas: 2
|
|
17
|
+
placement:
|
|
18
|
+
constraints:
|
|
19
|
+
- node.labels.type == app
|
|
20
|
+
- node.labels.env == staging
|
|
21
|
+
labels:
|
|
22
|
+
- traefik.enable=true
|
|
23
|
+
- traefik.docker.network=public
|
|
24
|
+
- traefik.constraint-label=public
|
|
25
|
+
# Service
|
|
26
|
+
- traefik.http.services.svc-lighttheme-stg-front.loadbalancer.server.port=3000
|
|
27
|
+
# Middlewares
|
|
28
|
+
# Routers
|
|
29
|
+
## light-theme.kitconcept.io
|
|
30
|
+
- traefik.http.routers.rt-lighttheme-stg-front.rule=Host(`light-theme.kitconcept.io`)
|
|
31
|
+
- traefik.http.routers.rt-lighttheme-stg-front.entrypoints=https
|
|
32
|
+
- traefik.http.routers.rt-lighttheme-stg-front.tls=true
|
|
33
|
+
- traefik.http.routers.rt-lighttheme-stg-front.tls.certresolver=le
|
|
34
|
+
- traefik.http.routers.rt-lighttheme-stg-front.service=svc-lighttheme-stg-front
|
|
35
|
+
- traefik.http.routers.rt-lighttheme-stg-front.middlewares=gzip
|
|
36
|
+
|
|
37
|
+
backend:
|
|
38
|
+
image: ghcr.io/kitconcept/voltolighttheme:latest
|
|
39
|
+
networks:
|
|
40
|
+
- public
|
|
41
|
+
deploy:
|
|
42
|
+
replicas: 1
|
|
43
|
+
placement:
|
|
44
|
+
constraints:
|
|
45
|
+
- node.labels.type == app
|
|
46
|
+
- node.labels.env == staging
|
|
47
|
+
labels:
|
|
48
|
+
- traefik.enable=true
|
|
49
|
+
- traefik.docker.network=public
|
|
50
|
+
- traefik.constraint-label=public
|
|
51
|
+
# Service
|
|
52
|
+
- traefik.http.services.svc-lighttheme-stg-backend.loadbalancer.server.port=8080
|
|
53
|
+
# Middleware
|
|
54
|
+
- "traefik.http.middlewares.mw-lighttheme-stg-backend-vhm.replacepathregex.regex=^/\\+\\+api\\+\\+($$|/.*)"
|
|
55
|
+
- "traefik.http.middlewares.mw-lighttheme-stg-backend-vhm.replacepathregex.replacement=/VirtualHostBase/https/light-theme.kitconcept.io/Plone/++api++/VirtualHostRoot/$$1"
|
|
56
|
+
# Router ++api++
|
|
57
|
+
- traefik.http.routers.rt-lighttheme-stg-backend.rule=Host(`light-theme.kitconcept.io`) && (PathPrefix(`/++api++`))
|
|
58
|
+
- traefik.http.routers.rt-lighttheme-stg-backend.entrypoints=https
|
|
59
|
+
- traefik.http.routers.rt-lighttheme-stg-backend.tls=true
|
|
60
|
+
- traefik.http.routers.rt-lighttheme-stg-backend.service=svc-lighttheme-stg-backend
|
|
61
|
+
- traefik.http.routers.rt-lighttheme-stg-backend.middlewares=gzip,mw-lighttheme-stg-backend-vhm
|
|
62
|
+
|
|
63
|
+
networks:
|
|
64
|
+
public:
|
|
65
|
+
external: true
|
|
66
|
+
driver: overlay
|
package/dockerfiles/Dockerfile
CHANGED
|
@@ -5,9 +5,17 @@ FROM plone/frontend-builder:${VOLTO_VERSION} as builder
|
|
|
5
5
|
ARG ADDON_NAME
|
|
6
6
|
ARG ADDON_PATH
|
|
7
7
|
|
|
8
|
+
ENV THEME='@kitconcept/volto-light-theme'
|
|
9
|
+
|
|
10
|
+
# Copy helper.py as /setupAddon
|
|
11
|
+
COPY dockerfiles/helper.py /setupAddon
|
|
12
|
+
|
|
13
|
+
# Copy addon code
|
|
8
14
|
COPY --chown=node:node ./ /app/src/addons/${ADDON_PATH}/
|
|
9
15
|
|
|
16
|
+
# Install
|
|
10
17
|
RUN <<EOT
|
|
18
|
+
set -e
|
|
11
19
|
/setupAddon
|
|
12
20
|
yarn install --network-timeout 1000000
|
|
13
21
|
yarn build
|
|
@@ -16,9 +24,9 @@ EOT
|
|
|
16
24
|
|
|
17
25
|
FROM plone/frontend-prod-config:${VOLTO_VERSION}
|
|
18
26
|
|
|
19
|
-
LABEL maintainer="
|
|
20
|
-
org.label-schema.name="
|
|
21
|
-
org.label-schema.description="
|
|
22
|
-
org.label-schema.vendor="
|
|
27
|
+
LABEL maintainer="kitconcept GmbH <contact@kitconcept.com>" \
|
|
28
|
+
org.label-schema.name="ghcr.io/kitconcept/lighttheme" \
|
|
29
|
+
org.label-schema.description="Volto project with @kitconcept/volto-light-theme" \
|
|
30
|
+
org.label-schema.vendor="kitconcept GmbH"
|
|
23
31
|
|
|
24
32
|
COPY --from=builder /app/ /app/
|
|
@@ -5,6 +5,9 @@ FROM plone/frontend-dev:${VOLTO_VERSION}
|
|
|
5
5
|
ARG ADDON_NAME
|
|
6
6
|
ARG ADDON_PATH
|
|
7
7
|
|
|
8
|
+
# Copy helper.py as /setupAddon
|
|
9
|
+
COPY dockerfiles/helper.py /setupAddon
|
|
10
|
+
|
|
8
11
|
# Copy linter / prettier configs
|
|
9
12
|
COPY --chown=node:node .eslintignore* .prettierignore* /app/
|
|
10
13
|
|
|
@@ -15,6 +18,7 @@ COPY --chown=node:node volto.config.js* /app/
|
|
|
15
18
|
COPY --chown=node:node package.json /app/src/addons/${ADDON_PATH}/
|
|
16
19
|
|
|
17
20
|
RUN <<EOT
|
|
21
|
+
set -e
|
|
18
22
|
/setupAddon
|
|
19
23
|
yarn install --network-timeout 1000000
|
|
20
24
|
EOT
|
|
@@ -9,7 +9,7 @@ services:
|
|
|
9
9
|
args:
|
|
10
10
|
ADDON_NAME: "${ADDON_NAME}"
|
|
11
11
|
ADDON_PATH: "${ADDON_PATH}"
|
|
12
|
-
VOLTO_VERSION: ${VOLTO_VERSION:-16}
|
|
12
|
+
VOLTO_VERSION: "${VOLTO_VERSION:-16}"
|
|
13
13
|
volumes:
|
|
14
14
|
- ${CURRENT_DIR}:/app/src/addons/${ADDON_PATH}/
|
|
15
15
|
environment:
|
|
@@ -22,11 +22,25 @@ services:
|
|
|
22
22
|
profiles:
|
|
23
23
|
- dev
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
addon-live:
|
|
26
|
+
build:
|
|
27
|
+
context: ../
|
|
28
|
+
dockerfile: ./dockerfiles/Dockerfile
|
|
29
|
+
args:
|
|
30
|
+
ADDON_NAME: "${ADDON_NAME}"
|
|
31
|
+
ADDON_PATH: "${ADDON_PATH}"
|
|
32
|
+
VOLTO_VERSION: "${VOLTO_VERSION:-16}"
|
|
27
33
|
environment:
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone
|
|
35
|
+
RAZZLE_API_PATH: http://localhost:8080/Plone
|
|
36
|
+
ports:
|
|
37
|
+
- 3000:3000
|
|
38
|
+
tty: true
|
|
39
|
+
profiles:
|
|
40
|
+
- live
|
|
41
|
+
|
|
42
|
+
backend:
|
|
43
|
+
image: ghcr.io/kitconcept/voltolighttheme:latest
|
|
30
44
|
ports:
|
|
31
45
|
- 8080:8080
|
|
32
46
|
profiles:
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""Addon support for Volto."""
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Tuple
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger("Volto Helper")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
APP_FOLDER = Path("/app").resolve()
|
|
15
|
+
PACKAGE_JSON_PATH = (APP_FOLDER / "package.json").resolve()
|
|
16
|
+
JSCONFIG_PATH = (APP_FOLDER / "jsconfig.json").resolve()
|
|
17
|
+
VOLTOCONFIGPATH = (APP_FOLDER / "volto.config.js").resolve()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
ADDON_NAME = os.environ.get("ADDON_NAME", "")
|
|
21
|
+
ADDITIONAL_ADDONS = os.environ.get("ADDITIONAL_ADDONS", "")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def add_packages_to_package_json(config: dict, packages: dict) -> dict:
|
|
25
|
+
"""Add addons to the main `package.json`."""
|
|
26
|
+
addons = config.get("addons", [])
|
|
27
|
+
workspaces = config.get("workspaces", [])
|
|
28
|
+
for pkg_name, pkg_path in packages.items():
|
|
29
|
+
if not VOLTOCONFIGPATH.exists():
|
|
30
|
+
addons.append(pkg_name)
|
|
31
|
+
workspace_path = pkg_path.replace("/src", "")
|
|
32
|
+
workspaces.append(f"src/{workspace_path}")
|
|
33
|
+
config["addons"] = addons
|
|
34
|
+
config["workspaces"] = workspaces
|
|
35
|
+
return config
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def parse_jsonconfig(config: dict) -> dict:
|
|
39
|
+
"""Parse existing `jsconfig.json`."""
|
|
40
|
+
packages = {}
|
|
41
|
+
config_paths = config.get("compilerOptions", {}).get("paths", {})
|
|
42
|
+
for pkg_name, pkg_path in config_paths.items():
|
|
43
|
+
if isinstance(pkg_path, list):
|
|
44
|
+
packages[pkg_name] = pkg_path[0]
|
|
45
|
+
return packages
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def parse_addon_name(addon_name: str) -> Tuple[str, str]:
|
|
49
|
+
"""Parse the addon name and return also its probable path."""
|
|
50
|
+
if addon_name.startswith("@"):
|
|
51
|
+
_, path = addon_name.split("/")
|
|
52
|
+
return addon_name, path
|
|
53
|
+
return addon_name, addon_name
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def addon_to_package_json(config: dict, addon_name: str, addon_path: str) -> dict:
|
|
57
|
+
"""Add a single addon to main `package.json`."""
|
|
58
|
+
project_addons = config["addons"]
|
|
59
|
+
project_dependencies = config["dependencies"]
|
|
60
|
+
# Process package.json for the addon
|
|
61
|
+
workspace_path = f"src/addons/{addon_path}"
|
|
62
|
+
addon_path = (APP_FOLDER / workspace_path).resolve()
|
|
63
|
+
addon_config = json.load(open(addon_path / "package.json"))
|
|
64
|
+
# Process peerDependencies
|
|
65
|
+
peer_dependencies = addon_config.get("peerDependencies", {})
|
|
66
|
+
for dependency_name, version in peer_dependencies.items():
|
|
67
|
+
if dependency_name in project_dependencies:
|
|
68
|
+
continue
|
|
69
|
+
project_dependencies[dependency_name] = version
|
|
70
|
+
# Process peerAddons
|
|
71
|
+
peer_addons = addon_config.get("peerAddons", [])
|
|
72
|
+
for name in peer_addons:
|
|
73
|
+
if name in project_addons:
|
|
74
|
+
continue
|
|
75
|
+
project_addons.append(name)
|
|
76
|
+
# Add our addon to addons and to workspaces
|
|
77
|
+
project_addons.append(addon_name)
|
|
78
|
+
workspaces = config.get("workspaces", [])
|
|
79
|
+
workspaces.append(workspace_path)
|
|
80
|
+
|
|
81
|
+
config["addons"] = project_addons
|
|
82
|
+
config["dependencies"] = project_dependencies
|
|
83
|
+
config["workspaces"] = workspaces
|
|
84
|
+
return config
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def addon_to_jsconfig_json(config: dict, addon_name: str, addon_path: str) -> dict:
|
|
88
|
+
"""Add a single addon to `jsconfig.json`."""
|
|
89
|
+
if "compilerOptions" not in config:
|
|
90
|
+
config["compilerOptions"] = {}
|
|
91
|
+
if "paths" not in config:
|
|
92
|
+
config["compilerOptions"]["paths"] = {}
|
|
93
|
+
|
|
94
|
+
config["compilerOptions"]["paths"][addon_name] = [f"addons/{addon_path}/src"]
|
|
95
|
+
return config
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if ADDON_NAME:
|
|
99
|
+
logger.info("Processing the ADDON_NAME variable.")
|
|
100
|
+
SETTINGS = (
|
|
101
|
+
(addon_to_package_json, PACKAGE_JSON_PATH),
|
|
102
|
+
(addon_to_jsconfig_json, JSCONFIG_PATH),
|
|
103
|
+
)
|
|
104
|
+
addon_name, addon_path = parse_addon_name(ADDON_NAME)
|
|
105
|
+
for func, path in SETTINGS:
|
|
106
|
+
data = func(json.load(open(path)), addon_name=addon_name, addon_path=addon_path)
|
|
107
|
+
json.dump(data, open(path, "w"), indent=2)
|
|
108
|
+
else:
|
|
109
|
+
packages = {}
|
|
110
|
+
if JSCONFIG_PATH.exists():
|
|
111
|
+
packages = parse_jsonconfig(json.load(open(JSCONFIG_PATH)))
|
|
112
|
+
|
|
113
|
+
if not packages:
|
|
114
|
+
logger.warning("Existing jsconfig.json does not contain packages.")
|
|
115
|
+
else:
|
|
116
|
+
logger.info("Processing existing jsconfig.json.")
|
|
117
|
+
package_json = json.load(open(PACKAGE_JSON_PATH))
|
|
118
|
+
# Process package_json
|
|
119
|
+
package_json = add_packages_to_package_json(package_json, packages)
|
|
120
|
+
json.dump(package_json, open(PACKAGE_JSON_PATH, "w"), indent=2)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitconcept/volto-light-theme",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.3",
|
|
4
4
|
"description": "Volto Light Theme by kitconcept",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -36,11 +36,21 @@
|
|
|
36
36
|
"postcss-scss": "4.0.6",
|
|
37
37
|
"prettier": "2.0.5",
|
|
38
38
|
"razzle-plugin-scss": "4.2.18",
|
|
39
|
-
"release-it": "
|
|
39
|
+
"release-it": "^16.1.0",
|
|
40
40
|
"stylelint-config-prettier": "9.0.4",
|
|
41
41
|
"stylelint-config-sass-guidelines": "9.0.1",
|
|
42
42
|
"stylelint-prettier": "1.1.2"
|
|
43
43
|
},
|
|
44
|
+
"peerAddons": [
|
|
45
|
+
"@eeacms/volto-accordion-block",
|
|
46
|
+
"@kitconcept/volto-button-block",
|
|
47
|
+
"@kitconcept/volto-dsgvo-banner",
|
|
48
|
+
"@kitconcept/volto-heading-block",
|
|
49
|
+
"@kitconcept/volto-image-block",
|
|
50
|
+
"@kitconcept/volto-introduction-block",
|
|
51
|
+
"@kitconcept/volto-separator-block",
|
|
52
|
+
"@kitconcept/volto-slider-block"
|
|
53
|
+
],
|
|
44
54
|
"peerDependencies": {
|
|
45
55
|
"@eeacms/volto-accordion-block": "^9.0.0",
|
|
46
56
|
"@kitconcept/volto-button-block": "^2.1.0",
|
|
@@ -2,9 +2,9 @@ import { defineMessages } from 'react-intl';
|
|
|
2
2
|
import { defaultStylingSchema } from '../schema';
|
|
3
3
|
|
|
4
4
|
const messages = defineMessages({
|
|
5
|
-
|
|
6
|
-
id: '
|
|
7
|
-
defaultMessage: '
|
|
5
|
+
BlockWidth: {
|
|
6
|
+
id: 'Block Width',
|
|
7
|
+
defaultMessage: 'Block Width',
|
|
8
8
|
},
|
|
9
9
|
});
|
|
10
10
|
|
|
@@ -18,7 +18,7 @@ export const ButtonStylingSchema = ({ schema, formData, intl }) => {
|
|
|
18
18
|
|
|
19
19
|
schema.properties.styles.schema.properties.buttonAlign = {
|
|
20
20
|
widget: 'align',
|
|
21
|
-
title: intl.formatMessage(messages.
|
|
21
|
+
title: intl.formatMessage(messages.BlockWidth),
|
|
22
22
|
actions: ['center', 'wide'],
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -3,3 +3,8 @@ export const teaserSchemaEnhancer = ({ schema, formData, intl }) => {
|
|
|
3
3
|
|
|
4
4
|
return schema;
|
|
5
5
|
};
|
|
6
|
+
|
|
7
|
+
export const gridTeaserDisableStylingSchema = ({ schema, formData, intl }) => {
|
|
8
|
+
schema.fieldsets = schema.fieldsets.filter((item) => item.id !== 'styling');
|
|
9
|
+
return schema;
|
|
10
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OVERRIDE NewsItemView.jsx
|
|
3
|
+
* REASON: BFS theme
|
|
4
|
+
* DATE: 2023-07-04
|
|
5
|
+
* DEVELOPER: @IFlameing
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* NewsItemView view component.
|
|
10
|
+
* @module components/theme/View/NewsItemView
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import PropTypes from 'prop-types';
|
|
15
|
+
import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
|
|
16
|
+
import { FormattedDate } from '@plone/volto/components';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* NewsItemView view component class.
|
|
20
|
+
* @function NewsItemView
|
|
21
|
+
* @params {object} content Content object.
|
|
22
|
+
* @returns {string} Markup of the component.
|
|
23
|
+
*/
|
|
24
|
+
const NewsItemView = ({ content }) => {
|
|
25
|
+
return (
|
|
26
|
+
<div id="page-document" className="ui container viewwrapper event-view">
|
|
27
|
+
<div className="dates">
|
|
28
|
+
{content?.effective ? (
|
|
29
|
+
<span className="day">
|
|
30
|
+
<FormattedDate date={content?.effective} />{' '}
|
|
31
|
+
</span>
|
|
32
|
+
) : (
|
|
33
|
+
<span className="day">No date</span>
|
|
34
|
+
)}{' '}
|
|
35
|
+
<span className="headtitle">| {content?.head_title}</span>
|
|
36
|
+
</div>
|
|
37
|
+
<RenderBlocks content={content} />
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Property types.
|
|
44
|
+
* @property {Object} propTypes Property types.
|
|
45
|
+
* @static
|
|
46
|
+
*/
|
|
47
|
+
NewsItemView.propTypes = {
|
|
48
|
+
content: PropTypes.shape({
|
|
49
|
+
title: PropTypes.string,
|
|
50
|
+
description: PropTypes.string,
|
|
51
|
+
text: PropTypes.shape({
|
|
52
|
+
data: PropTypes.string,
|
|
53
|
+
}),
|
|
54
|
+
}).isRequired,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default NewsItemView;
|
package/src/index.js
CHANGED
|
@@ -3,8 +3,7 @@ import { defineMessages } from 'react-intl';
|
|
|
3
3
|
import { composeSchema, getPreviousNextBlock } from '@plone/volto/helpers';
|
|
4
4
|
import { defaultStylingSchema } from './components/Blocks/schema';
|
|
5
5
|
import { teaserSchemaEnhancer } from './components/Blocks/Teaser/schema';
|
|
6
|
-
|
|
7
|
-
import { gridTeaserDisableStylingSchema } from '@kitconcept/volto-blocks-grid/components/Teaser/schema';
|
|
6
|
+
import { gridTeaserDisableStylingSchema } from '@plone/volto/components/manage/Blocks/Teaser/schema';
|
|
8
7
|
|
|
9
8
|
import ContainerQueriesPolyfill from './components/CQPolyfill';
|
|
10
9
|
import Container from './components/Atoms/Container/Container';
|
|
@@ -88,6 +87,11 @@ const applyConfig = (config) => {
|
|
|
88
87
|
styles.push('is--last--of--block-type');
|
|
89
88
|
}
|
|
90
89
|
|
|
90
|
+
// Inject a class depending if it has a headline
|
|
91
|
+
if (data?.headline || previousBlock?.['@type'] === 'heading') {
|
|
92
|
+
styles.push('has--headline');
|
|
93
|
+
}
|
|
94
|
+
|
|
91
95
|
// Given a StyleWrapper defined `backgroundColor` style
|
|
92
96
|
const previousColor =
|
|
93
97
|
previousBlock?.styles?.backgroundColor ?? 'transparent';
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
margin-bottom: $grid-block-vertical-spacing-bottom;
|
|
32
32
|
}
|
|
33
33
|
&.next--is--same--block-type.next--has--same--backgroundColor {
|
|
34
|
-
|
|
34
|
+
// We rely on the grid gutter to keep the vertical spacing in case grid + grid
|
|
35
|
+
// So here we cancel the default block margin-bottom
|
|
36
|
+
margin-bottom: 0;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
package/src/theme/_content.scss
CHANGED
|
@@ -5,3 +5,28 @@
|
|
|
5
5
|
padding: 0;
|
|
6
6
|
margin-top: 0;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
.contenttype-news-item {
|
|
10
|
+
.documentFirstHeading {
|
|
11
|
+
margin-top: 0px;
|
|
12
|
+
}
|
|
13
|
+
.blocks-group-wrapper {
|
|
14
|
+
padding-top: 0px;
|
|
15
|
+
}
|
|
16
|
+
.dates {
|
|
17
|
+
max-width: var(--default-container-width) !important;
|
|
18
|
+
margin-top: 40px;
|
|
19
|
+
margin-right: auto;
|
|
20
|
+
margin-bottom: 40px;
|
|
21
|
+
margin-left: auto;
|
|
22
|
+
.day,
|
|
23
|
+
.headtitle {
|
|
24
|
+
font-size: 18px;
|
|
25
|
+
|
|
26
|
+
font-weight: 700;
|
|
27
|
+
letter-spacing: 1px;
|
|
28
|
+
line-height: 24px;
|
|
29
|
+
text-transform: uppercase;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/theme/_layout.scss
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
--narrow-container-width: 620px;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
// Container queries still do not work with CSS properties
|
|
7
|
+
// Container queries still do not work with CSS custom properties
|
|
8
8
|
// They should be exact numbers
|
|
9
9
|
// For now, maintain in sync with the above
|
|
10
|
-
$layout-container-width: 1440px;
|
|
11
|
-
$default-container-width: 940px;
|
|
12
|
-
$narrow-container-width: 620px;
|
|
10
|
+
$layout-container-width: 1440px !default;
|
|
11
|
+
$default-container-width: 940px !default;
|
|
12
|
+
$narrow-container-width: 620px !default;
|
|
13
13
|
|
|
14
14
|
@mixin narrow-container-width() {
|
|
15
15
|
max-width: var(--narrow-container-width);
|
|
@@ -21,6 +21,13 @@ $narrow-container-width: 620px;
|
|
|
21
21
|
max-width: var(--default-container-width);
|
|
22
22
|
margin-right: auto;
|
|
23
23
|
margin-left: auto;
|
|
24
|
+
|
|
25
|
+
// This is mostly aesthetical if you don't want to "see" the jump
|
|
26
|
+
// but a nice animation instead - PoC (WIP)
|
|
27
|
+
// @media only screen and (max-width: #{$default-container-width + 5px}) {
|
|
28
|
+
// margin-right: 5px;
|
|
29
|
+
// margin-left: 5px;
|
|
30
|
+
// }
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
@mixin layout-container-width() {
|
|
@@ -29,11 +36,24 @@ $narrow-container-width: 620px;
|
|
|
29
36
|
margin-left: auto;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
// One still cannot use
|
|
39
|
+
// One still cannot use CSS custom properties directly on @container queries
|
|
33
40
|
@mixin adjustMarginsToContainer($width) {
|
|
41
|
+
// Next two ones are mostly aesthetical if you don't want to "see" the jump - PoC (WIP)
|
|
42
|
+
// transition: margin 1s ease;
|
|
43
|
+
|
|
44
|
+
// @container (max-width: #{$width + 5px}) {
|
|
45
|
+
// margin-right: 5px;
|
|
46
|
+
// margin-left: 5px;
|
|
47
|
+
// }
|
|
48
|
+
|
|
49
|
+
// @container (max-width: #{$width}) {
|
|
50
|
+
// margin-right: 0px;
|
|
51
|
+
// margin-left: 0px;
|
|
52
|
+
// }
|
|
53
|
+
|
|
34
54
|
@container (max-width: #{$width - 1}) {
|
|
35
|
-
margin-right:
|
|
36
|
-
margin-left:
|
|
55
|
+
margin-right: 20px;
|
|
56
|
+
margin-left: 20px;
|
|
37
57
|
}
|
|
38
58
|
}
|
|
39
59
|
|
|
@@ -127,7 +147,9 @@ footer {
|
|
|
127
147
|
& > pre,
|
|
128
148
|
& > .block.code {
|
|
129
149
|
@include narrow-container-width();
|
|
130
|
-
|
|
150
|
+
// Why was this for? Removing for now (Victor: 2023-07-06)
|
|
151
|
+
// @include adjustMarginsToContainer($narrow-container-width + 2 * 36px);
|
|
152
|
+
@include adjustMarginsToContainer($narrow-container-width);
|
|
131
153
|
}
|
|
132
154
|
|
|
133
155
|
& > h1.documentFirstHeading,
|
|
@@ -146,6 +168,7 @@ footer {
|
|
|
146
168
|
& > .table-of-contents,
|
|
147
169
|
& > .slate blockquote {
|
|
148
170
|
@include default-container-width();
|
|
171
|
+
@include adjustMarginsToContainer($default-container-width);
|
|
149
172
|
}
|
|
150
173
|
|
|
151
174
|
& > .block.teaser,
|
|
@@ -234,7 +257,18 @@ footer {
|
|
|
234
257
|
.block.gridBlock .grid-items,
|
|
235
258
|
.block.gridBlock h2.headline {
|
|
236
259
|
@include default-container-width();
|
|
237
|
-
|
|
260
|
+
// Adding 2 * 20px (one for each side) we force the container to extend the value of
|
|
261
|
+
// the gutter
|
|
262
|
+
max-width: calc(var(--default-container-width) + 2 * 20px);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.block.gridBlock {
|
|
266
|
+
.ui.grid > .column:not(.row):first-child {
|
|
267
|
+
padding-left: 20px;
|
|
268
|
+
}
|
|
269
|
+
.ui.grid > .column:not(.row):last-child {
|
|
270
|
+
padding-right: 20px;
|
|
271
|
+
}
|
|
238
272
|
}
|
|
239
273
|
|
|
240
274
|
// Fix for Image Grid with only one image
|
|
@@ -252,6 +286,11 @@ body.has-toolbar.has-sidebar .block .ui.basic.button.delete-button {
|
|
|
252
286
|
margin-right: -30px !important;
|
|
253
287
|
}
|
|
254
288
|
|
|
289
|
+
// Listings edge case, conflicting with Pastanaga CSS
|
|
290
|
+
.listing-item {
|
|
291
|
+
width: initial;
|
|
292
|
+
}
|
|
293
|
+
|
|
255
294
|
#page-add,
|
|
256
295
|
#page-edit {
|
|
257
296
|
.block-editor-accordion {
|
|
@@ -1,111 +1,184 @@
|
|
|
1
1
|
// Listing Block
|
|
2
|
-
.block.listing
|
|
3
|
-
.
|
|
4
|
-
|
|
2
|
+
.block.listing {
|
|
3
|
+
&.next--has--same--backgroundColor.next--is--same--block-type,
|
|
4
|
+
&.next--is--__button {
|
|
5
|
+
.listing-item:last-child {
|
|
6
|
+
padding-bottom: 40px !important;
|
|
7
|
+
border-bottom: 1px solid $black !important;
|
|
8
|
+
}
|
|
5
9
|
}
|
|
10
|
+
|
|
6
11
|
.listing-item {
|
|
7
|
-
padding-bottom: 40px;
|
|
12
|
+
padding-bottom: 40px !important;
|
|
8
13
|
border-bottom: 1px solid $black;
|
|
9
14
|
margin-bottom: 40px;
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@include text-heading-h2();
|
|
16
|
-
}
|
|
17
|
-
p {
|
|
18
|
-
margin-bottom: 0;
|
|
19
|
-
@include body-text();
|
|
20
|
-
}
|
|
21
|
-
p:empty {
|
|
22
|
-
display: none;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
16
|
+
&:last-child:not(> .column) {
|
|
17
|
+
padding-bottom: 0 !important;
|
|
18
|
+
border-bottom: none !important;
|
|
19
|
+
margin-bottom: 0;
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
|
-
}
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
margin-bottom: 40px;
|
|
34
|
-
img {
|
|
35
|
-
width: 25%;
|
|
36
|
-
height: min-content;
|
|
37
|
-
aspect-ratio: $aspect-ratio;
|
|
23
|
+
// Default variation
|
|
24
|
+
&.default {
|
|
25
|
+
.headline {
|
|
26
|
+
@include block-title();
|
|
38
27
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
|
|
29
|
+
.listing-item {
|
|
30
|
+
a {
|
|
31
|
+
.listing-body {
|
|
32
|
+
h2 {
|
|
33
|
+
color: $black;
|
|
34
|
+
@include text-heading-h2();
|
|
35
|
+
}
|
|
36
|
+
p {
|
|
37
|
+
margin-bottom: 0;
|
|
38
|
+
@include body-text();
|
|
39
|
+
}
|
|
40
|
+
p:empty {
|
|
41
|
+
display: none;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
|
-
}
|
|
46
47
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
// Summary variation
|
|
49
|
+
&.summary {
|
|
50
|
+
&.next--has--same--backgroundColor {
|
|
51
|
+
.listing-item:last-child {
|
|
52
|
+
padding-bottom: 40px;
|
|
53
|
+
border-bottom: 1px solid $black !important;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
.listing-item {
|
|
57
|
+
padding-top: 0 !important;
|
|
58
|
+
|
|
59
|
+
img {
|
|
60
|
+
width: 25%;
|
|
61
|
+
height: min-content;
|
|
62
|
+
aspect-ratio: $aspect-ratio;
|
|
63
|
+
}
|
|
64
|
+
h3 {
|
|
65
|
+
margin-bottom: 40px;
|
|
66
|
+
color: $black;
|
|
67
|
+
@include text-heading-h2();
|
|
68
|
+
}
|
|
54
69
|
}
|
|
55
70
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
|
|
72
|
+
// Grid variation
|
|
73
|
+
&.grid {
|
|
74
|
+
&.next--has--same--backgroundColor.next--is--same--block-type,
|
|
75
|
+
&.next--is--__button {
|
|
76
|
+
.listing-item:last-child {
|
|
77
|
+
padding-bottom: 0 !important;
|
|
78
|
+
border-bottom: none !important;
|
|
79
|
+
}
|
|
62
80
|
}
|
|
63
|
-
margin-bottom: 0;
|
|
64
81
|
|
|
65
|
-
.
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
.items {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-wrap: wrap;
|
|
68
85
|
@media only screen and (max-width: $tablet-breakpoint) {
|
|
69
|
-
|
|
86
|
+
flex-direction: column;
|
|
70
87
|
}
|
|
71
|
-
background-color: $lightgrey;
|
|
72
88
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
width: 100%;
|
|
76
|
-
aspect-ratio: $aspect-ratio;
|
|
89
|
+
.headline {
|
|
90
|
+
@include block-title();
|
|
77
91
|
}
|
|
92
|
+
.listing-item {
|
|
93
|
+
@media only screen and (min-width: $tablet-breakpoint) {
|
|
94
|
+
width: 50%;
|
|
78
95
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
&:nth-child(2n) {
|
|
97
|
+
.card-container {
|
|
98
|
+
margin-left: 0.5rem;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
82
101
|
|
|
83
|
-
|
|
84
|
-
|
|
102
|
+
&:nth-child(2n + 1) {
|
|
103
|
+
.card-container {
|
|
104
|
+
margin-right: 0.5rem;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
85
107
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
&:last-child,
|
|
109
|
+
&:nth-last-child(2):not(:nth-child(2n)) {
|
|
110
|
+
.card-container {
|
|
111
|
+
margin-bottom: 0 !important;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&:first-child,
|
|
116
|
+
&:nth-child(2) {
|
|
117
|
+
.card-container {
|
|
118
|
+
margin-top: 0 !important;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
93
121
|
}
|
|
94
122
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
123
|
+
padding-bottom: 0 !important;
|
|
124
|
+
border-bottom: none !important;
|
|
125
|
+
margin-bottom: 0 !important;
|
|
126
|
+
|
|
127
|
+
&:last-child:nth-child(2n + 1) {
|
|
128
|
+
margin-left: 0 !important;
|
|
99
129
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
130
|
+
|
|
131
|
+
.card-container {
|
|
132
|
+
width: 100%;
|
|
133
|
+
margin-top: 0.5rem;
|
|
134
|
+
margin-bottom: 0.5rem;
|
|
135
|
+
background-color: $lightgrey;
|
|
136
|
+
@media only screen and (max-width: $tablet-breakpoint) {
|
|
137
|
+
margin-left: 0;
|
|
138
|
+
}
|
|
103
139
|
}
|
|
104
|
-
|
|
105
|
-
|
|
140
|
+
|
|
141
|
+
img.grid-item-image {
|
|
142
|
+
width: 100%;
|
|
143
|
+
margin: 0;
|
|
144
|
+
aspect-ratio: $aspect-ratio;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.grid-item {
|
|
148
|
+
margin-top: 40px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.content {
|
|
152
|
+
padding: 0 20px 40px 20px;
|
|
153
|
+
|
|
154
|
+
.headline {
|
|
155
|
+
padding: 0 !important;
|
|
156
|
+
margin-bottom: 20px;
|
|
157
|
+
color: $black;
|
|
158
|
+
letter-spacing: 1px;
|
|
159
|
+
text-transform: uppercase;
|
|
160
|
+
@include headtitle1();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
h2 {
|
|
164
|
+
margin: 0 0 20px 0;
|
|
165
|
+
color: $black;
|
|
166
|
+
@include text-heading-h3();
|
|
167
|
+
}
|
|
168
|
+
p {
|
|
169
|
+
margin-bottom: 0;
|
|
170
|
+
@include body-text();
|
|
171
|
+
}
|
|
172
|
+
p:empty {
|
|
173
|
+
display: none;
|
|
174
|
+
}
|
|
106
175
|
}
|
|
107
176
|
}
|
|
108
177
|
}
|
|
178
|
+
|
|
179
|
+
&.previous--is--same--block-type.previous--has--same--backgroundColor:not(.has--headline) {
|
|
180
|
+
margin-top: 200px;
|
|
181
|
+
}
|
|
109
182
|
}
|
|
110
183
|
|
|
111
184
|
#page-add .block-editor-listing.has--backgroundColor--grey,
|