Skip to content

Commit 3dfea05

Browse files
committed
feat: block builder components and site nav
1 parent c5738df commit 3dfea05

27 files changed

+1404
-193
lines changed

.eslintrc.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module.exports = {
1010
ignorePatterns: [
1111
'.nuxt/',
1212
'.output/',
13-
'dist/'
13+
'dist/',
14+
'.stories.js'
1415
],
1516
rules: {
1617
'no-console': process.env.NODE_ENV !== 'development' ? 'error' : 'off',

assets/scss/theme/typography.scss

-10
Original file line numberDiff line numberDiff line change
@@ -173,35 +173,25 @@ $fontAssetPath: 'assets/fonts';
173173
line-height: leading(21, 18);
174174
font-weight: 500;
175175
letter-spacing: 0.03em;
176-
color: var(--link-color);
177176
@include small {
178177
font-size: toRem(14);
179178
line-height: leading(26, 14);
180179
font-weight: 500;
181180
letter-spacing: 0.03em;
182181
}
183-
&:hover {
184-
color: var(--link-hover-color);
185-
transition: color .25s ease;
186-
}
187182
}
188183

189184
@mixin b2 { // Secondary button styles
190185
font-size: toRem(16);
191186
line-height: leading(24, 16);
192187
font-weight: 600;
193188
letter-spacing: 0.01em;
194-
color: var(--link-color);
195189
@include small {
196190
font-size: toRem(14);
197191
line-height: leading(21, 14);
198192
font-weight: 600;
199193
letter-spacing: 0.01em;
200194
}
201-
&:hover {
202-
color: var(--link-hover-color);
203-
transition: color .25s ease;
204-
}
205195
}
206196

207197
@mixin navButton {

assets/scss/theme/utilities.scss

+34-37
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/*
1111
* General layout spacing settings
1212
*/
13-
// $siteHeaderHeight: toRem(78);
13+
$siteHeaderHeight: toRem(78);
1414

1515
// ===================================================================== Colours
1616

@@ -124,42 +124,6 @@ $tundora: #414141;
124124
}
125125
}
126126

