vuetiwatch 0.1.0
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/LICENSE +21 -0
- package/README.md +232 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +41 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +58 -0
- package/dist/plugin.js.map +1 -0
- package/dist/registry.d.ts +17 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +37 -0
- package/dist/registry.js.map +1 -0
- package/dist/styles/aurora.css +74 -0
- package/dist/styles/aurora.min.css +1 -0
- package/dist/styles/brutalist.css +48 -0
- package/dist/styles/brutalist.min.css +1 -0
- package/dist/styles/calm.css +21 -0
- package/dist/styles/calm.min.css +1 -0
- package/dist/styles/clay.css +44 -0
- package/dist/styles/clay.min.css +1 -0
- package/dist/styles/core.css +140 -0
- package/dist/styles/core.min.css +1 -0
- package/dist/styles/darkGlass.css +43 -0
- package/dist/styles/darkGlass.min.css +1 -0
- package/dist/styles/liquidGlass.css +100 -0
- package/dist/styles/liquidGlass.min.css +1 -0
- package/dist/styles/lux.css +21 -0
- package/dist/styles/lux.min.css +1 -0
- package/dist/styles/morph.css +37 -0
- package/dist/styles/morph.min.css +1 -0
- package/dist/styles/neon.css +41 -0
- package/dist/styles/neon.min.css +1 -0
- package/dist/styles/paper.css +17 -0
- package/dist/styles/paper.min.css +1 -0
- package/dist/styles/sketchy.css +25 -0
- package/dist/styles/sketchy.min.css +1 -0
- package/dist/styles/slate.css +16 -0
- package/dist/styles/slate.min.css +1 -0
- package/dist/styles/soft.css +46 -0
- package/dist/styles/soft.min.css +1 -0
- package/dist/styles.css +686 -0
- package/dist/styles.min.css +1 -0
- package/dist/themes/aurora.d.ts +10 -0
- package/dist/themes/aurora.d.ts.map +1 -0
- package/dist/themes/aurora.js +86 -0
- package/dist/themes/aurora.js.map +1 -0
- package/dist/themes/brutalist.d.ts +10 -0
- package/dist/themes/brutalist.d.ts.map +1 -0
- package/dist/themes/brutalist.js +103 -0
- package/dist/themes/brutalist.js.map +1 -0
- package/dist/themes/calm.d.ts +11 -0
- package/dist/themes/calm.d.ts.map +1 -0
- package/dist/themes/calm.js +88 -0
- package/dist/themes/calm.js.map +1 -0
- package/dist/themes/classic.d.ts +6 -0
- package/dist/themes/classic.d.ts.map +1 -0
- package/dist/themes/classic.js +23 -0
- package/dist/themes/classic.js.map +1 -0
- package/dist/themes/clay.d.ts +8 -0
- package/dist/themes/clay.d.ts.map +1 -0
- package/dist/themes/clay.js +80 -0
- package/dist/themes/clay.js.map +1 -0
- package/dist/themes/darkGlass.d.ts +7 -0
- package/dist/themes/darkGlass.d.ts.map +1 -0
- package/dist/themes/darkGlass.js +77 -0
- package/dist/themes/darkGlass.js.map +1 -0
- package/dist/themes/index.d.ts +15 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +15 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/themes/liquidGlass.d.ts +19 -0
- package/dist/themes/liquidGlass.d.ts.map +1 -0
- package/dist/themes/liquidGlass.js +111 -0
- package/dist/themes/liquidGlass.js.map +1 -0
- package/dist/themes/lux.d.ts +8 -0
- package/dist/themes/lux.d.ts.map +1 -0
- package/dist/themes/lux.js +91 -0
- package/dist/themes/lux.js.map +1 -0
- package/dist/themes/morph.d.ts +10 -0
- package/dist/themes/morph.d.ts.map +1 -0
- package/dist/themes/morph.js +82 -0
- package/dist/themes/morph.js.map +1 -0
- package/dist/themes/neon.d.ts +7 -0
- package/dist/themes/neon.d.ts.map +1 -0
- package/dist/themes/neon.js +96 -0
- package/dist/themes/neon.js.map +1 -0
- package/dist/themes/paper.d.ts +7 -0
- package/dist/themes/paper.d.ts.map +1 -0
- package/dist/themes/paper.js +88 -0
- package/dist/themes/paper.js.map +1 -0
- package/dist/themes/sketchy.d.ts +11 -0
- package/dist/themes/sketchy.d.ts.map +1 -0
- package/dist/themes/sketchy.js +88 -0
- package/dist/themes/sketchy.js.map +1 -0
- package/dist/themes/slate.d.ts +7 -0
- package/dist/themes/slate.d.ts.map +1 -0
- package/dist/themes/slate.js +89 -0
- package/dist/themes/slate.js.map +1 -0
- package/dist/themes/soft.d.ts +7 -0
- package/dist/themes/soft.d.ts.map +1 -0
- package/dist/themes/soft.js +84 -0
- package/dist/themes/soft.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/util/defaults.d.ts +62 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +100 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/defineTheme.d.ts +21 -0
- package/dist/util/defineTheme.d.ts.map +1 -0
- package/dist/util/defineTheme.js +25 -0
- package/dist/util/defineTheme.js.map +1 -0
- package/dist/util/merge.d.ts +8 -0
- package/dist/util/merge.d.ts.map +1 -0
- package/dist/util/merge.js +17 -0
- package/dist/util/merge.js.map +1 -0
- package/package.json +75 -0
- package/src/index.ts +35 -0
- package/src/plugin.ts +116 -0
- package/src/registry.ts +64 -0
- package/src/styles/core.css +311 -0
- package/src/styles/index.css +30 -0
- package/src/styles/themes/aurora.css +86 -0
- package/src/styles/themes/brutalist.css +59 -0
- package/src/styles/themes/calm.css +31 -0
- package/src/styles/themes/clay.css +60 -0
- package/src/styles/themes/darkGlass.css +69 -0
- package/src/styles/themes/liquidGlass.css +172 -0
- package/src/styles/themes/lux.css +31 -0
- package/src/styles/themes/morph.css +53 -0
- package/src/styles/themes/neon.css +56 -0
- package/src/styles/themes/paper.css +32 -0
- package/src/styles/themes/sketchy.css +34 -0
- package/src/styles/themes/slate.css +26 -0
- package/src/styles/themes/soft.css +63 -0
- package/src/themes/aurora.ts +86 -0
- package/src/themes/brutalist.ts +103 -0
- package/src/themes/calm.ts +88 -0
- package/src/themes/classic.ts +23 -0
- package/src/themes/clay.ts +80 -0
- package/src/themes/darkGlass.ts +77 -0
- package/src/themes/index.ts +14 -0
- package/src/themes/liquidGlass.ts +111 -0
- package/src/themes/lux.ts +91 -0
- package/src/themes/morph.ts +82 -0
- package/src/themes/neon.ts +96 -0
- package/src/themes/paper.ts +88 -0
- package/src/themes/sketchy.ts +88 -0
- package/src/themes/slate.ts +89 -0
- package/src/themes/soft.ts +84 -0
- package/src/types.ts +44 -0
- package/src/util/defaults.ts +164 -0
- package/src/util/defineTheme.ts +49 -0
- package/src/util/merge.ts +23 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import type { VuetiwatchDefaults } from '../types.js'
|
|
2
|
+
import { mergeDeep } from './merge.js'
|
|
3
|
+
|
|
4
|
+
type Props = Record<string, unknown>
|
|
5
|
+
|
|
6
|
+
/** Every component that renders a `v-field` and shares its `variant` prop. */
|
|
7
|
+
const FIELD_COMPONENTS = [
|
|
8
|
+
'VTextField',
|
|
9
|
+
'VTextarea',
|
|
10
|
+
'VSelect',
|
|
11
|
+
'VAutocomplete',
|
|
12
|
+
'VCombobox',
|
|
13
|
+
'VFileInput',
|
|
14
|
+
] as const
|
|
15
|
+
|
|
16
|
+
/** The subset of those that opens a menu, and so draws a dropdown glyph. */
|
|
17
|
+
const MENU_COMPONENTS = [
|
|
18
|
+
'VSelect',
|
|
19
|
+
'VAutocomplete',
|
|
20
|
+
'VCombobox',
|
|
21
|
+
] as const
|
|
22
|
+
|
|
23
|
+
/** Selection controls that share the `density` prop. */
|
|
24
|
+
const CONTROL_COMPONENTS = [
|
|
25
|
+
'VCheckbox',
|
|
26
|
+
'VRadioGroup',
|
|
27
|
+
'VSwitch',
|
|
28
|
+
] as const
|
|
29
|
+
|
|
30
|
+
/** Containers that share the `flat` / `border` props. */
|
|
31
|
+
const BAR_COMPONENTS = [
|
|
32
|
+
'VAppBar',
|
|
33
|
+
'VToolbar',
|
|
34
|
+
] as const
|
|
35
|
+
|
|
36
|
+
/** Surfaces that share the `variant` prop with cards. */
|
|
37
|
+
const SURFACE_COMPONENTS = [
|
|
38
|
+
'VCard',
|
|
39
|
+
'VAlert',
|
|
40
|
+
'VChip',
|
|
41
|
+
] as const
|
|
42
|
+
|
|
43
|
+
const spread = (names: readonly string[], props: Props): VuetiwatchDefaults =>
|
|
44
|
+
Object.fromEntries(names.map(name => [name, props]))
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Applies the same props to every field-based input, so a theme states its
|
|
48
|
+
* input style once instead of six times.
|
|
49
|
+
*/
|
|
50
|
+
export const fields = (props: Props): VuetiwatchDefaults =>
|
|
51
|
+
spread(FIELD_COMPONENTS, props)
|
|
52
|
+
|
|
53
|
+
/** Applies the same props to checkboxes, radio groups and switches. */
|
|
54
|
+
export const controls = (props: Props): VuetiwatchDefaults =>
|
|
55
|
+
spread(CONTROL_COMPONENTS, props)
|
|
56
|
+
|
|
57
|
+
/** Applies the same props to app bars and toolbars. */
|
|
58
|
+
export const bars = (props: Props): VuetiwatchDefaults =>
|
|
59
|
+
spread(BAR_COMPONENTS, props)
|
|
60
|
+
|
|
61
|
+
/** Applies the same props to cards, alerts and chips. */
|
|
62
|
+
export const surfaces = (props: Props): VuetiwatchDefaults =>
|
|
63
|
+
spread(SURFACE_COMPONENTS, props)
|
|
64
|
+
|
|
65
|
+
/** Applies the same `density` to lists and both table components. */
|
|
66
|
+
export const tables = (density: 'default' | 'comfortable' | 'compact'): VuetiwatchDefaults => ({
|
|
67
|
+
VList: { density },
|
|
68
|
+
VTable: { density },
|
|
69
|
+
VDataTable: { density },
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Layers default sets over each other so helpers compose without a later
|
|
74
|
+
* component key wiping an earlier one — `{ VSwitch: { density } }` followed
|
|
75
|
+
* by `{ VSwitch: { inset } }` keeps both.
|
|
76
|
+
*/
|
|
77
|
+
export const combine = (...parts: VuetiwatchDefaults[]): VuetiwatchDefaults =>
|
|
78
|
+
parts.reduce<VuetiwatchDefaults>((acc, part) => mergeDeep(acc, part), {})
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Glyphs a theme can swap.
|
|
82
|
+
*
|
|
83
|
+
* Vuetify's icon *set* (`mdi`, `fa`, a custom SVG set) is global
|
|
84
|
+
* configuration and is not reactive, so it cannot vary per theme. Which
|
|
85
|
+
* glyph a component reaches for is an ordinary prop, though, and props go
|
|
86
|
+
* through defaults like everything else — so a theme can pick outlines
|
|
87
|
+
* where it is thin, solids where it is loud, and circles where it is round.
|
|
88
|
+
*
|
|
89
|
+
* Names must exist in whatever set the app installed; a missing one renders
|
|
90
|
+
* as blank. Everything here is left undefined by default, so a theme states
|
|
91
|
+
* only what it changes.
|
|
92
|
+
*/
|
|
93
|
+
export interface VuetiwatchIcons {
|
|
94
|
+
/** Opens a select menu, an expansion panel or a list group. */
|
|
95
|
+
dropdown?: string
|
|
96
|
+
/** Closes the same. */
|
|
97
|
+
collapse?: string
|
|
98
|
+
next?: string
|
|
99
|
+
prev?: string
|
|
100
|
+
first?: string
|
|
101
|
+
last?: string
|
|
102
|
+
checkboxOn?: string
|
|
103
|
+
checkboxOff?: string
|
|
104
|
+
radioOn?: string
|
|
105
|
+
radioOff?: string
|
|
106
|
+
ratingFull?: string
|
|
107
|
+
ratingEmpty?: string
|
|
108
|
+
/** The clear affordance inside a field. */
|
|
109
|
+
clear?: string
|
|
110
|
+
/** Dismisses a chip or an alert. */
|
|
111
|
+
close?: string
|
|
112
|
+
sortAsc?: string
|
|
113
|
+
sortDesc?: string
|
|
114
|
+
/** Separates breadcrumb items; a plain string, not an icon name. */
|
|
115
|
+
breadcrumbDivider?: string
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Spreads one semantic icon set across every component that draws it. */
|
|
119
|
+
export function icons (set: VuetiwatchIcons): VuetiwatchDefaults {
|
|
120
|
+
const out: Record<string, Props> = {}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Merges rather than assigns, because a component can draw more than one
|
|
124
|
+
* of these glyphs — a select carries both `menuIcon` and `clearIcon`, and
|
|
125
|
+
* assigning would drop whichever came first. Props the theme left unset
|
|
126
|
+
* are skipped so they fall through to Vuetify's own.
|
|
127
|
+
*/
|
|
128
|
+
const put = (names: readonly string[], props: Props) => {
|
|
129
|
+
const given = Object.entries(props).filter(([, value]) => value !== undefined)
|
|
130
|
+
|
|
131
|
+
if (!given.length) return
|
|
132
|
+
|
|
133
|
+
for (const name of names) {
|
|
134
|
+
out[name] = { ...out[name], ...Object.fromEntries(given) }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const paging = {
|
|
139
|
+
nextIcon: set.next,
|
|
140
|
+
prevIcon: set.prev,
|
|
141
|
+
firstIcon: set.first,
|
|
142
|
+
lastIcon: set.last,
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
put(FIELD_COMPONENTS, { clearIcon: set.clear })
|
|
146
|
+
put(MENU_COMPONENTS, { menuIcon: set.dropdown })
|
|
147
|
+
put(['VExpansionPanelTitle', 'VList'], {
|
|
148
|
+
expandIcon: set.dropdown,
|
|
149
|
+
collapseIcon: set.collapse,
|
|
150
|
+
})
|
|
151
|
+
put(['VPagination', 'VDataTable'], paging)
|
|
152
|
+
put(['VDataTable'], { sortAscIcon: set.sortAsc, sortDescIcon: set.sortDesc })
|
|
153
|
+
put(['VSlideGroup'], { nextIcon: set.next, prevIcon: set.prev })
|
|
154
|
+
put(['VCheckbox', 'VCheckboxBtn'], {
|
|
155
|
+
trueIcon: set.checkboxOn,
|
|
156
|
+
falseIcon: set.checkboxOff,
|
|
157
|
+
})
|
|
158
|
+
put(['VRadio'], { trueIcon: set.radioOn, falseIcon: set.radioOff })
|
|
159
|
+
put(['VRating'], { fullIcon: set.ratingFull, emptyIcon: set.ratingEmpty })
|
|
160
|
+
put(['VChip', 'VAlert'], { closeIcon: set.close })
|
|
161
|
+
put(['VBreadcrumbs'], { divider: set.breadcrumbDivider })
|
|
162
|
+
|
|
163
|
+
return out
|
|
164
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ThemeDefinition } from 'vuetify'
|
|
2
|
+
import type { VuetiwatchDefaults, VuetiwatchMeta, VuetiwatchTheme } from '../types.js'
|
|
3
|
+
import { combine } from './defaults.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Applied under every theme's own defaults.
|
|
7
|
+
*
|
|
8
|
+
* A slider with no `color` falls back to `surface-variant`, which reads as
|
|
9
|
+
* dead grey whatever the palette — so the controls whose whole job is to
|
|
10
|
+
* show a value are coloured here once. A theme overrides this the way it
|
|
11
|
+
* overrides anything else.
|
|
12
|
+
*/
|
|
13
|
+
const baseDefaults: VuetiwatchDefaults = {
|
|
14
|
+
VSlider: { color: 'primary' },
|
|
15
|
+
VRangeSlider: { color: 'primary' },
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface DefineThemeOptions<Name extends string = string> {
|
|
19
|
+
name: Name
|
|
20
|
+
meta: VuetiwatchMeta
|
|
21
|
+
/**
|
|
22
|
+
* Colors and CSS variables. Only what the theme actually changes: Vuetify
|
|
23
|
+
* merges every theme over its own `light` or `dark` before use, picking
|
|
24
|
+
* the one matching `dark`, so anything left out is inherited rather than
|
|
25
|
+
* missing.
|
|
26
|
+
*/
|
|
27
|
+
theme: ThemeDefinition
|
|
28
|
+
/**
|
|
29
|
+
* Component defaults, as one object or as layers to fold together —
|
|
30
|
+
* `combine()` is applied for you, so helpers compose without a later
|
|
31
|
+
* component key wiping an earlier one.
|
|
32
|
+
*/
|
|
33
|
+
defaults?: VuetiwatchDefaults | VuetiwatchDefaults[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function defineTheme<const Name extends string> (
|
|
37
|
+
options: DefineThemeOptions<Name>,
|
|
38
|
+
): VuetiwatchTheme<Name> {
|
|
39
|
+
const layers = options.defaults
|
|
40
|
+
? [options.defaults].flat()
|
|
41
|
+
: []
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
name: options.name,
|
|
45
|
+
meta: options.meta,
|
|
46
|
+
theme: options.theme,
|
|
47
|
+
defaults: combine(baseDefaults, ...layers),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type Plain = Record<string, any>
|
|
2
|
+
|
|
3
|
+
const isPlainObject = (value: unknown): value is Plain =>
|
|
4
|
+
value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Recursively merges `source` onto `target` without mutating either.
|
|
8
|
+
* Arrays and primitives from `source` replace the target value outright.
|
|
9
|
+
*/
|
|
10
|
+
export function mergeDeep<T extends Plain> (target: T, source?: Plain): T {
|
|
11
|
+
if (!source) return { ...target }
|
|
12
|
+
|
|
13
|
+
const out: Plain = { ...target }
|
|
14
|
+
|
|
15
|
+
for (const key of Object.keys(source)) {
|
|
16
|
+
const a = out[key]
|
|
17
|
+
const b = source[key]
|
|
18
|
+
|
|
19
|
+
out[key] = isPlainObject(a) && isPlainObject(b) ? mergeDeep(a, b) : b
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return out as T
|
|
23
|
+
}
|