Skip to content

Commit

Permalink
Use useTheme in Tweeq
Browse files Browse the repository at this point in the history
  • Loading branch information
baku89 committed Sep 29, 2023
1 parent 18daf2e commit 713174c
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 67 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
"postversion": "git push && git push --tags"
},
"devDependencies": {
"@material/material-color-utilities": "^0.2.7",
"@types/wicg-file-system-access": "^2020.9.6",
"@typescript-eslint/eslint-plugin": "^6.7.0",
"@typescript-eslint/parser": "^6.7.0",
"@vitejs/plugin-vue": "^4.3.4",
"@vueuse/core": "^10.4.1",
"bndr-js": "^0.9.4",
"case": "^1.6.3",
"eslint": "^8.49.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-jest": "^27.2.3",
Expand Down
39 changes: 10 additions & 29 deletions src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import paper from 'paper'
import PaperOffset from 'paperjs-offset'
PaperOffset(paper)
import {useTweeq} from '@/tweeq'
import FloatingPane from '@/tweeq/FloatingPane'
import MonacoEditor, {ErrorInfo} from '@/tweeq/MonacoEditor'
import RoundButton from '@/tweeq/RoundButton'
import {Tab, Tabs} from '@/tweeq/Tabs'
import TitleBar from '@/tweeq/TitleBar'
import {provideAppStorage} from '@/tweeq/useAppStorage'
import {useCommentMeta} from '@/use/useCommentMeta'
import {useZUI} from '@/use/useZUI'
import {replaceTextBetween} from '@/utils'
Expand All @@ -34,7 +34,7 @@ import OverlayColorPicker from './OverlayColorPicker.vue'
import OverlayNumberSlider from './OverlayNumberSlider.vue'
import OverlayPointHandle from './OverlayPointHandle.vue'
const {appStorage} = provideAppStorage('com.baku89.paperjs-editor')
const {appStorage} = useTweeq('com.baku89.paperjs-editor')
interface PaperDesc {
id?: string
Expand Down Expand Up @@ -192,10 +192,12 @@ const canvasGridStyle = computed(() => {
const opacity = scalar.smoothstep(0.1, 0.4, zoom.value)
const op = `${opacity * 100}%`
return {
backgroundSize: size,
backgroundPosition: offset,
'--dot-color': `rgba(var(--ui-color-rgb), ${opacity})`,
'--dot-color': `color-mix(in srgb, var(--tq-color-text) ${op}, transparent)`,
}
})
Expand Down Expand Up @@ -376,10 +378,11 @@ window.addEventListener('drop', async e => {
</template>

<style lang="stylus" scoped>
@import '../tweeq/common.styl'
.title
.zoom
font-variant-numeric: tabular-nums;
font-numeric()
font-size 11px
border 1px solid transparent
border-radius 4px
Expand All @@ -389,7 +392,7 @@ window.addEventListener('drop', async e => {
transition all ease .1s
&:hover
border-color var(--ui-button)
border-color var(--tq-color-primary)
.main
position relative
Expand All @@ -411,35 +414,13 @@ window.addEventListener('drop', async e => {
.canvas-grid
// draws dotted grid
--axis-color 'rgba(%s, .1)' % var(--ui-color-rgb)
background-image radial-gradient(circle at 0 0, var(--dot-color) 1px, transparent 0), linear-gradient(to bottom, var(--axis-color) 1px, transparent 0), linear-gradient(to right, var(--axis-color) 1px, transparent 0)
--axis-color var(--tq-color-text)
background-image radial-gradient(circle at 0 0, var(--tq-color-text) 1px, transparent 0), linear-gradient(to bottom, var(--axis-color) 1px, transparent 0), linear-gradient(to right, var(--axis-color) 1px, transparent 0)
background-repeat repeat, repeat-x, repeat-y
.inspector-tab
height 100%
.play
display inline-flex
justify-content center
align-items center
background var(--ui-button)
color var(--ui-color)
width 32px
height 32px
border-radius 9999px
vertical-align middle
padding 0 6px
gap .4em
transition all ease .2s
width auto
padding 0 12px 0 6px
background var(--ui-color)
color var(--ui-bg)
&:hover
background var(--ui-accent)
color var(--ui-bg)
.editor
height 100%
Expand Down
4 changes: 2 additions & 2 deletions src/components/OverlayNumberSlider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ function onPointerup(e: PointerEvent) {
transform translateX(-50%)
width 8rem
height 1.6rem
background var(--ui-button)
background var(--md-sys-color-inverse-surface)
border-radius 9999px
cursor col-resize
background-image linear-gradient(to right, var(--ui-color) 4%, transparent 4%)
background-image linear-gradient(to right, var(--md-sys-color-inverse-on-surface) 4%, transparent 4%)
background-size 25px 40%
background-repeat repeat-x
</style>
Expand Down
6 changes: 3 additions & 3 deletions src/components/OverlayPointHandle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ onMounted(() => {
width 17px
height 17px
outline 1px solid rgba(255, 255, 255, 0.5)
border 1px solid var(--ui-accent)
border 1px solid var(--tq-color-primary)
border-radius 50%
background var(--ui-bg)
background var(--tq-color-bg)
&:before
content ''
Expand All @@ -127,5 +127,5 @@ onMounted(() => {
border-radius 50%
&:hover
background var(--ui-accent)
background var(--tq-color-primary)
</style>
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import './style.styl'
import '@/tweeq/style.styl'

import {createApp} from 'vue'

Expand Down
16 changes: 7 additions & 9 deletions src/tweeq/FloatingPane/FloatingPane.vue
Original file line number Diff line number Diff line change
Expand Up @@ -126,21 +126,19 @@ onMounted(() => {
</template>

<style lang="stylus" scoped>
@import '../common.styl'
.FloatingPane
pane()
--resize-width 2rem
position absolute
padding 1rem
border 1px solid 'rgba(%s, .1)' % var(--ui-color-rgb)
outline 'rgba(%s, .5)' % var(--ui-bg-rgb) 1px solid
background 'rgba(%s, .95)' % var(--ui-bg-rgb)
backdrop-filter blur(4px)
right 0
top calc(env(titlebar-area-y, 0px) + var(--titlebar-area-height))
border-width 1px
border-radius var(--ui-pane-border-radius) 0 0 var(--ui-pane-border-radius)
border-radius var(--tq-pane-border-radius) 0 0 var(--tq-pane-border-radius)
display grid
grid-template-columns 1fr
grid-template-rows 1fr
Expand All @@ -157,7 +155,7 @@ onMounted(() => {
&.w-fill
width 100vw
--ui-pane-border-radius 0rem
--tq-pane-border-radius 0rem
& > .left:before
left calc(50% - 1px)
Expand Down Expand Up @@ -193,9 +191,9 @@ onMounted(() => {
.left
left 0
top var(--ui-pane-border-radius)
top var(--tq-pane-border-radius)
width var(--resize-width)
bottom var(--ui-pane-border-radius)
bottom var(--tq-pane-border-radius)
cursor col-resize
margin-left calc(-0.5 * var(--resize-width))
Expand All @@ -204,7 +202,7 @@ onMounted(() => {
left calc(50% - 2.5px)
.bottom
left var(--ui-pane-border-radius)
left var(--tq-pane-border-radius)
bottom 0
right 0
height var(--resize-width)
Expand Down
2 changes: 2 additions & 0 deletions src/tweeq/RoundButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import RoundButton from './RoundButton.vue'
export default RoundButton
4 changes: 2 additions & 2 deletions src/tweeq/Tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,11 @@ onMounted(() => {
transition border-bottom-color .2s ease
&.active
border-bottom-color var(--ui-color)
border-bottom-color var(--tq-color-text)
.tablist-link
text-decoration none
color var(--ui-color)
color var(--tq-color-text)
opacity .4
transition opacity .2s ease
Expand Down
4 changes: 2 additions & 2 deletions src/tweeq/TitleBar/TitleBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ defineSlots<{
z-index 100
user-select none
position fixed
background 'linear-gradient(to bottom, rgba(%s, .7) 0, transparent)' % var(--ui-bg-rgb)
background linear-gradient(to bottom, var(--tq-color-bg), transparent)
backdrop-filter blur(2px)
gap .6rem
padding .4rem .4rem .4rem .6rem
Expand All @@ -40,7 +40,7 @@ defineSlots<{
line-height calc(var(--titlebar-area-height) - 0.8rem)
@media (display-mode: window-controls-overlay)
background 'linear-gradient(to bottom, rgba(%s, .5) 20%, transparent)' % var(--ui-bg-rgb), linear-gradient(to right, var(--ui-bg) 0, transparent 15%, transparent 85%, var(--ui-bg) 100%)
background linear-gradient(to bottom, var(--tq-color-bg) 20%, transparent), linear-gradient(to right, var(--tq-color-bg) 0, transparent 15%, transparent 85%, var(--tq-color-bg) 100%)
.icon
Expand Down
8 changes: 8 additions & 0 deletions src/tweeq/common.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
font-numeric()
font-family var(--tq-font-numeric)
font-variant-numeric tabular-nums

pane()
border 1px solid var(--tq-color-pane-border)
background var(--tq-color-pane)
backdrop-filter blur(4px)
1 change: 1 addition & 0 deletions src/tweeq/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {useTweeq} from './useTweeq'
23 changes: 4 additions & 19 deletions src/style.styl → src/tweeq/style.styl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../node_modules/reset-css/reset.css'
@import '../../node_modules/reset-css/reset.css'

:root
font-size 13px
Expand All @@ -8,23 +8,8 @@
-moz-osx-font-smoothing grayscale
-webkit-text-size-adjust 100%
--titlebar-area-height env(titlebar-area-height, 38px)
// Color scheme
--ui-bg #ffffff
--ui-bg-rgb 255, 255, 255
--ui-color #000
--ui-color-rgb 0, 0, 0
--ui-button #eee
--ui-accent blue
// UI Metrics
--ui-pane-border-radius 1.4rem

@media (prefers-color-scheme dark)
--ui-bg #222
--ui-bg-rgb 34, 34, 34
--ui-color #fff
--ui-color-rgb 255, 255, 255
--ui-button #333
--ui-accent skyblue
--tq-pane-border-radius 1.4rem

*, *:before, *:after
box-sizing border-box
Expand All @@ -46,5 +31,5 @@ body
overflow hidden
margin 0
height 100vh
background var(--ui-bg)
color var(--ui-color)
background var(--tq-color-bg)
color var(--tq-color-text)
97 changes: 97 additions & 0 deletions src/tweeq/useTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
applyTheme,
argbFromHex,
hexFromArgb,
themeFromSourceColor,
} from '@material/material-color-utilities'
import {kebab} from 'case'
import {inject, InjectionKey, provide, Ref} from 'vue'

export interface Theme {
// Colors
colorPrimary: string
colorOnPrimary: string
colorPrimaryContainer: string
colorOnPrimaryContainer: string
colorBg: string
colorText: string
colorPane: string
colorPaneBorder: string

// Font
fontCode: string
fontHeading: string
fontUi: string
fontNumeric: string

// UI Metrics
paneBorderRadius: string
inputHeight: string
}

const ThemeKey: InjectionKey<Theme> = Symbol('tqTheme')

export function provideTheme(accentColor: Ref<string>) {
// Get the theme from a hex color
const materialTheme = themeFromSourceColor(argbFromHex(accentColor.value))

const dark = false

const scheme = dark ? materialTheme.schemes.dark : materialTheme.schemes.light

const theme: Theme = {
colorPrimary: toColor(scheme.primary),
colorPrimaryContainer: toColor(scheme.primaryContainer),
colorOnPrimaryContainer: toColor(scheme.onPrimaryContainer),
colorOnPrimary: toColor(scheme.onPrimary),
colorText: toColor(scheme.onBackground),
colorBg: toColor(scheme.background),
colorPane: toColor(scheme.background, 0.95),
colorPaneBorder: toColor(scheme.onBackground, 0.12),

fontCode: "'Fira Code', monospace",
fontHeading: 'Inter, sans-serif',
fontUi: 'Inter, system-ui, sans-serif',
fontNumeric: 'Inter, system-ui, sans-serif',

paneBorderRadius: '20px',
inputHeight: '16px',
}

// Promote all
for (const [key, value] of Object.entries(theme)) {
const varName = '--tq-' + kebab(key)
document.body.style.setProperty(varName, value)
}

provide(ThemeKey, theme)

// Apply the theme to the body by updating custom properties for material tokens
applyTheme(materialTheme, {target: document.body, dark})

return theme
}

// function

function toColor(color: number, opacity?: number) {
let alpha = ''

if (opacity !== undefined) {
alpha = Math.round(opacity * 255)
.toString(16)
.padStart(2, '0')
}

return `${hexFromArgb(color)}${alpha}`
}

export function useTheme() {
const theme = inject(ThemeKey)

if (!theme) {
throw new Error('theme is not provided')
}

return theme
}
Loading

0 comments on commit 713174c

Please sign in to comment.