127-
/*
128-
* Update color variables below with newly added variables declared above
129-
*/
130-
@mixin selection-dark {
131-
::-moz-selection { background: $alto; color: $codGray; }
132-
::selection { background: $alto; color: $codGray; }
133-
}
134-
135-
@mixin selection-light {
136-
::-moz-selection { background: $alto; color: $codGray; }
137-
::selection { background: $alto; color: $codGray; }
138-
}
139-
140-
@mixin gradientText {
141-
@include sageWhiteGradient;
142-
background-clip: text;
143-
-moz-background-clip: text;
144-
-webkit-text-fill-color: transparent;
145-
-moz-text-fill-color: transparent;
146-
text-fill-color: transparent;
147-
// IE11 fix
148-
@include IE10and11 {
149-
background: none;
150-
}
151-
&::-moz-selection {
152-
-webkit-text-fill-color: $codGray;
153-
-moz-text-fill-color: $codGray;
154-
text-fill-color: $codGray;
155-
}
156-
&::selection {
157-
-webkit-text-fill-color: $codGray;
158-
-moz-text-fill-color: $codGray;
159-
text-fill-color: $codGray;
160-
}
161-
}
162-
163127
// ------------------------------------------------------------------- Gradients
164128
@mixin sageWhiteGradient_Basic {
165129
background: linear-gradient(278deg, $alto 10.02%, $sageGreen 86.99%);
@@ -224,3 +188,36 @@ $tundora: #414141;
224188
@include blurredBackdrop;
225189
@include gradientBorder($gradientAngle);
226190
}
191+
192+
@mixin selection-dark {
193+
::-moz-selection { background: $alto; color: $codGray; }
194+
::selection { background: $alto; color: $codGray; }
195+
}
196+
197+
@mixin selection-light {
198+
::-moz-selection { background: $alto; color: $codGray; }
199+
::selection { background: $alto; color: $codGray; }
200+
}
201+
202+
@mixin gradientText {
203+
background: linear-gradient(278deg, #D4D4D4 10.02%, #A6C888 86.99%);
204+
background-clip: text;
205+
-moz-background-clip: text;
206+
-webkit-text-fill-color: transparent;
207+
-moz-text-fill-color: transparent;
208+
text-fill-color: transparent;
209+
// IE11 fix
210+
@include IE10and11 {
211+
background: none;
212+
}
213+
&::-moz-selection {
214+
-webkit-text-fill-color: $codGray;
215+
-moz-text-fill-color: $codGray;
216+
text-fill-color: $codGray;
217+
}
218+
&::selection {
219+
-webkit-text-fill-color: $codGray;
220+
-moz-text-fill-color: $codGray;
221+
text-fill-color: $codGray;
222+
}
223+
}
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable */
2+
import BlockBuilder from './block-builder.vue'
3+
import TextBlock from './text-block.vue'
4+
import ImageBlock from './image-block.vue'
5+
6+
export default {
7+
title: 'Blocks/BlockBuilder',
8+
component: BlockBuilder,
9+
parameters: {
10+
docs: {
11+
description: {
12+
component: 'Grid: https://gridlex.devlint.fr/.'
13+
}
14+
}
15+
}
16+
}
17+
18+
const defaultTemplate = {
19+
components: {
20+
TextBlock,
21+
ImageBlock,
22+
BlockBuilder
23+
},
24+
template: '<BlockBuilder :sections="sections" />',
25+
props: {
26+
sections: {}
27+
}
28+
}
29+
30+
export const Default = args => defaultTemplate
31+
Default.args = {
32+
sections: {
33+
left_image: {
34+
grid: ['middle', 'center', 'noGutter'],
35+
col_1: {
36+
src: 'https://dummyimage.com/440x580',
37+
type: 'image_block',
38+
cols: {
39+
num: 'col-4_lg-5_md-12',
40+
push_left: '',
41+
push_right: 'off-1_md-0'
42+
}
43+
},
44+
col_2: {
45+
heading: 'Studio',
46+
description: 'We work with people who’ve inherited work, that doesn’t work. It usually starts with an itch and turns into a scratch—a product offering that needs to be recalibrated, fixing a Frankenstein website, elevating your UI, bridging conversion needs with user experience, reclaiming a software build that isn’t going the way you wanted, or creating a visual identity that people want to engage with.',
47+
type: 'text_block',
48+
cols: {
49+
num: 'col-5_lg-6_md-12',
50+
push_left: '',
51+
push_right: ''
52+
}
53+
}
54+
}
55+
}
56+
}

components/blocks/block-builder.vue

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<template>
2+
<div class="sectionals">
3+
4+
<div
5+
v-for="section in sections"
6+
:key="section.id">
7+
8+
<section v-if="!section.hide" :id="section.slug" :class="['sectional', section.id]">
9+
<!-- ============================================ [Section] Off Grid -->
10+
<div
11+
v-if="section.off_grid"
12+
:id="`${section.id}-background`"
13+
class="section-background">
14+
15+
<component
16+
:is="component.name"
17+
v-for="(component, i) in section.off_grid"
18+
:key="`${section.id}-background-${i}`"
19+
v-bind="component.props" />
20+
21+
</div>
22+
23+
<!-- ================================================ [Section] Grid -->
24+
<div :class="[getGridClasses(section.grid), section.classNames]">
25+
<template v-for="(block, blockId) in section">
26+
<div
27+
v-if="blockAllowed(blockId)"
28+
:key="blockId"
29+
:class="[getColumnCount(block)]"
30+
:data-block-id="blockId"
31+
:data-push-left="getColumnPushCount(block, 'left')"
32+
:data-push-right="getColumnPushCount(block, 'right')">
33+
<div class="column-content">
34+
35+
<!-- ======================================== [Block] Custom -->
36+
<template v-if="block.type === 'custom'">
37+
<component
38+
:is="component.name"
39+
v-for="(component, componentKey) in block.customizations"
40+
:key="componentKey"
41+
v-bind="component.props" />
42+
</template>
43+
44+
<!-- ======================================= [Block] Dynamic -->
45+
<component
46+
:is="getComponentName(block)"
47+
v-else-if="block.type !== 'sectional'"
48+
v-bind="{ block }" />
49+
50+
<!-- ===================== Recursive Sectional/Block imports -->
51+
<!-- <BlockBuilder
52+
v-else
53+
:sections="block.sections" /> -->
54+
55+
</div>
56+
</div>
57+
</template>
58+
</div>
59+
</section>
60+
</div>
61+
62+
</div>
63+
</template>
64+
65+
<script>
66+
import TextBlock from '@/components/blocks/text-block'
67+
import ImageBlock from '@/components/blocks/image-block'
68+
import MarkdownBlock from '@/components/blocks/markdown-block'
69+
// import BlockBuilder from '@/components/blocks/block-builder'
70+
71+
export default {
72+
name: 'BlockBuilder',
73+
74+
components: {
75+
TextBlock,
76+
ImageBlock,
77+
// BlockBuilder,
78+
MarkdownBlock
79+
},
80+
81+
props: {
82+
sections: {
83+
type: Object,
84+
required: true
85+
}
86+
},
87+
88+
methods: {
89+
getGridClasses (blockGrid) {
90+
const classList = ['grid']
91+
if (typeof blockGrid === 'object' && Array.isArray(blockGrid) && blockGrid.length > 0) {
92+
blockGrid.forEach(className => classList.push(`-${className}`))
93+
}
94+
return classList.join('')
95+
},
96+
blockAllowed (blockId) {
97+
return !['grid', 'classNames', 'off_grid', 'slug', 'hide', 'id'].includes(blockId)
98+
},
99+
getColumnCount (block) {
100+
return block.cols.num
101+
},
102+
getColumnPushCount (block, direction) {
103+
return block.cols.hasOwnProperty(`push_${direction}`) ? block.cols[`push_${direction}`] : undefined
104+
},
105+
getComponentName (block) {
106+
const type = block.type
107+
let name = ''
108+
switch (type) {
109+
case 'text_block' : name = 'TextBlock'; break
110+
case 'image_block' : name = 'ImageBlock'; break
111+
case 'markdown_block': name = 'MarkdownBlock'; break
112+
case 'custom' : name = block.component; break
113+
}
114+
return name
115+
}
116+
}
117+
}
118+
</script>

components/blocks/card-list-block.vue

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<template>
2+
<div class="card-list-block">
3+
<div :class="grid">
4+
<div
5+
v-for="(card, i) in cards"
6+
:key="`card-col-${i}`"
7+
:class="columns">
8+
9+
<template v-if="Array.isArray(card)">
10+
<Card
11+
v-for="(minicard, j) in card"
12+
:key="`minicard-${j}`"
13+
:card="minicard" />
14+
</template>
15+
16+
<Card v-else :card="card" />
17+
18+
</div>
19+
</div>
20+
</div>
21+
</template>
22+
23+
<script>
24+
// ====================================================================== Import
25+
import Card from '@/components/card'
26+
27+
// ====================================================================== Export
28+
export default {
29+
name: 'CardListBlock',
30+
31+
components: {
32+
Card
33+
},
34+
35+
props: {
36+
block: {
37+
type: Object,
38+
required: true,
39+
default: () => ({})
40+
}
41+
},
42+
43+
computed: {
44+
cards () {
45+
const sortKey = this.block.sort_key
46+
if (this.block.alphabetize && sortKey) {
47+
return [...this.block.cards].sort((a, b) => {
48+
if (a[sortKey].toLowerCase() < b[sortKey].toLowerCase()) { return -1 }
49+
if (a[sortKey].toLowerCase() > b[sortKey].toLowerCase()) { return 1 }
50+
return 0
51+
})
52+
}
53+
return this.block.cards
54+
},
55+
grid () {
56+
return Array.isArray(this.block.card_grid) ? `grid-${this.block.card_grid.join('-')}` : 'grid'
57+
},
58+
columns () {
59+
return this.block.card_columns
60+
}
61+
}
62+
}
63+
</script>
64+
65+
<style lang="scss" scoped>
66+
// ///////////////////////////////////////////////////////////////////// General
67+
</style>

components/blocks/code-block.vue

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<div class="code-block">
3+
</div>
4+
</template>
5+
6+
<script setup>
7+
</script>
8+
9+
<style lang="scss" scoped>
10+
</style>

0 commit comments

Comments
 (0)