Skip to content

Commit 4231933

Browse files
authored
feat: new directives, v-text-color, v-background-color (#4)
* feat: v-text-color, v-background-color * chore: update dev-app
1 parent 81d11d9 commit 4231933

21 files changed

+235
-31
lines changed

packages/dev-app/app/app.vue

+39-26
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</IconButton>
2020
</template>
2121
<template #end>
22-
<IconButton @click="theme.setTheme(e => ({ isDark: !e.isDark }))">
22+
<IconButton @click="() => theme.setTheme(e => ({ isDark: !e.isDark }))">
2323
<Icon>{{ theme.getTheme.isDark ? 'light_mode' : 'dark_mode' }}</Icon>
2424
</IconButton>
2525
</template>
@@ -49,25 +49,39 @@
4949
>
5050
<h1>Dev App</h1>
5151
</template>
52-
<NavigationDrawerItem
53-
label="Home"
54-
url="/"
55-
></NavigationDrawerItem>
56-
<NavigationDrawerItem type="divider"></NavigationDrawerItem>
57-
<NavigationDrawerItem
58-
type="headline"
59-
label="Component"
60-
></NavigationDrawerItem>
61-
62-
<NavigationDrawerItem
63-
v-for="route in routesWithoutIndexPage"
64-
:label="route.label"
65-
:url="route.url"
66-
>
67-
</NavigationDrawerItem>
52+
<template #default>
53+
<NavigationDrawerItem
54+
label="Home"
55+
url="/"
56+
></NavigationDrawerItem>
57+
58+
<NavigationDrawerItem type="divider"></NavigationDrawerItem>
59+
<NavigationDrawerItem
60+
type="headline"
61+
label="Component"
62+
></NavigationDrawerItem>
63+
<NavigationDrawerItem
64+
v-for="route in componentRoutes"
65+
:label="(route.name as string)"
66+
:url="route.path"
67+
>
68+
</NavigationDrawerItem>
69+
70+
<NavigationDrawerItem type="divider"></NavigationDrawerItem>
71+
<NavigationDrawerItem
72+
type="headline"
73+
label="Directives"
74+
></NavigationDrawerItem>
75+
<NavigationDrawerItem
76+
v-for="route in directiveRoutes"
77+
:label="(route.name as string)"
78+
:url="route.path"
79+
>
80+
</NavigationDrawerItem>
81+
</template>
82+
6883
</NavigationDrawer>
6984
</nav>
70-
7185
</template>
7286

7387
</NuxtLayout>
@@ -76,6 +90,7 @@
7690
</template>
7791

7892
<script setup lang="ts">
93+
import type { RouteRecordRaw } from 'vue-router'
7994
import { GlareProvider, IconButton, Icon, NavigationDrawer, NavigationDrawerItem } from '../../ui/src'
8095
8196
const theme = useThemeStore()
@@ -84,16 +99,14 @@ const isModal = ref(false)
8499
const isNavOpen = ref(false)
85100
86101
const router = useRouter()
87-
const routesWithoutIndexPage = computed<Array<{ label: string, url: string }>>(() => {
102+
const currentRouteName = computed<string>(() => router.currentRoute.value.name as string)
103+
const routesWithoutIndexPage = computed<Array<RouteRecordRaw>>(() => {
88104
const routes = router.getRoutes()
89-
routes.splice(routes.findIndex(e => e.name === 'index'), 1)
90-
return routes.map(e => ({
91-
label: e.name?.toString().replace('examples-', ''),
92-
url: e.path,
93-
}))
105+
routes.splice(routes.findIndex(e => e.name === 'Home'), 1)
106+
return routes
94107
})
95-
const currentRouteName = computed(() => router.currentRoute.value.name === 'index' ? 'Home' : router.currentRoute.value.name?.toString().replace('examples-', ''))
96-
108+
const componentRoutes = computed(() => routesWithoutIndexPage.value.filter(r => (r.path as string).startsWith('/components')))
109+
const directiveRoutes = computed(() => routesWithoutIndexPage.value.filter(r => (r.path as string).startsWith('/directives')))
97110
98111
const handleResize = (e: Event) => {
99112
const target = e.target as Window

packages/dev-app/app/layouts/ComponentLayout.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
<script setup lang="ts">
2121
import { Typography, ETypographyVariant } from '../../../ui/src'
2222
23-
const props = withDefaults(defineProps<{
23+
const props = withDefaults(defineProps<Partial<{
2424
shape: boolean
2525
outline: boolean
2626
paddingX: boolean
2727
headline: string | null
28-
}>(), {
28+
}>>(), {
2929
shape: true,
3030
outline: true,
3131
paddingX: true,

packages/dev-app/app/layouts/PageViewLayout.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
<script setup lang="ts">
1717
import { ETypographyVariant, Typography } from '../../../ui/src'
1818
19-
const props = withDefaults(defineProps<{
19+
const props = withDefaults(defineProps<Partial<{
2020
disableHeadline: boolean
2121
headline: string | null
22-
}>(), {
22+
}>>(), {
2323
disableHeadline: false,
2424
headline: null
2525
})

packages/dev-app/app/pages/examples/Button.vue renamed to packages/dev-app/app/pages/components/Button.vue

+4
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,8 @@
163163

164164
<script setup lang="ts">
165165
import { Button, Icon } from '../../../../ui/src'
166+
167+
definePageMeta({
168+
name: 'Button'
169+
})
166170
</script>

packages/dev-app/app/pages/examples/Checkbox.vue renamed to packages/dev-app/app/pages/components/Checkbox.vue

+4
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121

2222
<script setup lang="ts">
2323
import { Checkbox } from '../../../../ui/src'
24+
25+
definePageMeta({
26+
name: 'Checkbox'
27+
})
2428
</script>

packages/dev-app/app/pages/examples/Divider.vue renamed to packages/dev-app/app/pages/components/Divider.vue

+4
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,8 @@
4040

4141
<script setup lang="ts">
4242
import { Divider, EDividerVariant } from '../../../../ui/src'
43+
44+
definePageMeta({
45+
name: 'Divider'
46+
})
4347
</script>

packages/dev-app/app/pages/examples/Elevation.vue renamed to packages/dev-app/app/pages/components/Elevation.vue

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363

6464
<script setup lang="ts">
6565
import { Elevation, vElevation, Typography, ETypographyVariant } from '../../../../ui/src'
66+
67+
definePageMeta({
68+
name: 'Elevation'
69+
})
6670
</script>
6771

6872
<style>

packages/dev-app/app/pages/examples/Fab.vue renamed to packages/dev-app/app/pages/components/Fab.vue

+4
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,8 @@
167167

168168
<script setup lang="ts">
169169
import { Fab, Icon } from '../../../../ui/src'
170+
171+
definePageMeta({
172+
name: 'Fab'
173+
})
170174
</script>

packages/dev-app/app/pages/examples/IconButton.vue renamed to packages/dev-app/app/pages/components/IconButton.vue

+4
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,8 @@
7373

7474
<script setup lang="ts">
7575
import { IconButton, TogglableIconButton, Icon } from '../../../../ui/src'
76+
77+
definePageMeta({
78+
name: 'IconButton'
79+
})
7680
</script>

packages/dev-app/app/pages/examples/NavigationBar.vue renamed to packages/dev-app/app/pages/components/NavigationBar.vue

+4
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@
3131

3232
<script setup lang="ts">
3333
import { NavigationBar, NavigationTab, Icon } from '../../../../ui/src'
34+
35+
definePageMeta({
36+
name: 'NavigationBar'
37+
})
3438
</script>

packages/dev-app/app/pages/examples/Progress.vue renamed to packages/dev-app/app/pages/components/Progress.vue

+4
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@
2525

2626
<script setup lang="ts">
2727
import { LinearProgress, CircularProgress } from '../../../../ui/src'
28+
29+
definePageMeta({
30+
name: 'Progress'
31+
})
2832
</script>

packages/dev-app/app/pages/examples/Radio.vue renamed to packages/dev-app/app/pages/components/Radio.vue

+4
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121

2222
<script setup lang="ts">
2323
import { Radio } from '../../../../ui/src'
24+
25+
definePageMeta({
26+
name: 'Radio'
27+
})
2428
</script>

packages/dev-app/app/pages/examples/Ripple.vue renamed to packages/dev-app/app/pages/components/Ripple.vue

+3
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@
105105
<script setup lang="ts">
106106
import { AttachableControllerSymbol, type AttachableControllerHost, Ripple, vRipple, vRippleHoverColor, vRipplePressedColor, Button } from '../../../../ui/src'
107107
108+
definePageMeta({
109+
name: 'Ripple'
110+
})
108111
109112
const handleClick = (mode: 'attach' | 'detach') => {
110113
const ripple = (document.querySelector('#my-ripple') as AttachableControllerHost)[AttachableControllerSymbol]

packages/dev-app/app/pages/examples/Switch.vue renamed to packages/dev-app/app/pages/components/Switch.vue

+4
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121

2222
<script setup lang="ts">
2323
import { Switch } from '../../../../ui/src'
24+
25+
definePageMeta({
26+
name: 'Switch'
27+
})
2428
</script>

packages/dev-app/app/pages/examples/Typography.vue renamed to packages/dev-app/app/pages/components/Typography.vue

+4
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@
3030

3131
<script setup lang="ts">
3232
import { Typography } from '../../../../ui/src'
33+
34+
definePageMeta({
35+
name: 'Typography'
36+
})
3337
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<template>
2+
<NuxtLayout
3+
name="page-view-layout"
4+
headline="Color"
5+
>
6+
<NuxtLayout
7+
name="component-layout"
8+
headline="v-text-color"
9+
>
10+
<p
11+
class="box"
12+
v-text-color="'#000000'"
13+
>#000000</p>
14+
15+
<p
16+
class="box"
17+
v-text-color="'#4e8de0'"
18+
>#4e8de0</p>
19+
20+
<p
21+
class="box"
22+
v-text-color
23+
>Default color</p>
24+
</NuxtLayout>
25+
26+
<NuxtLayout
27+
name="component-layout"
28+
headline="v-background-color"
29+
>
30+
<p
31+
class="box"
32+
v-background-color="'#000000'"
33+
>#000000</p>
34+
35+
<p
36+
class="box"
37+
v-background-color="'#4e8de0'"
38+
>#4e8de0</p>
39+
40+
<p
41+
class="box"
42+
v-background-color
43+
>Default color</p>
44+
</NuxtLayout>
45+
</NuxtLayout>
46+
</template>
47+
48+
<script setup lang="ts">
49+
import { vTextColor, vBackgroundColor } from '../../../../ui/src'
50+
51+
definePageMeta({
52+
name: 'Color'
53+
})
54+
</script>
55+
56+
<style scoped>
57+
.box {
58+
@apply w-full h-12 border grid place-content-center;
59+
}
60+
</style>

packages/dev-app/app/pages/index.vue

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222

2323
<script setup lang="ts">
2424
import { ETypographyVariant, Icon, Typography } from '../../../ui/src'
25+
26+
definePageMeta({
27+
name: 'Home'
28+
})
2529
</script>
2630

2731
<style scoped></style>

packages/dev-app/nuxt.config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default defineNuxtConfig({
88
future: {
99
compatibilityVersion: 4,
1010
},
11-
ssr: true,
11+
ssr: false,
1212
modules: [
1313
'@pinia/nuxt',
1414
],

packages/ui/src/directives/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './v-color'

packages/ui/src/directives/v-color.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import type { Directive } from 'vue'
2+
3+
abstract class ColorableElement {
4+
5+
/**
6+
*
7+
* @param property 'text' | 'background'
8+
* @param value hex-like
9+
*/
10+
protected setElementColorProperty(element: HTMLElement, property: 'text' | 'background', value: string) {
11+
element.style.setProperty(property === 'text' ? 'color' : 'background', value)
12+
}
13+
}
14+
15+
class TextColorDirective extends ColorableElement {
16+
17+
private readonly defaultColor = 'var(--gu-sys-color-on-surface)'
18+
19+
public readonly directive: Directive<HTMLElement, string> = {
20+
mounted: (el, binding) => {
21+
const colorRaw = binding.value
22+
let color = binding.value
23+
if (typeof colorRaw === 'undefined' || colorRaw === null) {
24+
console.warn(`v-text-color accepts a string of hexadecimal color values. v-text-color received an unexpected value [${color}].`)
25+
color = this.defaultColor
26+
}
27+
this.setElementColorProperty(el, 'text', color)
28+
},
29+
updated: (el, binding) => {
30+
if (binding.oldValue === binding.value) return
31+
const colorRaw = binding.value
32+
let color = binding.value
33+
if (typeof colorRaw === 'undefined' || colorRaw === null) {
34+
console.warn(`v-text-color accepts a string of hexadecimal color values. v-text-color received an unexpected value [${color}].`)
35+
color = this.defaultColor
36+
}
37+
this.setElementColorProperty(el, 'text', color)
38+
}
39+
}
40+
41+
}
42+
43+
class BackgroundColorDirective extends ColorableElement {
44+
45+
private readonly defaultColor = 'var(--gu-sys-color-surface)'
46+
47+
public readonly directive: Directive<HTMLElement, string> = {
48+
mounted: (el, binding) => {
49+
const colorRaw = binding.value
50+
let color = binding.value
51+
if (typeof colorRaw === 'undefined' || colorRaw === null) {
52+
console.warn(`v-text-color accepts a string of hexadecimal color values. v-text-color received an unexpected value [${color}].`)
53+
color = this.defaultColor
54+
}
55+
this.setElementColorProperty(el, 'background', color)
56+
},
57+
updated: (el, binding) => {
58+
if (binding.oldValue === binding.value) return
59+
const colorRaw = binding.value
60+
let color = binding.value
61+
if (typeof colorRaw === 'undefined' || colorRaw === null) {
62+
console.warn(`v-text-color accepts a string of hexadecimal color values. v-text-color received an unexpected value [${color}].`)
63+
color = this.defaultColor
64+
}
65+
this.setElementColorProperty(el, 'background', color)
66+
}
67+
}
68+
69+
}
70+
71+
72+
73+
export const vTextColor = new TextColorDirective().directive
74+
export const vBackgroundColor = new BackgroundColorDirective().directive

0 commit comments

Comments
 (0)